Coverage Report

Created: 2024-06-12 07:07

/src/libewf/libewf/libewf_table_section.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Table section functions
3
 *
4
 * Copyright (C) 2006-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <types.h>
25
26
#include "libewf_checksum.h"
27
#include "libewf_definitions.h"
28
#include "libewf_libbfio.h"
29
#include "libewf_libcerror.h"
30
#include "libewf_libcnotify.h"
31
#include "libewf_section.h"
32
#include "libewf_table_section.h"
33
34
#include "ewf_section.h"
35
#include "ewf_table.h"
36
37
/* Creates a table section
38
 * Make sure the value table_section is referencing, is set to NULL
39
 * Returns 1 if successful or -1 on error
40
 */
41
int libewf_table_section_initialize(
42
     libewf_table_section_t **table_section,
43
     libcerror_error_t **error )
44
1.40k
{
45
1.40k
  static char *function = "libewf_table_section_initialize";
46
47
1.40k
  if( table_section == NULL )
48
0
  {
49
0
    libcerror_error_set(
50
0
     error,
51
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
52
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
53
0
     "%s: invalid table section.",
54
0
     function );
55
56
0
    return( -1 );
57
0
  }
58
1.40k
  if( *table_section != NULL )
59
0
  {
60
0
    libcerror_error_set(
61
0
     error,
62
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
63
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
64
0
     "%s: invalid table section value already set.",
65
0
     function );
66
67
0
    return( -1 );
68
0
  }
69
1.40k
  *table_section = memory_allocate_structure(
70
1.40k
                    libewf_table_section_t );
71
72
1.40k
  if( *table_section == NULL )
73
0
  {
74
0
    libcerror_error_set(
75
0
     error,
76
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
77
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
78
0
     "%s: unable to create table section.",
79
0
     function );
80
81
0
    goto on_error;
82
0
  }
83
1.40k
  if( memory_set(
84
1.40k
       *table_section,
85
1.40k
       0,
86
1.40k
       sizeof( libewf_table_section_t ) ) == NULL )
87
0
  {
88
0
    libcerror_error_set(
89
0
     error,
90
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
91
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
92
0
     "%s: unable to clear table section.",
93
0
     function );
94
95
0
    goto on_error;
96
0
  }
97
1.40k
  return( 1 );
98
99
0
on_error:
100
0
  if( *table_section != NULL )
101
0
  {
102
0
    memory_free(
103
0
     *table_section );
104
105
0
    *table_section = NULL;
106
0
  }
107
0
  return( -1 );
108
1.40k
}
109
110
/* Frees a table section
111
 * Returns 1 if successful or -1 on error
112
 */
113
int libewf_table_section_free(
114
     libewf_table_section_t **table_section,
115
     libcerror_error_t **error )
116
1.40k
{
117
1.40k
  static char *function = "libewf_table_section_free";
118
119
1.40k
  if( table_section == NULL )
120
0
  {
121
0
    libcerror_error_set(
122
0
     error,
123
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
124
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
125
0
     "%s: invalid table section.",
126
0
     function );
127
128
0
    return( -1 );
129
0
  }
130
1.40k
  if( *table_section != NULL )
131
1.40k
  {
132
1.40k
    if( ( *table_section )->section_data != NULL )
133
1.25k
    {
134
1.25k
      memory_free(
135
1.25k
       ( *table_section )->section_data );
136
1.25k
    }
137
1.40k
    memory_free(
138
1.40k
     *table_section );
139
140
1.40k
    *table_section = NULL;
141
1.40k
  }
142
1.40k
  return( 1 );
143
1.40k
}
144
145
/* Reads the header of a version 1 table or table2 section or version 2 sector table section
146
 * Returns the number of bytes read or -1 on error
147
 */
148
int libewf_table_section_read_header_data(
149
     libewf_table_section_t *table_section,
150
     libewf_io_handle_t *io_handle,
151
     const uint8_t *data,
152
     size_t data_size,
153
     uint8_t format_version,
154
     libcerror_error_t **error )
