Coverage Report

Created: 2026-10-22 07:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libewf/libewf/libewf_table_section.c
Line
Count
Source
1
/*
2
 * Table section functions
3
 *
4
 * Copyright (C) 2006-2026, 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.38k
{
45
1.38k
  static char *function = "libewf_table_section_initialize";
46
47
1.38k
  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.38k
  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.38k
  *table_section = memory_allocate_structure(
70
1.38k
                    libewf_table_section_t );
71
72
1.38k
  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.38k
  if( memory_set(
84
1.38k
       *table_section,
85
1.38k
       0,
86
1.38k
       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.38k
  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.38k
}
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.38k
{
117
1.38k
  static char *function = "libewf_table_section_free";
118
119
1.38k
  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.38k
  if( *table_section != NULL )
131
1.38k
  {
132
1.38k
    if( ( *table_section )->section_data != NULL )
133
1.22k
    {
134
1.22k
      memory_free(
135
1.22k
       ( *table_section )->section_data );
136
1.22k
    }
137
1.38k
    memory_free(
138
1.38k
     *table_section );
139
140
1.38k
    *table_section = NULL;
141
1.38k
  }
142
1.38k
  return( 1 );
143
1.38k
}
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.31k
{
156
1.31k
  static char *function              = "libewf_table_section_read_header_data";
157
1.31k
  size_t header_data_size            = 0;
158
1.31k
  uint32_t calculated_checksum       = 0;
159
1.31k
  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.31k
  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.31k
  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.31k
  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.31k
  if( format_version == 1 )
202
1.31k
  {
203
1.31k
    header_data_size = sizeof( ewf_table_header_v1_t );
204
1.31k
  }
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.31k
  if( ( data_size < header_data_size )
221
1.31k
   || ( 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.31k
  if( format_version == 1 )
245
1.31k
  {
246
1.31k
    byte_stream_copy_to_uint32_little_endian(
247
1.31k
     ( (ewf_table_header_v1_t *) data )->number_of_entries,
248
1.31k
     table_section->number_of_entries );
249
250
1.31k
    byte_stream_copy_to_uint64_little_endian(
251
1.31k
     ( (ewf_table_header_v1_t *) data )->base_offset,
252
1.31k
     table_section->base_offset );
253
254
1.31k
    byte_stream_copy_to_uint32_little_endian(
255
1.31k
     ( (ewf_table_header_v1_t *) data )->checksum,
256
1.31k
     stored_checksum );
257
1.31k
  }
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.31k
  if( format_version == 1 )
344
1.31k
  {
345
1.31k
    header_data_size -= 4;
346
1.31k
  }
347
0
  else if( format_version == 2 )
348
0
  {
349
0
    header_data_size -= 16;
350
0
  }
351
1.31k
  if( libewf_checksum_calculate_adler32(
352
1.31k
       &calculated_checksum,
353
1.31k
       data,
354
1.31k
       header_data_size,
355
1.31k
       1,
356
1.31k
       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.31k
  if( stored_checksum != calculated_checksum )
369
55
  {
370
55
    libcerror_error_set(
371
55
     error,
372
55
     LIBCERROR_ERROR_DOMAIN_INPUT,
373
55
     LIBCERROR_INPUT_ERROR_CHECKSUM_MISMATCH,
374
55
     "%s: header checksum does not match (stored: 0x%08" PRIx32 ", calculated: 0x%08" PRIx32 ").",
375
55
     function,
376
55
     stored_checksum,
377
55
     calculated_checksum );
378
379
55
    return( -1 );
380
55
  }
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.25k
  if( table_section->base_offset > (uint64_t) INT64_MAX )
409
6
  {
410
6
    libcerror_error_set(
411
6
     error,
412
6
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
413
6
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
414
6
     "%s: invalid base offset value out of bounds.",
415
6
     function );
416
417
6
    return( -1 );
418
6
  }
419
1.25k
  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.25k
  return( 1 );
431
1.25k
}
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.22k
{
444
1.22k
  static char *function         = "libewf_table_section_read_footer_data";
445
1.22k
  size_t footer_data_size       = 0;
446
1.22k
  uint32_t safe_stored_checksum = 0;
447
448
1.22k
  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.22k
  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.22k
  if( format_version == 1 )
471
1.22k
  {
472
1.22k
    footer_data_size = 4;
473
1.22k
  }
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.22k
  if( data_size != footer_data_size )
490
1
  {
491
1
    libcerror_error_set(
492
1
     error,
493
1
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
494
1
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
495
1
     "%s: invalid data size value out of bounds.",
496
1
     function );
497
498
1
    return( -1 );
499
1
  }
500
1.22k
  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.22k
  byte_stream_copy_to_uint32_little_endian(
524
1.22k
   data,
525
1.22k
   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.22k
  *stored_checksum = safe_stored_checksum;
554
555
1.22k
  return( 1 );
556
1.22k
}
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.38k
{
572
1.38k
  static char *function         = "libewf_table_section_read_file_io_pool";
573
1.38k
  size_t data_offset            = 0;
574
1.38k
  size_t table_entry_data_size  = 0;
575
1.38k
  size_t table_footer_data_size = 0;
576
1.38k
  size_t table_header_data_size = 0;
577
1.38k
  ssize_t read_count            = 0;
578
1.38k
  uint32_t calculated_checksum  = 0;
579
1.38k
  uint32_t stored_checksum      = 0;
580
581
1.38k
  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.38k
  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.38k
  if( format_version == 1 )
604
1.38k
  {
605
1.38k
    table_header_data_size = sizeof( ewf_table_header_v1_t );
606
1.38k
    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.38k
    if( segment_file_type != LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
611
1.38k
    {
612
1.38k
      table_footer_data_size = 4;
613
1.38k
    }
614
1.38k
  }
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.38k
  if( ( section_data_size == 0 )
633
1.38k
   || ( 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.38k
  if( ( segment_file_type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
647
1.38k
   || ( io_handle->format == LIBEWF_FORMAT_ENCASE1 ) )
648
89
  {
649
/* TODO consider reading max number of chunks for table with chunk data */
650
89
    table_section->section_data_size = (size_t) table_header_data_size;
