Coverage Report

Created: 2025-06-22 07:35

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