155
1.34k
{
156
1.34k
  static char *function              = "libewf_table_section_read_header_data";
157
1.34k
  size_t header_data_size            = 0;
158
1.34k
  uint32_t calculated_checksum       = 0;
159
1.34k
  uint32_t stored_checksum           = 0;
160
161
#if defined( HAVE_VERBOSE_OUTPUT )
162
  uint32_t maximum_number_of_entries = 0;
163
#endif
164
#if defined( HAVE_DEBUG_OUTPUT )
165
  uint32_t value_32bit               = 0;
166
#endif
167
168
1.34k
  if( table_section == NULL )
169
0
  {
170
0
    libcerror_error_set(
171
0
     error,
172
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
173
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
174
0
     "%s: invalid table section.",
175
0
     function );
176
177
0
    return( -1 );
178
0
  }
179
1.34k
  if( io_handle == NULL )
180
0
  {
181
0
    libcerror_error_set(
182
0
     error,
183
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
184
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
185
0
     "%s: invalid IO handle.",
186
0
     function );
187
188
0
    return( -1 );
189
0
  }
190
1.34k
  if( data == NULL )
191
0
  {
192
0
    libcerror_error_set(
193
0
     error,
194
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
195
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
196
0
     "%s: invalid data.",
197
0
     function );
198
199
0
    return( -1 );
200
0
  }
201
1.34k
  if( format_version == 1 )
202
1.34k
  {
203
1.34k
    header_data_size = sizeof( ewf_table_header_v1_t );
204
1.34k
  }
205
0
  else if( format_version == 2 )
206
0
  {
207
0
    header_data_size = sizeof( ewf_table_header_v2_t );
208
0
  }
209
0
  else
210
0
  {
211
0
    libcerror_error_set(
212
0
     error,
213
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
214
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
215
0
     "%s: unsupported format version.",
216
0
     function );
217
218
0
    return( -1 );
219
0
  }
220
1.34k
  if( ( data_size < header_data_size )
221
1.34k
   || ( data_size > (size_t) SSIZE_MAX ) )
222
0
  {
223
0
    libcerror_error_set(
224
0
     error,
225
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
226
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
227
0
     "%s: invalid data size value out of bounds.",
228
0
     function );
229
230
0
    return( -1 );
231
0
  }
232
#if defined( HAVE_DEBUG_OUTPUT )
233
  if( libcnotify_verbose != 0 )
234
  {
235
    libcnotify_printf(
236
     "%s: table header data:\n",
237
     function );
238
    libcnotify_print_data(
239
     data,
240
     header_data_size,
241
     0 );
242
  }
243
#endif
244
1.34k
  if( format_version == 1 )
245
1.34k
  {
246
1.34k
    byte_stream_copy_to_uint32_little_endian(
247
1.34k
     ( (ewf_table_header_v1_t *) data )->number_of_entries,
248
1.34k
     table_section->number_of_entries );
249
250
1.34k
    byte_stream_copy_to_uint64_little_endian(
251
1.34k
     ( (ewf_table_header_v1_t *) data )->base_offset,
252
1.34k
     table_section->base_offset );
253
254
1.34k
    byte_stream_copy_to_uint32_little_endian(
255
1.34k
     ( (ewf_table_header_v1_t *) data )->checksum,
256
1.34k
     stored_checksum );
257
1.34k
  }
258
0
  else if( format_version == 2 )
259
0
  {
260
0
    byte_stream_copy_to_uint64_little_endian(
261
0
     ( (ewf_table_header_v2_t *) data )->first_chunk_number,
262
0
     table_section->first_chunk_index );
263
264
0
    byte_stream_copy_to_uint32_little_endian(
265
0
     ( (ewf_table_header_v2_t *) data )->number_of_entries,
266
0
     table_section->number_of_entries );
267
268
0
    byte_stream_copy_to_uint32_little_endian(
269
0
     ( (ewf_table_header_v2_t *) data )->checksum,
270
0
     stored_checksum );
271
0
  }
272
#if defined( HAVE_DEBUG_OUTPUT )
273
  if( libcnotify_verbose != 0 )
274
  {
275
    if( format_version == 2 )
276
    {
277
      libcnotify_printf(
278
       "%s: first chunk number\t\t: %" PRIu64 "\n",
279
       function,
280
       table_section->first_chunk_index );
281
    }
282
    libcnotify_printf(
283
     "%s: number of entries\t\t: %" PRIu32 "\n",
284
     function,
285
     table_section->number_of_entries );
286
287
    if( format_version == 1 )
288
    {
289
      byte_stream_copy_to_uint32_little_endian(
290
       ( (ewf_table_header_v1_t *) data )->padding1,
291
       value_32bit );
292
      libcnotify_printf(
293
       "%s: padding1\t\t\t\t: 0x%08" PRIx32 "\n",
294
       function,
295
       value_32bit );
296
297
      libcnotify_printf(
298
       "%s: base offset\t\t\t: 0x%08" PRIx64 "\n",
299
       function,
300
       table_section->base_offset );
301
302
      byte_stream_copy_to_uint32_little_endian(
303
       ( (ewf_table_header_v1_t *) data )->padding2,
304
       value_32bit );
305
      libcnotify_printf(
306
       "%s: padding2\t\t\t\t: 0x%08" PRIx32 "\n",
307
       function,
308
       value_32bit );
309
    }
310
    else if( format_version == 2 )
311
    {
312
      byte_stream_copy_to_uint32_little_endian(
313
       ( (ewf_table_header_v2_t *) data )->unknown1,
314
       value_32bit );
315
      libcnotify_printf(
316
       "%s: unknown1\t\t\t\t: 0x%08" PRIx32 "\n",
317
       function,
318
       value_32bit );
319
    }
320
    libcnotify_printf(
321
     "%s: checksum\t\t\t\t: 0x%08" PRIx32 "\n",
322
     function,
323
     stored_checksum );
324
325
    if( format_version == 1 )
326
    {
327
      libcnotify_printf(
328
       "\n" );
329
    }
330
    else if( format_version == 2 )
331
    {
332
      libcnotify_printf(
333
       "%s: padding:\n",
334
       function );
335
      libcnotify_print_data(
336
       ( (ewf_table_header_v2_t *) data )->padding,
337
       12,
338
       0 );
339
    }
340
  }
341
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
342
343
1.34k
  if( format_version == 1 )
344
1.34k
  {
345
1.34k
    header_data_size -= 4;
346
1.34k
  }
347
0
  else if( format_version == 2 )
348
0
  {
349
0
    header_data_size -= 16;
350
0
  }
351
1.34k
  if( libewf_checksum_calculate_adler32(
352
1.34k
       &calculated_checksum,
353
1.34k
       data,
354
1.34k
       header_data_size,
355
1.34k
       1,
356
1.34k
       error ) != 1 )
357
0
  {
358
0
    libcerror_error_set(
359
0
     error,
360
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
361
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
362
0
     "%s: unable to calculate header checksum.",
363
0
     function );
364
365
0
    return( -1 );
366
0
  }
367
/* TODO flag that header is corrupted and continue */
368
1.34k
  if( stored_checksum != calculated_checksum )
369
56
  {
370
56
    libcerror_error_set(
371
56
     error,
372
56
     LIBCERROR_ERROR_DOMAIN_INPUT,
373
56
     LIBCERROR_INPUT_ERROR_CHECKSUM_MISMATCH,
374
56
     "%s: header checksum does not match (stored: 0x%08" PRIx32 ", calculated: 0x%08" PRIx32 ").",
375
56
     function,
376
56
     stored_checksum,
377
56
     calculated_checksum );
378
379
56
    return( -1 );
380
56
  }
381
#if defined( HAVE_VERBOSE_OUTPUT )
382
  if( libcnotify_verbose != 0 )
383
  {
384
/* TODO what about linen7 */
385
    if( format_version == 1 )
386
    {
387
      if( ( io_handle->format == LIBEWF_FORMAT_ENCASE6 )
388
       || ( io_handle->format == LIBEWF_FORMAT_ENCASE7 ) )
389
      {
390
        maximum_number_of_entries = LIBEWF_MAXIMUM_TABLE_ENTRIES_ENCASE6;
391
      }
392
      else
393
      {
394
        maximum_number_of_entries = LIBEWF_MAXIMUM_TABLE_ENTRIES;
395
      }
396
      if( table_section->number_of_entries > maximum_number_of_entries )
397
      {
398
        libcnotify_printf(
399
         "%s: number of entries: %" PRIu32 " exceeds maximum: %" PRIu32 ".\n",
400
         function,
401
         table_section->number_of_entries,
402
         maximum_number_of_entries );
403
      }
404
    }
405
  }
406
#endif /* defined( HAVE_VERBOSE_OUTPUT ) */
407
408
1.29k
  if( table_section->base_offset > (uint64_t) INT64_MAX )
409
5
  {
410
5
    libcerror_error_set(
411
5
     error,
412
5
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
413
5
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
414
5
     "%s: invalid base offset value out of bounds.",
415
5
     function );
416
417
5
    return( -1 );
418
5
  }
419
1.28k
  if( table_section->first_chunk_index > (uint64_t) INT64_MAX )
420
0
  {
421
0
    libcerror_error_set(
422
0
     error,
423
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
424
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
425
0
     "%s: invalid first chunk index value out of bounds.",
426
0
     function );
427
428
0
    return( -1 );
429
0
  }
430
1.28k
  return( 1 );
431
1.28k
}
432
433
/* Reads the footer of a version 1 table or table2 section or version 2 sector table section
434
 * Returns the number of bytes read or -1 on error
435
 */