651
89
  }
652
1.29k
  else
653
1.29k
  {
654
1.29k
    table_section->section_data_size = (size_t) section_data_size;
655
1.29k
  }
656
1.38k
  if( ( table_section->section_data_size < table_header_data_size )
657
1.38k
   || ( table_section->section_data_size > MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
658
30
  {
659
30
    libcerror_error_set(
660
30
     error,
661
30
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
662
30
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
663
30
     "%s: invalid section data size value out of bounds.",
664
30
     function );
665
666
30
    goto on_error;
667
30
  }
668
1.35k
  table_section->section_data = (uint8_t *) memory_allocate(
669
1.35k
                                             sizeof( uint8_t ) * table_section->section_data_size );
670
671
1.35k
  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.35k
  read_count = libbfio_pool_read_buffer(
683
1.35k
                file_io_pool,
684
1.35k
                file_io_pool_entry,
685
1.35k
                table_section->section_data,
686
1.35k
                table_section->section_data_size,
687
1.35k
                error );
688
689
1.35k
  if( read_count != (ssize_t) table_section->section_data_size )
690
39
  {
691
39
    libcerror_error_set(
692
39
     error,
693
39
     LIBCERROR_ERROR_DOMAIN_IO,
694
39
     LIBCERROR_IO_ERROR_READ_FAILED,
695
39
     "%s: unable to read section data.",
696
39
     function );
697
698
39
    goto on_error;
699
39
  }
700
1.31k
  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.31k
  if( libewf_table_section_read_header_data(
724
1.31k
       table_section,
725
1.31k
       io_handle,
726
1.31k
       table_section->section_data,
727
1.31k
       table_section->section_data_size,
728
1.31k
       format_version,
729
1.31k
       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.25k
  data_offset = table_header_data_size;
741
742
1.25k
  if( table_section->number_of_entries > 0 )
743
1.25k
  {
744
1.25k
    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.24k
    table_section->entries_size = (size_t) table_section->number_of_entries * table_entry_data_size;
756
757
1.24k
    if( ( segment_file_type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
758
1.24k
     || ( io_handle->format == LIBEWF_FORMAT_ENCASE1 ) )
759
40
    {
760
40
      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
40
      table_section->section_data_size = table_section->entries_size + table_footer_data_size;
772
773
40
      memory_free(
774
40
       table_section->section_data );
775
776
/* TODO consider using memory_reallocate */
777
40
      table_section->section_data = (uint8_t *) memory_allocate(
778
40
                                                 sizeof( uint8_t ) * table_section->section_data_size );
779
780
40
      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
40
      read_count = libbfio_pool_read_buffer(
792
40
              file_io_pool,
793
40
              file_io_pool_entry,
794
40
              table_section->section_data,
795
40
              table_section->section_data_size,
796
40
              error );
797
798
40
      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
17
      data_offset = 0;
810
17
    }
811
/* TODO flag that number of entries is corrupted and continue */
812
1.22k
    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.22k
    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.22k
    if( libewf_checksum_calculate_adler32(
838
1.22k
         &calculated_checksum,
839
1.22k
         &( table_section->section_data[ data_offset ] ),
840
1.22k
         table_section->entries_size,
841
1.22k
         1,
842
1.22k
         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.22k
    data_offset += table_section->entries_size;
854
855
1.22k
    if( table_footer_data_size > 0 )
856
1.22k
    {
857
1.22k
      if( libewf_table_section_read_footer_data(
858
1.22k
           table_section,
859
1.22k
           &( table_section->section_data[ data_offset ] ),
860
1.22k
           table_section->section_data_size - data_offset,
861
1.22k
           format_version,
862
1.22k
           &stored_checksum,
863
1.22k
           error ) != 1 )
864
1
      {
865
1
        libcerror_error_set(
866
1
         error,
867
1
         LIBCERROR_ERROR_DOMAIN_IO,
868
1
         LIBCERROR_IO_ERROR_READ_FAILED,
869
1
         "%s: unable to read table section footer.",
870
1
         function );
871
872
1
        goto on_error;
873
1
      }
874
#if defined( HAVE_VERBOSE_OUTPUT ) || defined( HAVE_DEBUG_OUTPUT )
875
      data_offset += table_footer_data_size;
876
#endif
877
1.22k
      if( stored_checksum != calculated_checksum )
878
1.19k
      {
879
#if defined( HAVE_VERBOSE_OUTPUT )
880
                          if( libcnotify_verbose != 0 )
881
        {
882
          libcnotify_printf(
883
           "%s: entries checksum does not match (stored: 0x%08" PRIx32 ", calculated: 0x%08" PRIx32 ").\n",
884
           function,
885
           stored_checksum,
886
           calculated_checksum );
887
        }
888
#endif
889
        /* The table entries cannot be fully trusted therefore mark them as corrupted
890
         */
891
1.19k
        table_section->entries_corrupted = 1;
892
1.19k
      }
893
1.22k
    }
894
1.22k
  }
895
#if defined( HAVE_VERBOSE_OUTPUT )
896
  else if( libcnotify_verbose != 0 )
897
  {
898
    if( table_section->number_of_entries == 0 )
899
    {
900
      libcnotify_printf(
901
       "%s: table section contains no entries.\n",
902
       function );
903
    }
904
  }
905
#endif
906
#if defined( HAVE_VERBOSE_OUTPUT ) || defined( HAVE_DEBUG_OUTPUT )
907
  if( libcnotify_verbose != 0 )
908
  {
909
    if( data_offset < table_section->section_data_size )
910
    {
911
#if defined( HAVE_DEBUG_OUTPUT )
912
      libcnotify_printf(
913
       "%s: trailing data:\n",
914
       function );
915
      libcnotify_print_data(
916
       &( table_section->section_data[ data_offset ] ),
917
       table_section->section_data_size - data_offset,
918
       0 );
919
920
#elif defined( HAVE_VERBOSE_OUTPUT )
921
      libcnotify_printf(
922
       "%s: section has trailing data.\n",
923
       function );
924
#endif
925
    }
926
  }
927
#endif
928
1.22k
  return( read_count );
929
930
162
on_error:
931
162
  if( table_section->section_data != NULL )
932
132
  {
933
132
    memory_free(
934
132
     table_section->section_data );
935
936
132
    table_section->section_data = NULL;
937
132
  }
938
162
  table_section->section_data_size = 0;
939
940
162
  return( -1 );
941
1.25k
}
942
943
/* Writes the header of a version 1 table or table2 section or version 2 sector table section
944
 * Returns the number of bytes written or -1 on error
945
 */
946
int libewf_table_section_write_header_data(
947
     libewf_table_section_t *table_section,
948
     uint8_t *data,
949
     size_t data_size,
950
     uint8_t format_version,
951
     libcerror_error_t **error )
952
0
{
953
0
  static char *function        = "libewf_table_section_write_header_data";
954
0
  size_t header_data_size      = 0;
955
0
  uint32_t calculated_checksum = 0;
956
957
0
  if( table_section == NULL )
958
0
  {
959
0
    libcerror_error_set(
960
0
     error,
961
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
962
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
963
0
     "%s: invalid table section.",
964
0
     function );
965
966
0
    return( -1 );
967
0
  }
968
0
  if( data == NULL )
969
0
  {
970
0
    libcerror_error_set(
971
0
     error,
972
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
973
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
974
0
     "%s: invalid data.",
975
0
     function );
976
977
0
    return( -1 );
978
0
  }
979
0
  if( format_version == 1 )
980
0
  {
981
0
    header_data_size = sizeof( ewf_table_header_v1_t );
982
0
  }
983
0
  else if( format_version == 2 )
984
0
  {
985
0
    header_data_size = sizeof( ewf_table_header_v2_t );
986
0
  }
987
0
  else
988
0
  {
989
0
    libcerror_error_set(
990
0
     error,
991
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
992
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
993
0
     "%s: unsupported format version.",
994
0
     function );
995
996
0
    return( -1 );
997
0
  }
998
0
  if( ( data_size < header_data_size )
999
0
   || ( data_size > (size_t) SSIZE_MAX ) )
1000
0
  {
1001
0
    libcerror_error_set(
1002
0
     error,
1003
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1004
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1005
0
     "%s: invalid data size value out of bounds.",
1006
0
     function );
1007
1008
0
    return( -1 );
1009
0
  }
1010
0
  if( memory_set(
1011
0
       data,
1012
0
       0,
1013
0
       header_data_size ) == NULL )
1014
0
  {
1015
0
    libcerror_error_set(
1016
0
     error,
1017
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1018
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
1019
0
     "%s: unable to clear table header data.",
1020
0
     function );
1021
1022
0
    return( -1 );
1023
0
  }
1024
0
  if( format_version == 1 )
1025
0
  {
1026
0
    byte_stream_copy_from_uint32_little_endian(
1027
0
     ( (ewf_table_header_v1_t *) data )->number_of_entries,
1028
0
     table_section->number_of_entries );
1029
1030
0
    byte_stream_copy_from_uint64_little_endian(
1031
0
     ( (ewf_table_header_v1_t *) data )->base_offset,
1032
0
     table_section->base_offset );
1033
0
  }
1034
0
  else if( format_version == 2 )
1035
0
  {
1036
0
    byte_stream_copy_from_uint64_little_endian(
1037
0
     ( (ewf_table_header_v2_t *) data )->first_chunk_number,
1038
0
     table_section->first_chunk_index );
1039
1040
0
    byte_stream_copy_from_uint32_little_endian(
1041
0
     ( (ewf_table_header_v2_t *) data )->number_of_entries,
1042
0
     table_section->number_of_entries );
1043
1044
0
    header_data_size -= 12;
1045
0
  }
1046
0
  if( libewf_checksum_calculate_adler32(
1047
0
       &calculated_checksum,
1048
0
       data,
1049
0
       header_data_size - 4,
1050
0
       1,
1051
0
       error ) != 1 )
1052
0
  {
1053
0
    libcerror_error_set(
1054
0
     error,
1055
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1056
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1057
0
     "%s: unable to calculate checksum.",
1058
0
     function );
1059
1060
0
    return( -1 );
1061
0
  }
1062
0
  if( format_version == 1 )
1063
0
  {
1064
0
    byte_stream_copy_from_uint32_little_endian(
1065
0
     ( (ewf_table_header_v1_t *) data )->checksum,
1066
0
     calculated_checksum );
1067
0
  }
1068
0
  else if( format_version == 2 )
1069
0
  {
1070
0
    byte_stream_copy_from_uint32_little_endian(
1071
0
     ( (ewf_table_header_v2_t *) data )->checksum,
1072
0
     calculated_checksum );
1073
1074
#if defined( HAVE_DEBUG_OUTPUT )
1075
    header_data_size += 12;
1076
#endif
1077
0
  }
1078
#if defined( HAVE_DEBUG_OUTPUT )
1079
  if( libcnotify_verbose != 0 )
1080
  {
1081
    libcnotify_printf(
1082
     "%s: table header data:\n",
1083
     function );
1084
    libcnotify_print_data(
1085
     data,
1086
     header_data_size,
1087
     0 );
1088
  }
1089
#endif
1090
0
  return( 1 );
1091
0
}
1092
1093
/* Writes the footer of a version 1 table or table2 section or version 2 sector table section
1094
 * Returns the number of bytes written or -1 on error
1095
 */
1096
int libewf_table_section_write_footer_data(
1097
     libewf_table_section_t *table_section,
1098
     uint8_t *data,
1099
     size_t data_size,
1100
     uint8_t format_version,
1101
     uint32_t calculated_checksum,
1102
     libcerror_error_t **error )
1103
0
{
1104
0
  static char *function   = "libewf_table_section_write_footer_data";
1105
0
  size_t footer_data_size = 0;
1106
1107
0
  if( table_section == NULL )
1108
0
  {
1109
0
    libcerror_error_set(
1110
0
     error,
1111
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1112
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1113
0
     "%s: invalid table section.",
1114
0
     function );
1115
1116
0
    return( -1 );
1117
0
  }
1118
0
  if( data == NULL )
1119
0
  {
1120
0
    libcerror_error_set(
1121
0
     error,
1122
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1123
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1124
0
     "%s: invalid data.",
1125
0
     function );
1126
1127
0
    return( -1 );
1128
0
  }
1129
0
  if( format_version == 1 )
1130
0
  {
1131
0
    footer_data_size = 4;
1132
0
  }
1133
0
  else if( format_version == 2 )
1134
0
  {
1135
0
    footer_data_size = 16;
1136
0
  }
1137
0
  else
1138
0
  {
1139
0
    libcerror_error_set(
1140
0
     error,
1141
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1142
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1143
0
     "%s: unsupported format version.",
1144
0
     function );
1145
1146
0
    return( -1 );
1147
0
  }
1148
0
  if( ( data_size < footer_data_size )
1149
0
   || ( data_size > (size_t) SSIZE_MAX ) )
1150
0
  {
1151
0
    libcerror_error_set(
1152
0
     error,
1153
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1154
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1155
0
     "%s: invalid data size value out of bounds.",
1156
0
     function );
1157
1158
0
    return( -1 );
1159
0
  }
1160
0
  if( memory_set(
1161
0
       data,
1162
0
       0,
1163
0
       footer_data_size ) == NULL )
1164
0
  {
1165
0
    libcerror_error_set(
1166
0
     error,
1167
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1168
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
1169
0
     "%s: unable to clear data.",
1170
0
     function );
1171
1172
0
    return( -1 );
1173
0
  }
1174
0
  byte_stream_copy_from_uint32_little_endian(
1175
0
   data,
1176
0
   calculated_checksum );
1177
1178
#if defined( HAVE_DEBUG_OUTPUT )
1179
  if( libcnotify_verbose != 0 )
1180
  {
1181
    libcnotify_printf(
1182
     "%s: table footer data:\n",
1183
     function );
1184
    libcnotify_print_data(
1185
     data,
1186
     footer_data_size,
1187
     0 );
1188
  }
1189
#endif
1190
0
  return( 1 );
1191
0
}
1192
1193
/* Writes a version 1 table or table2 section or version 2 sector table section
1194
 * Returns the number of bytes written or -1 on error
1195
 */
1196
ssize_t libewf_table_section_write_file_io_pool(
1197
         libewf_table_section_t *table_section,
1198
         libewf_io_handle_t *io_handle,
1199
         libbfio_pool_t *file_io_pool,
1200
         int file_io_pool_entry,
1201
         uint8_t format_version,
1202
         uint8_t segment_file_type,
1203
         uint8_t *type_string,
1204
         size_t type_string_length,
1205
         off64_t section_offset,
1206
         uint8_t *table_entries_data,
1207
         size_t table_entries_data_size,
1208
         size64_t chunks_data_size,
1209
         libcerror_error_t **error )
1210
0
{
1211
0
  libewf_section_descriptor_t *section_descriptor = NULL;
1212
0
  static char *function                           = "libewf_table_section_write_file_io_pool";
1213
0
  size_t data_offset                              = 0;
1214
0
  size_t required_section_data_size               = 0;
1215
0
  size_t section_descriptor_data_size             = 0;
1216
0
  size_t table_entry_data_size                    = 0;
1217
0
  size_t table_footer_data_size                   = 0;
1218
0
  size_t table_header_data_size                   = 0;
1219
0
  size_t used_table_entries_data_size             = 0;
1220
0
  ssize_t total_write_count                       = 0;
1221
0
  ssize_t write_count                             = 0;
1222
0
  uint32_t calculated_checksum                    = 0;
1223
0
  uint32_t section_padding_size                   = 0;
1224
1225
0
  if( table_section == NULL )
1226
0
  {
1227
0
    libcerror_error_set(
1228
0
     error,
1229
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1230
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1231
0
     "%s: invalid table section.",
1232
0
     function );
1233
1234
0
    return( -1 );
1235
0
  }
1236
0
  if( table_section->section_data == NULL )
1237
0
  {
1238
0
    libcerror_error_set(
1239
0
     error,
1240
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1241
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1242
0
     "%s: invalid table section - missing section data.",
1243
0
     function );
1244
1245
0
    return( -1 );
1246
0
  }
1247
0
  if( table_section->section_data_size > (size_t) SSIZE_MAX )
1248
0
  {
1249
0
    libcerror_error_set(
1250
0
     error,
1251
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1252
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1253
0
     "%s: invalid table section - section data size value exceeds maximum.",
1254
0
     function );
1255
1256
0
    return( -1 );
1257
0
  }
1258
0
  if( table_section->base_offset > (uint64_t) INT64_MAX )
1259
0
  {
1260
0
    libcerror_error_set(
1261
0
     error,
1262
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1263
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1264
0
     "%s: invalid table section - base offset value exceeds maximum.",
1265
0
     function );
1266
1267
0
    return( -1 );
1268
0
  }
1269
0
  if( table_section->number_of_entries == 0 )
1270
0
  {
1271
0
    libcerror_error_set(
1272
0
     error,
1273
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1274
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1275
0
     "%s: invalid table section - number of entries values out of bounds.",
1276
0
     function );
1277
1278
0
    return( -1 );
1279
0
  }
1280
0
  if( format_version == 1 )
1281
0
  {
1282
0
    section_descriptor_data_size = sizeof( ewf_section_descriptor_v1_t );
1283
0
    table_header_data_size       = sizeof( ewf_table_header_v1_t );
1284
0
    table_entry_data_size        = sizeof( ewf_table_entry_v1_t );
1285
0
    table_footer_data_size       = 4;
1286
0
  }
1287
0
  else if( format_version == 2 )
1288
0
  {
1289
0
    section_descriptor_data_size = sizeof( ewf_section_descriptor_v2_t );
1290
0
    table_header_data_size       = sizeof( ewf_table_header_v2_t );
1291
0
    table_entry_data_size        = sizeof( ewf_table_entry_v2_t );
1292
0
    table_footer_data_size       = 16;
1293
0
    section_padding_size         = 24;
1294
0
  }
1295
0
  else
1296
0
  {
1297
0
    libcerror_error_set(
1298
0
     error,
1299
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1300
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1301
0
     "%s: unsupported format version.",
1302
0
     function );
1303
1304
0
    return( -1 );
1305
0
  }
1306
0
  if( type_string == NULL )
1307
0
  {
1308
0
    libcerror_error_set(
1309
0
     error,
1310
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1311
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1312
0
     "%s: invalid type string.",
1313
0
     function );
1314
1315
0
    return( -1 );
1316
0
  }
1317
0
  if( table_entries_data == NULL )
1318
0
  {
1319
0
    libcerror_error_set(
1320
0
     error,
1321
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1322
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1323
0
     "%s: invalid table entries data.",
1324
0
     function );
1325
1326
0
    return( -1 );
1327
0
  }
1328
/* TODO improve bounds check */
1329
0
  if( ( table_entries_data_size == 0 )
1330
0
   || ( table_entries_data_size > (size_t) SSIZE_MAX ) )
1331
0
  {
1332
0
    libcerror_error_set(
1333
0
     error,
1334
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1335
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1336
0
     "%s: invalid table entries data size value out of bounds.",
1337
0
     function );
1338
1339
0
    return( -1 );
1340
0
  }
1341
0
  used_table_entries_data_size = table_section->number_of_entries * table_entry_data_size;
1342
1343
0
  if( used_table_entries_data_size > table_entries_data_size )
1344
0
  {
1345
0
    libcerror_error_set(
1346
0
     error,
1347
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1348
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1349
0
     "%s: invalid table entries data size value out of bounds.",
1350
0
     function );
1351
1352
0
    goto on_error;
1353
0
  }
1354
0
  required_section_data_size = table_header_data_size
1355
0
                             + used_table_entries_data_size;
1356
1357
0
  if( segment_file_type != LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
1358
0
  {
1359
0
    required_section_data_size += table_footer_data_size;
1360
0
  }
1361
0
  if( required_section_data_size > table_section->section_data_size )
1362
0
  {
1363
0
    libcerror_error_set(
1364
0
     error,
1365
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1366
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1367
0
     "%s: invalid section data value too small.",
1368
0
     function );
1369
1370
0
    goto on_error;
1371
0
  }
1372
0
  if( libewf_section_descriptor_initialize(
1373
0
       &section_descriptor,
1374
0
       error ) != 1 )
1375
0
  {
1376
0
    libcerror_error_set(
1377
0
     error,
1378
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1379
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1380
0
     "%s: unable to create section descriptor.",
1381
0
     function );
1382
1383
0
    goto on_error;
1384
0
  }
1385
0
  if( libewf_section_descriptor_set(
1386
0
       section_descriptor,
1387
0
       LIBEWF_SECTION_TYPE_SECTOR_TABLE,
1388
0
       type_string,
1389
0
       type_string_length,
1390
0
       section_offset,
1391
0
       section_descriptor_data_size + required_section_data_size + chunks_data_size,
1392
0
       required_section_data_size + chunks_data_size,
1393
0
       section_padding_size,
1394
0
       error ) != 1 )
1395
0
  {
1396
0
    libcerror_error_set(
1397
0
     error,
1398
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1399
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1400
0
     "%s: unable to set section descriptor.",
1401
0
     function );
1402
1403
0
    goto on_error;
1404
0
  }
1405
0
  if( format_version == 1 )
1406
0
  {
1407
0
    write_count = libewf_section_descriptor_write_file_io_pool(
1408
0
             section_descriptor,
1409
0
             file_io_pool,
1410
0
             file_io_pool_entry,
1411
0
             format_version,
1412
0
             error );
1413
1414
0
    if( write_count != (ssize_t) section_descriptor_data_size )
1415
0
    {
1416
0
      libcerror_error_set(
1417
0
       error,
1418
0
       LIBCERROR_ERROR_DOMAIN_IO,
1419
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
1420
0
       "%s: unable to write section descriptor data.",
1421
0
       function );
1422
1423
0
      goto on_error;
1424
0
    }
1425
0
    total_write_count += write_count;
1426
0
  }
1427
0
  if( libewf_table_section_write_header_data(
1428
0
       table_section,
1429
0
       table_section->section_data,
1430
0
       table_section->section_data_size,
1431
0
       format_version,
1432
0
       error ) != 1 )
1433
0
  {
1434
0
    libcerror_error_set(
1435
0
     error,
1436
0
     LIBCERROR_ERROR_DOMAIN_IO,
1437
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
1438
0
     "%s: unable to write section header data.",
1439
0
     function );
1440
1441
0
    goto on_error;
1442
0
  }
1443
0
  data_offset = table_header_data_size;
1444
1445
0
  if( &( table_section->section_data[ data_offset ] ) != table_entries_data )
1446
0
  {
1447
0
    libcerror_error_set(
1448
0
     error,
1449
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1450
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1451
0
     "%s: invalid table entries data value out of bounds.",
1452
0
     function );
1453
1454
0
    goto on_error;
1455
0
  }
1456
#if defined( HAVE_DEBUG_OUTPUT )
1457
  if( libcnotify_verbose != 0 )
1458
  {
1459
    libcnotify_printf(
1460
     "%s: table entries data:\n",
1461
     function );
1462
    libcnotify_print_data(
1463
     &( table_section->section_data[ data_offset ] ),
1464
     used_table_entries_data_size,
1465
     0 );
1466
  }
1467
#endif
1468
0
  if( segment_file_type != LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
1469
0
  {
1470
0
    if( libewf_checksum_calculate_adler32(
1471
0
         &calculated_checksum,
1472
0
         &( table_section->section_data[ data_offset ] ),
1473
0
         used_table_entries_data_size,
1474
0
         1,
1475
0
         error ) != 1 )
1476
0
    {
1477
0
      libcerror_error_set(
1478
0
       error,
1479
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1480
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1481
0
       "%s: unable to calculate checksum.",
1482
0
       function );
1483
1484
0
      goto on_error;
1485
0
    }
1486
0
    data_offset += used_table_entries_data_size;
1487
1488
0
    if( libewf_table_section_write_footer_data(
1489
0
         table_section,
1490
0
         &( table_section->section_data[ data_offset ] ),
1491
0
         table_section->section_data_size - data_offset,
1492
0
         format_version,
1493
0
         calculated_checksum,
1494
0
         error ) != 1 )
1495
0
    {
1496
0
      libcerror_error_set(
1497
0
       error,
1498
0
       LIBCERROR_ERROR_DOMAIN_IO,
1499
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
1500
0
       "%s: unable to write section footer data.",
1501
0
       function );
1502
1503
0
      goto on_error;
1504
0
    }
1505
0
  }
1506
0
  write_count = libewf_section_write_data(
1507
0
                 section_descriptor,
1508
0
                 io_handle,
1509
0
                 file_io_pool,
1510
0
                 file_io_pool_entry,
1511
0
                 table_section->section_data,
1512
0
                 required_section_data_size,
1513
0
                 error );
1514
1515
0
  if( write_count == -1 )
1516
0
  {
1517
0
    libcerror_error_set(
1518
0
     error,
1519
0
     LIBCERROR_ERROR_DOMAIN_IO,
1520
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
1521
0
     "%s: unable to write section data.",
1522
0
     function );
1523
1524
0
    goto on_error;
1525
0
  }
1526
0
  total_write_count += write_count;
1527
1528
0
  if( format_version == 2 )
1529
0
  {
1530
0
    write_count = libewf_section_descriptor_write_file_io_pool(
1531
0
             section_descriptor,
1532
0
             file_io_pool,
1533
0
             file_io_pool_entry,
1534
0
             format_version,
1535
0
             error );
1536
1537
0
    if( write_count != (ssize_t) section_descriptor_data_size )
1538
0
    {
1539
0
      libcerror_error_set(
1540
0
       error,
1541
0
       LIBCERROR_ERROR_DOMAIN_IO,
1542
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
1543
0
       "%s: unable to write section descriptor data.",
1544
0
       function );
1545
1546
0
      goto on_error;
1547
0
    }
1548
0
    total_write_count += write_count;
1549
0
  }
1550
0
  if( libewf_section_descriptor_free(
1551
0
       &section_descriptor,
1552
0
       error ) != 1 )
1553
0
  {
1554
0
    libcerror_error_set(
1555
0
     error,
1556
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1557
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1558
0
     "%s: unable to free section.",
1559
0
     function );
1560
1561
0
    goto on_error;
1562
0
  }
1563
0
  return( total_write_count );
1564
1565
0
on_error:
1566
0
  if( section_descriptor != NULL )
1567
0
  {
1568
0
    libewf_section_descriptor_free(
1569
0
     &section_descriptor,
1570
     NULL );
1571
0
  }
1572
0
  return( -1 );
1573
0
}
1574