436
int libewf_table_section_read_footer_data(
437
     libewf_table_section_t *table_section,
438
     const uint8_t *data,
439
     size_t data_size,
440
     uint8_t format_version,
441
     uint32_t *stored_checksum,
442
     libcerror_error_t **error )
443
1.25k
{
444
1.25k
  static char *function         = "libewf_table_section_read_footer_data";
445
1.25k
  size_t footer_data_size       = 0;
446
1.25k
  uint32_t safe_stored_checksum = 0;
447
448
1.25k
  if( table_section == NULL )
449
0
  {
450
0
    libcerror_error_set(
451
0
     error,
452
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
453
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
454
0
     "%s: invalid table section.",
455
0
     function );
456
457
0
    return( -1 );
458
0
  }
459
1.25k
  if( data == NULL )
460
0
  {
461
0
    libcerror_error_set(
462
0
     error,
463
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
464
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
465
0
     "%s: invalid data.",
466
0
     function );
467
468
0
    return( -1 );
469
0
  }
470
1.25k
  if( format_version == 1 )
471
1.25k
  {
472
1.25k
    footer_data_size = 4;
473
1.25k
  }
474
0
  else if( format_version == 2 )
475
0
  {
476
0
    footer_data_size = 16;
477
0
  }
478
0
  else
479
0
  {
480
0
    libcerror_error_set(
481
0
     error,
482
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
483
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
484
0
     "%s: unsupported format version.",
485
0
     function );
486
487
0
    return( -1 );
488
0
  }
489
1.25k
  if( data_size != footer_data_size )
490
0
  {
491
0
    libcerror_error_set(
492
0
     error,
493
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
494
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
495
0
     "%s: invalid data size value out of bounds.",
496
0
     function );
497
498
0
    return( -1 );
499
0
  }
500
1.25k
  if( stored_checksum == NULL )
501
0
  {
502
0
    libcerror_error_set(
503
0
     error,
504
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
505
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
506
0
     "%s: invalid stored checksum.",
507
0
     function );
508
509
0
    return( -1 );
510
0
  }
511
#if defined( HAVE_DEBUG_OUTPUT )
512
  if( libcnotify_verbose != 0 )
513
  {
514
    libcnotify_printf(
515
     "%s: table footer data:\n",
516
     function );
517
    libcnotify_print_data(
518
     data,
519
     footer_data_size,
520
     0 );
521
  }
522
#endif
523
1.25k
  byte_stream_copy_to_uint32_little_endian(
524
1.25k
   data,
525
1.25k
   safe_stored_checksum );
526
527
#if defined( HAVE_DEBUG_OUTPUT )
528
  if( libcnotify_verbose != 0 )
529
  {
530
    libcnotify_printf(
531
     "%s: table entries checksum\t\t: 0x%08" PRIx32 "\n",
532
     function,
533
     safe_stored_checksum );
534
535
    if( format_version == 1 )
536
    {
537
      libcnotify_printf(
538
       "\n" );
539
    }
540
    else if( format_version == 2 )
541
    {
542
      libcnotify_printf(
543
       "%s: padding:\n",
544
       function );
545
      libcnotify_print_data(
546
       &( data[ 4 ] ),
547
       12,
548
       0 );
549
    }
550
  }
551
#endif /* defined( HAVE_VERBOSE_OUTPUT ) */
552
553
1.25k
  *stored_checksum = safe_stored_checksum;
554
555
1.25k
  return( 1 );
556
1.25k
}
557
558
/* Reads a version 1 table or table2 section or version 2 sector table section
559
 * Returns the number of bytes read or -1 on error
560
 */
561
ssize_t libewf_table_section_read_file_io_pool(
562
         libewf_table_section_t *table_section,
563
         libewf_io_handle_t *io_handle,
564
         libbfio_pool_t *file_io_pool,
565
         int file_io_pool_entry,
566
         uint8_t format_version,
567
         uint8_t segment_file_type,
568
         size64_t section_data_size,
569
         uint32_t section_data_flags,
570
         libcerror_error_t **error )
571
1.40k
{
572
1.40k
  static char *function         = "libewf_table_section_read_file_io_pool";
573
1.40k
  size_t data_offset            = 0;
574
1.40k
  size_t table_entry_data_size  = 0;
575
1.40k
  size_t table_footer_data_size = 0;
576
1.40k
  size_t table_header_data_size = 0;
577
1.40k
  ssize_t read_count            = 0;
578
1.40k
  uint32_t calculated_checksum  = 0;
579
1.40k
  uint32_t stored_checksum      = 0;
580
581
1.40k
  if( table_section == NULL )
582
0
  {
583
0
    libcerror_error_set(
584
0
     error,
585
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
586
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
587
0
     "%s: invalid table section.",
588
0
     function );
589
590
0
    return( -1 );
591
0
  }
592
1.40k
  if( io_handle == NULL )
593
0
  {
594
0
    libcerror_error_set(
595
0
     error,
596
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
597
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
598
0
     "%s: invalid IO handle.",
599
0
     function );
600
601
0
    return( -1 );
602
0
  }
603
1.40k
  if( format_version == 1 )
604
1.40k
  {
605
1.40k
    table_header_data_size = sizeof( ewf_table_header_v1_t );
606
1.40k
    table_entry_data_size  = sizeof( ewf_table_entry_v1_t );
607
608
    /* The original EWF and SMART (EWF-S01) formats do not contain a table footer
609
     */
610
1.40k
    if( segment_file_type != LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
611
1.40k
    {
612
1.40k
      table_footer_data_size = 4;
613
1.40k
    }
614
1.40k
  }
615
0
  else if( format_version == 2 )
616
0
  {
617
0
    table_header_data_size = sizeof( ewf_table_header_v2_t );
618
0
    table_entry_data_size  = sizeof( ewf_table_entry_v2_t );
619
0
    table_footer_data_size = 16;
620
0
  }
621
0
  else
622
0
  {
623
0
    libcerror_error_set(
624
0
     error,
625
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
626
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
627
0
     "%s: unsupported format version.",
628
0
     function );
629
630
0
    return( -1 );
631
0
  }
632
1.40k
  if( ( section_data_size == 0 )
633
1.40k
   || ( section_data_size > (size64_t) SSIZE_MAX ) )
634
0
  {
635
0
    libcerror_error_set(
636
0
     error,
637
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
638
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
639
0
     "%s: invalid section data size value out of bounds.",
640
0
     function );
641
642
0
    return( -1 );
643
0
  }
644
  /* In original EWF, SMART (EWF-S01) and EnCase1 EWF-E01 the trailing data will be the chunk data
645
   */
646
1.40k
  if( ( segment_file_type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
647
1.40k
   || ( io_handle->format == LIBEWF_FORMAT_ENCASE1 ) )
648
73
  {
649
/* TODO consider reading max number of chunks for table with chunk data */
650
73
    table_section->section_data_size = (size_t) table_header_data_size;
651
73
  }
652
1.33k
  else
653
1.33k
  {
654
1.33k
    table_section->section_data_size = (size_t) section_data_size;
655
1.33k
  }
656
1.40k
  if( ( table_section->section_data_size < table_header_data_size )
657
1.40k
   || ( table_section->section_data_size > MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
658
17
  {
659
17
    libcerror_error_set(
660
17
     error,
661
17
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
662
17
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
663
17
     "%s: invalid section data size value out of bounds.",
664
17
     function );
665
666
17
    goto on_error;
667
17
  }
668
1.38k
  table_section->section_data = (uint8_t *) memory_allocate(
669
1.38k
                                             sizeof( uint8_t ) * table_section->section_data_size );
670
671
1.38k
  if( table_section->section_data == NULL )
672
0
  {
673
0
    libcerror_error_set(
674
0
     error,
675
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
676
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
677
0
     "%s: unable to create section data.",
678
0
     function );
679
680
0
    goto on_error;
681
0
  }
682
1.38k
  read_count = libbfio_pool_read_buffer(
683
1.38k
                file_io_pool,
684
1.38k
                file_io_pool_entry,
685
1.38k
                table_section->section_data,
686
1.38k
                table_section->section_data_size,
687
1.38k
                error );
688
689
1.38k
  if( read_count != (ssize_t) table_section->section_data_size )
690
43
  {
691
43
    libcerror_error_set(
692
43
     error,
693
43
     LIBCERROR_ERROR_DOMAIN_IO,
694
43
     LIBCERROR_IO_ERROR_READ_FAILED,
695
43
     "%s: unable to read section data.",
696
43
     function );
697
698
43
    goto on_error;
699
43
  }
700
1.34k
  if( ( section_data_flags & LIBEWF_SECTION_DATA_FLAGS_IS_ENCRYPTED ) != 0 )
701
0
  {
702
#if defined( HAVE_DEBUG_OUTPUT )
703
    if( libcnotify_verbose != 0 )
704
    {
705
      libcnotify_printf(
706
       "%s: encrypted data:\n",
707
       function );
708
      libcnotify_print_data(
709
       table_section->section_data,
710
       table_section->section_data_size,
711
       0 );
712
    }
713
#endif
714
/* TODO decrypt */
715
0
    memory_free(
716
0
     table_section->section_data );
717
718
0
    table_section->section_data      = NULL;
719
0
    table_section->section_data_size = 0;
720
721
0
    return( 0 );
722
0
  }
723
1.34k
  if( libewf_table_section_read_header_data(
724
1.34k
       table_section,
725
1.34k
       io_handle,
726
1.34k
       table_section->section_data,
727
1.34k
       table_section->section_data_size,
728
1.34k
       format_version,
729
1.34k
       error ) != 1 )
730
61
  {
731
61
    libcerror_error_set(
732
61
     error,
733
61
     LIBCERROR_ERROR_DOMAIN_IO,
734
61
     LIBCERROR_IO_ERROR_READ_FAILED,
735
61
     "%s: unable to read table section header.",
736
61
     function );
737
738
61
    goto on_error;
739
61
  }
740
1.28k
  data_offset = table_header_data_size;
741
742
1.28k
  if( table_section->number_of_entries > 0 )
743
1.28k
  {
744
1.28k
    if( (size_t) table_section->number_of_entries > ( (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE / table_entry_data_size ) )
745
5
    {
746
5
      libcerror_error_set(
747
5
       error,
748
5
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
749
5
       LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
750
5
       "%s: invalid table section - number of entries value exceeds maximum allocation size.",
751
5
       function );
752
753
5
      goto on_error;
754
5
    }
755
1.28k
    table_section->entries_size = (size_t) table_section->number_of_entries * table_entry_data_size;
756
757
1.28k
    if( ( segment_file_type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
758
1.28k
     || ( io_handle->format == LIBEWF_FORMAT_ENCASE1 ) )
759
31
    {
760
31
      if( (size_t) table_section->number_of_entries > ( (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE - table_footer_data_size ) )
761
0
      {
762
0
        libcerror_error_set(
763
0
         error,
764
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
765
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
766
0
         "%s: invalid section data size value out of bounds.",
767
0
         function );
768
769
0
        goto on_error;
770
0
      }
771
31
      table_section->section_data_size = table_section->entries_size + table_footer_data_size;
772
773
31
      memory_free(
774
31
       table_section->section_data );
775
776
/* TODO consider using memory_reallocate */
777
31
      table_section->section_data = (uint8_t *) memory_allocate(
778
31
                                                 sizeof( uint8_t ) * table_section->section_data_size );
779
780
31
      if( table_section->section_data == NULL )
781
0
      {
782
0
        libcerror_error_set(
783
0
         error,
784
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
785
0
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
786
0
         "%s: unable to create section data.",
787
0
         function );
788
789
0
        goto on_error;
790
0
      }
791
31
      read_count = libbfio_pool_read_buffer(
792
31
              file_io_pool,
793
31
              file_io_pool_entry,
794
31
              table_section->section_data,
795
31
              table_section->section_data_size,
796
31
              error );
797
798
31
      if( read_count != (ssize_t) table_section->section_data_size )
799
23
      {
800
23
        libcerror_error_set(
801
23
         error,
802
23
         LIBCERROR_ERROR_DOMAIN_IO,
803
23
         LIBCERROR_IO_ERROR_READ_FAILED,
804
23
         "%s: unable to read section data.",
805
23
         function );
806
807
23
        goto on_error;
808
23
      }
809
8
      data_offset = 0;
810
8
    }
811
/* TODO flag that number of entries is corrupted and continue */
812
1.25k
    if( table_section->entries_size > ( table_section->section_data_size - data_offset ) )
813
3
    {
814
3
      libcerror_error_set(
815
3
       error,
816
3
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
817
3
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
818
3
       "%s: invalid section size value out of bounds - insufficient space for entries.",
819
3
       function );
820
821
3
      goto on_error;
822
3
    }
823
1.25k
    table_section->entries_offset = data_offset;
824
825
#if defined( HAVE_DEBUG_OUTPUT )
826
    if( libcnotify_verbose != 0 )
827
    {
828
      libcnotify_printf(
829
       "%s: table entries data:\n",
830
       function );
831
      libcnotify_print_data(
832
       &( table_section->section_data[ data_offset ] ),
833
       table_section->entries_size,
834
       0 );
835
    }
836
#endif
837
1.25k
    if( libewf_checksum_calculate_adler32(
838
1.25k
         &calculated_checksum,
839
1.25k
         &( table_section->section_data[ data_offset ] ),
840
1.25k
         table_section->entries_size,
841
1.25k
         1,
842
1.25k
         error ) != 1 )
843
0
    {
844
0
      libcerror_error_set(
845
0
       error,
846
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
847
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
848
0
       "%s: unable to calculate entries checksum.",
849
0
       function );
850
851
0
      goto on_error;
852
0
    }
853
1.25k
    data_offset += table_section->entries_size;
854
855
1.25k
    if( table_footer_data_size > 0 )
856
1.25k
    {
857
1.25k
      if( libewf_table_section_read_footer_data(
858
1.25k
           table_section,
859
1.25k
           &( table_section->section_data[ data_offset ] ),
860
1.25k
           table_section->section_data_size - data_offset,
861
1.25k
           format_version,
862
1.25k
           &stored_checksum,
863
1.25k
           error ) != 1 )
864
0
      {
865
0
        libcerror_error_set(
866
0
         error,
867
0
         LIBCERROR_ERROR_DOMAIN_IO,
868
0
         LIBCERROR_IO_ERROR_READ_FAILED,
869
0
         "%s: unable to read table section footer.",
870
0
         function );
871
872
0
        goto on_error;
873
0
      }
874
1.25k
      data_offset += table_footer_data_size;
875
876
1.25k
      if( stored_checksum != calculated_checksum )
877
1.22k
      {
878
#if defined( HAVE_VERBOSE_OUTPUT )
879
                          if( libcnotify_verbose != 0 )
880
        {
881
          libcnotify_printf(
882
           "%s: entries checksum does not match (stored: 0x%08" PRIx32 ", calculated: 0x%08" PRIx32 ").\n",
883
           function,
884
           stored_checksum,
885
           calculated_checksum );
886
        }
887
#endif
888
        /* The table entries cannot be fully trusted therefore mark them as corrupted
889
         */
890
1.22k
        table_section->entries_corrupted = 1;
891
1.22k
      }
892
1.25k
    }
893
1.25k
  }
894
#if defined( HAVE_VERBOSE_OUTPUT )
895
  else if( libcnotify_verbose != 0 )
896
  {
897
    if( table_section->number_of_entries == 0 )
898
    {
899
      libcnotify_printf(
900
       "%s: table section contains no entries.\n",
901
       function );
902
    }
903
  }
904
#endif
905
#if defined( HAVE_VERBOSE_OUTPUT ) || defined( HAVE_DEBUG_OUTPUT )
906
  if( libcnotify_verbose != 0 )
907
  {
908
    if( data_offset < table_section->section_data_size )
909
    {
910
#if defined( HAVE_DEBUG_OUTPUT )
911
      libcnotify_printf(
912
       "%s: trailing data:\n",
913
       function );
914
      libcnotify_print_data(
915
       &( table_section->section_data[ data_offset ] ),
916
       table_section->section_data_size - data_offset,
917
       0 );
918
919
#elif defined( HAVE_VERBOSE_OUTPUT )
920
      libcnotify_printf(
921
       "%s: section has trailing data.\n",
922
       function );
923
#endif
924
    }
925
  }
926
#endif
927
1.25k
  return( read_count );
928
929
152
on_error:
930
152
  if( table_section->section_data != NULL )
931
135
  {
932
135
    memory_free(
933
135
     table_section->section_data );
934
935
135
    table_section->section_data = NULL;
936
135
  }
937
152
  table_section->section_data_size = 0;
938
939
152
  return( -1 );
940
1.28k
}
941
942
/* Writes the header of a version 1 table or table2 section or version 2 sector table section
943
 * Returns the number of bytes written or -1 on error
944
 */
945
int libewf_table_section_write_header_data(
946
     libewf_table_section_t *table_section,
947
     uint8_t *data,
948
     size_t data_size,
949
     uint8_t format_version,
950
     libcerror_error_t **error )
951
0
{
952
0
  static char *function        = "libewf_table_section_write_header_data";
953
0
  size_t header_data_size      = 0;
954
0
  uint32_t calculated_checksum = 0;
955
956
0
  if( table_section == NULL )
957
0
  {
958
0
    libcerror_error_set(
959
0
     error,
960
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
961
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
962
0
     "%s: invalid table section.",
963
0
     function );
964
965
0
    return( -1 );
966
0
  }
967
0
  if( data == NULL )
968
0
  {
969
0
    libcerror_error_set(
970
0
     error,
971
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
972
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
973
0
     "%s: invalid data.",
974
0
     function );
975
976
0
    return( -1 );
977
0
  }
978
0
  if( format_version == 1 )
979
0
  {
980
0
    header_data_size = sizeof( ewf_table_header_v1_t );
981
0
  }
982
0
  else if( format_version == 2 )
983
0
  {
984
0
    header_data_size = sizeof( ewf_table_header_v2_t );
985
0
  }
986
0
  else
987
0
  {
988
0
    libcerror_error_set(
989
0
     error,
990
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
991
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
992
0
     "%s: unsupported format version.",
993
0
     function );
994
995
0
    return( -1 );
996
0
  }
997
0
  if( ( data_size < header_data_size )
998
0
   || ( data_size > (size_t) SSIZE_MAX ) )
999
0
  {
1000
0
    libcerror_error_set(
1001
0
     error,
1002
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1003
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1004
0
     "%s: invalid data size value out of bounds.",
1005
0
     function );
1006
1007
0
    return( -1 );
1008
0
  }
1009
0
  if( memory_set(
1010
0
       data,
1011
0
       0,
1012
0
       header_data_size ) == NULL )
1013
0
  {
1014
0
    libcerror_error_set(
1015
0
     error,
1016
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1017
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
1018
0
     "%s: unable to clear table header data.",
1019
0
     function );
1020
1021
0
    return( -1 );
1022
0
  }
1023
0
  if( format_version == 1 )
1024
0
  {
1025
0
    byte_stream_copy_from_uint32_little_endian(
1026
0
     ( (ewf_table_header_v1_t *) data )->number_of_entries,
1027
0
     table_section->number_of_entries );
1028
1029
0
    byte_stream_copy_from_uint64_little_endian(
1030
0
     ( (ewf_table_header_v1_t *) data )->base_offset,
1031
0
     table_section->base_offset );
1032
0
  }
1033
0
  else if( format_version == 2 )
1034
0
  {
1035
0
    byte_stream_copy_from_uint64_little_endian(
1036
0
     ( (ewf_table_header_v2_t *) data )->first_chunk_number,
1037
0
     table_section->first_chunk_index );
1038
1039
0
    byte_stream_copy_from_uint32_little_endian(
1040
0
     ( (ewf_table_header_v2_t *) data )->number_of_entries,
1041
0
     table_section->number_of_entries );
1042
1043
0
    header_data_size -= 12;
1044
0
  }
1045
0
  if( libewf_checksum_calculate_adler32(
1046
0
       &calculated_checksum,
1047
0
       data,
1048
0
       header_data_size - 4,
1049
0
       1,
1050
0
       error ) != 1 )
1051
0
  {
1052
0
    libcerror_error_set(
1053
0
     error,
1054
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1055
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1056
0
     "%s: unable to calculate checksum.",
1057
0
     function );
1058
1059
0
    return( -1 );
1060
0
  }
1061
0
  if( format_version == 1 )
1062
0
  {
1063
0
    byte_stream_copy_from_uint32_little_endian(
1064
0
     ( (ewf_table_header_v1_t *) data )->checksum,
1065
0
     calculated_checksum );
1066
0
  }
1067
0
  else if( format_version == 2 )
1068
0
  {
1069
0
    byte_stream_copy_from_uint32_little_endian(
1070
0
     ( (ewf_table_header_v2_t *) data )->checksum,
1071
0
     calculated_checksum );
1072
1073
0
    header_data_size += 12;
1074
0
  }
1075
#if defined( HAVE_DEBUG_OUTPUT )
1076
  if( libcnotify_verbose != 0 )
1077
  {
1078
    libcnotify_printf(
1079
     "%s: table header data:\n",
1080
     function );
1081
    libcnotify_print_data(
1082
     data,
1083
     header_data_size,
1084
     0 );
1085
  }
1086
#endif
1087
0
  return( 1 );
1088
0
}
1089
1090
/* Writes the footer of a version 1 table or table2 section or version 2 sector table section
1091
 * Returns the number of bytes written or -1 on error
1092
 */
1093
int libewf_table_section_write_footer_data(
1094
     libewf_table_section_t *table_section,
1095
     uint8_t *data,
1096
     size_t data_size,
1097
     uint8_t format_version,
1098
     uint32_t calculated_checksum,
1099
     libcerror_error_t **error )
1100
0
{
1101
0
  static char *function   = "libewf_table_section_write_footer_data";
1102
0
  size_t footer_data_size = 0;
1103
1104
0
  if( table_section == NULL )
1105
0
  {
1106
0
    libcerror_error_set(
1107
0
     error,
1108
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1109
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1110
0
     "%s: invalid table section.",
1111
0
     function );
1112
1113
0
    return( -1 );
1114
0
  }
1115
0
  if( data == NULL )
1116
0
  {
1117
0
    libcerror_error_set(
1118
0
     error,
1119
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1120
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1121
0
     "%s: invalid data.",
1122
0
     function );
1123
1124
0
    return( -1 );
1125
0
  }
1126
0
  if( format_version == 1 )
1127
0
  {
1128
0
    footer_data_size = 4;
1129
0
  }
1130
0
  else if( format_version == 2 )
1131
0
  {
1132
0
    footer_data_size = 16;
1133
0
  }
1134
0
  else
1135
0
  {
1136
0
    libcerror_error_set(
1137
0
     error,
1138
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1139
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1140
0
     "%s: unsupported format version.",
1141
0
     function );
1142
1143
0
    return( -1 );
1144
0
  }
1145
0
  if( ( data_size < footer_data_size )
1146
0
   || ( data_size > (size_t) SSIZE_MAX ) )
1147
0
  {
1148
0
    libcerror_error_set(
1149
0
     error,
1150
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1151
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1152
0
     "%s: invalid data size value out of bounds.",
1153
0
     function );
1154
1155
0
    return( -1 );
1156
0
  }
1157
0
  if( memory_set(
1158
0
       data,
1159
0
       0,
1160
0
       footer_data_size ) == NULL )
1161
0
  {
1162
0
    libcerror_error_set(
1163
0
     error,
1164
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1165
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
1166
0
     "%s: unable to clear data.",
1167
0
     function );
1168
1169
0
    return( -1 );
1170
0
  }
1171
0
  byte_stream_copy_from_uint32_little_endian(
1172
0
   data,
1173
0
   calculated_checksum );
1174
1175
#if defined( HAVE_DEBUG_OUTPUT )
1176
  if( libcnotify_verbose != 0 )
1177
  {
1178
    libcnotify_printf(
1179
     "%s: table footer data:\n",
1180
     function );
1181
    libcnotify_print_data(
1182
     data,
1183
     footer_data_size,
1184
     0 );
1185
  }
1186
#endif
1187
0
  return( 1 );
1188
0
}
1189
1190
/* Writes a version 1 table or table2 section or version 2 sector table section
1191
 * Returns the number of bytes written or -1 on error
1192
 */
1193
ssize_t libewf_table_section_write_file_io_pool(
1194
         libewf_table_section_t *table_section,
1195
         libewf_io_handle_t *io_handle,
1196
         libbfio_pool_t *file_io_pool,
1197
         int file_io_pool_entry,
1198
         uint8_t format_version,
1199
         uint8_t segment_file_type,
1200
         uint8_t *type_string,
1201
         size_t type_string_length,
1202
         off64_t section_offset,
1203
         uint8_t *table_entries_data,
1204
         size_t table_entries_data_size,
1205
         size64_t chunks_data_size,
1206
         libcerror_error_t **error )
1207
0
{
1208
0
  libewf_section_descriptor_t *section_descriptor = NULL;
1209
0
  static char *function                           = "libewf_table_section_write_file_io_pool";
1210
0
  size_t data_offset                              = 0;
1211
0
  size_t required_section_data_size               = 0;
1212
0
  size_t section_descriptor_data_size             = 0;
1213
0
  size_t table_entry_data_size                    = 0;
1214
0
  size_t table_footer_data_size                   = 0;
1215
0
  size_t table_header_data_size                   = 0;
1216
0
  size_t used_table_entries_data_size             = 0;
1217
0
  ssize_t total_write_count                       = 0;
1218
0
  ssize_t write_count                             = 0;
1219
0
  uint32_t calculated_checksum                    = 0;
1220
0
  uint32_t section_padding_size                   = 0;
1221
1222
0
  if( table_section == NULL )
1223
0
  {
1224
0
    libcerror_error_set(
1225
0
     error,
1226
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1227
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1228
0
     "%s: invalid table section.",
1229
0
     function );
1230
1231
0
    return( -1 );
1232
0
  }
1233
0
  if( table_section->section_data == NULL )
1234
0
  {
1235
0
    libcerror_error_set(
1236
0
     error,
1237
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1238
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1239
0
     "%s: invalid table section - missing section data.",
1240
0
     function );
1241
1242
0
    return( -1 );
1243
0
  }
1244
0
  if( table_section->section_data_size > (size_t) SSIZE_MAX )
1245
0
  {
1246
0
    libcerror_error_set(
1247
0
     error,
1248
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1249
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1250
0
     "%s: invalid table section - section data size value exceeds maximum.",
1251
0
     function );
1252
1253
0
    return( -1 );
1254
0
  }
1255
0
  if( table_section->base_offset > (uint64_t) INT64_MAX )
1256
0
  {
1257
0
    libcerror_error_set(
1258
0
     error,
1259
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1260
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1261
0
     "%s: invalid table section - base offset value exceeds maximum.",
1262
0
     function );
1263
1264
0
    return( -1 );
1265
0
  }
1266
0
  if( table_section->number_of_entries == 0 )
1267
0
  {
1268
0
    libcerror_error_set(
1269
0
     error,
1270
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1271
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1272
0
     "%s: invalid table section - number of entries values out of bounds.",
1273
0
     function );
1274
1275
0
    return( -1 );
1276
0
  }
1277
0
  if( format_version == 1 )
1278
0
  {
1279
0
    section_descriptor_data_size = sizeof( ewf_section_descriptor_v1_t );
1280
0
    table_header_data_size       = sizeof( ewf_table_header_v1_t );
1281
0
    table_entry_data_size        = sizeof( ewf_table_entry_v1_t );
1282
0
    table_footer_data_size       = 4;
1283
0
  }
1284
0
  else if( format_version == 2 )
1285
0
  {
1286
0
    section_descriptor_data_size = sizeof( ewf_section_descriptor_v2_t );
1287
0
    table_header_data_size       = sizeof( ewf_table_header_v2_t );
1288
0
    table_entry_data_size        = sizeof( ewf_table_entry_v2_t );
1289
0
    table_footer_data_size       = 16;
1290
0
    section_padding_size         = 24;
1291
0
  }
1292
0
  else
1293
0
  {
1294
0
    libcerror_error_set(
1295
0
     error,
1296
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1297
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1298
0
     "%s: unsupported format version.",
1299
0
     function );
1300
1301
0
    return( -1 );
1302
0
  }
1303
0
  if( type_string == NULL )
1304
0
  {
1305
0
    libcerror_error_set(
1306
0
     error,
1307
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1308
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1309
0
     "%s: invalid type string.",
1310
0
     function );
1311
1312
0
    return( -1 );
1313
0
  }
1314
0
  if( table_entries_data == NULL )
1315
0
  {
1316
0
    libcerror_error_set(
1317
0
     error,
1318
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1319
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1320
0
     "%s: invalid table entries data.",
1321
0
     function );
1322
1323
0
    return( -1 );
1324
0
  }
1325
/* TODO improve bounds check */
1326
0
  if( ( table_entries_data_size == 0 )
1327
0
   || ( table_entries_data_size > (size_t) SSIZE_MAX ) )
1328
0
  {
1329
0
    libcerror_error_set(
1330
0
     error,
1331
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1332
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1333
0
     "%s: invalid table entries data size value out of bounds.",
1334
0
     function );
1335
1336
0
    return( -1 );
1337
0
  }
1338
0
  used_table_entries_data_size = table_section->number_of_entries * table_entry_data_size;
1339
1340
0
  if( used_table_entries_data_size > table_entries_data_size )
1341
0
  {
1342
0
    libcerror_error_set(
1343
0
     error,
1344
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1345
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1346
0
     "%s: invalid table entries data size value out of bounds.",
1347
0
     function );
1348
1349
0
    goto on_error;
1350
0
  }
1351
0
  required_section_data_size = table_header_data_size
1352
0
                             + used_table_entries_data_size;
1353
1354
0
  if( segment_file_type != LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
1355
0
  {
1356
0
    required_section_data_size += table_footer_data_size;
1357
0
  }
1358
0
  if( required_section_data_size > table_section->section_data_size )
1359
0
  {
1360
0
    libcerror_error_set(
1361
0
     error,
1362
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1363
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1364
0
     "%s: invalid section data value too small.",
1365
0
     function );
1366
1367
0
    goto on_error;
1368
0
  }
1369
0
  if( libewf_section_descriptor_initialize(
1370
0
       &section_descriptor,
1371
0
       error ) != 1 )
1372
0
  {
1373
0
    libcerror_error_set(
1374
0
     error,
1375
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1376
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1377
0
     "%s: unable to create section descriptor.",
1378
0
     function );
1379
1380
0
    goto on_error;
1381
0
  }
1382
0
  if( libewf_section_descriptor_set(
1383
0
       section_descriptor,
1384
0
       LIBEWF_SECTION_TYPE_SECTOR_TABLE,
1385
0
       type_string,
1386
0
       type_string_length,
1387
0
       section_offset,
1388
0
       section_descriptor_data_size + required_section_data_size + chunks_data_size,
1389
0
       required_section_data_size + chunks_data_size,
1390
0
       section_padding_size,
1391
0
       error ) != 1 )
1392
0
  {
1393
0
    libcerror_error_set(
1394
0
     error,
1395
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1396
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1397
0
     "%s: unable to set section descriptor.",
1398
0
     function );
1399
1400
0
    goto on_error;
1401
0
  }
1402
0
  if( format_version == 1 )
1403
0
  {
1404
0
    write_count = libewf_section_descriptor_write_file_io_pool(
1405
0
             section_descriptor,
1406
0
             file_io_pool,
1407
0
             file_io_pool_entry,
1408
0
             format_version,
1409
0
             error );
1410
1411
0
    if( write_count != (ssize_t) section_descriptor_data_size )
1412
0
    {
1413
0
      libcerror_error_set(
1414
0
       error,
1415
0
       LIBCERROR_ERROR_DOMAIN_IO,
1416
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
1417
0
       "%s: unable to write section descriptor data.",
1418
0
       function );
1419
1420
0
      goto on_error;
1421
0
    }
1422
0
    total_write_count += write_count;
1423
0
  }
1424
0
  if( libewf_table_section_write_header_data(
1425
0
       table_section,
1426
0
       table_section->section_data,
1427
0
       table_section->section_data_size,
1428
0
       format_version,
1429
0
       error ) != 1 )
1430
0
  {
1431
0
    libcerror_error_set(
1432
0
     error,
1433
0
     LIBCERROR_ERROR_DOMAIN_IO,
1434
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
1435
0
     "%s: unable to write section header data.",
1436
0
     function );
1437
1438
0
    goto on_error;
1439
0
  }
1440
0
  data_offset = table_header_data_size;
1441
1442
0
  if( &( table_section->section_data[ data_offset ] ) != table_entries_data )
1443
0
  {
1444
0
    libcerror_error_set(
1445
0
     error,
1446
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1447
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1448
0
     "%s: invalid table entries data value out of bounds.",
1449
0
     function );
1450
1451
0
    goto on_error;
1452
0
  }
1453
#if defined( HAVE_DEBUG_OUTPUT )
1454
  if( libcnotify_verbose != 0 )
1455
  {
1456
    libcnotify_printf(
1457
     "%s: table entries data:\n",
1458
     function );
1459
    libcnotify_print_data(
1460
     &( table_section->section_data[ data_offset ] ),
1461
     used_table_entries_data_size,
1462
     0 );
1463
  }
1464
#endif
1465
0
  if( segment_file_type != LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
1466
0
  {
1467
0
    if( libewf_checksum_calculate_adler32(
1468
0
         &calculated_checksum,
1469
0
         &( table_section->section_data[ data_offset ] ),
1470
0
         used_table_entries_data_size,
1471
0
         1,
1472
0
         error ) != 1 )
1473
0
    {
1474
0
      libcerror_error_set(
1475
0
       error,
1476
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1477
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1478
0
       "%s: unable to calculate checksum.",
1479
0
       function );
1480
1481
0
      goto on_error;
1482
0
    }
1483
0
    data_offset += used_table_entries_data_size;
1484
1485
0
    if( libewf_table_section_write_footer_data(
1486
0
         table_section,
1487
0
         &( table_section->section_data[ data_offset ] ),
1488
0
         table_section->section_data_size - data_offset,
1489
0
         format_version,
1490
0
         calculated_checksum,
1491
0
         error ) != 1 )
1492
0
    {
1493
0
      libcerror_error_set(
1494
0
       error,
1495
0
       LIBCERROR_ERROR_DOMAIN_IO,
1496
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
1497
0
       "%s: unable to write section footer data.",
1498
0
       function );
1499
1500
0
      goto on_error;
1501
0
    }
1502
0
  }
1503
0
  write_count = libewf_section_write_data(
1504
0
                 section_descriptor,
1505
0
                 io_handle,
1506
0
                 file_io_pool,
1507
0
                 file_io_pool_entry,
1508
0
                 table_section->section_data,
1509
0
                 required_section_data_size,
1510
0
                 error );
1511
1512
0
  if( write_count == -1 )
1513
0
  {
1514
0
    libcerror_error_set(
1515
0
     error,
1516
0
     LIBCERROR_ERROR_DOMAIN_IO,
1517
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
1518
0
     "%s: unable to write section data.",
1519
0
     function );
1520
1521
0
    goto on_error;
1522
0
  }
1523
0
  total_write_count += write_count;
1524
1525
0
  if( format_version == 2 )
1526
0
  {
1527
0
    write_count = libewf_section_descriptor_write_file_io_pool(
1528
0
             section_descriptor,
1529
0
             file_io_pool,
1530
0
             file_io_pool_entry,
1531
0
             format_version,
1532
0
             error );
1533
1534
0
    if( write_count != (ssize_t) section_descriptor_data_size )
1535
0
    {
1536
0
      libcerror_error_set(
1537
0
       error,
1538
0
       LIBCERROR_ERROR_DOMAIN_IO,
1539
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
1540
0
       "%s: unable to write section descriptor data.",
1541
0
       function );
1542
1543
0
      goto on_error;
1544
0
    }
1545
0
    total_write_count += write_count;
1546
0
  }
1547
0
  if( libewf_section_descriptor_free(
1548
0
       &section_descriptor,
1549
0
       error ) != 1 )
1550
0
  {
1551
0
    libcerror_error_set(
1552
0
     error,
1553
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1554
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1555
0
     "%s: unable to free section.",
1556
0
     function );
1557
1558
0
    goto on_error;
1559
0
  }
1560
0
  return( total_write_count );
1561
1562
0
on_error:
1563
0
  if( section_descriptor != NULL )
1564
0
  {
1565
0
    libewf_section_descriptor_free(
1566
0
     &section_descriptor,
1567
0
     NULL );
1568
0
  }
1569
0
  return( -1 );
1570
0
}
1571