Coverage Report

Created: 2025-10-14 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libewf/libewf/libewf_section.c
Line
Count
Source
1
/*
2
 * Section reading/writing 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_compression.h"
30
#include "libewf_debug.h"
31
#include "libewf_definitions.h"
32
#include "libewf_hash_sections.h"
33
#include "libewf_header_values.h"
34
#include "libewf_header_sections.h"
35
#include "libewf_io_handle.h"
36
#include "libewf_libbfio.h"
37
#include "libewf_libcerror.h"
38
#include "libewf_libcdata.h"
39
#include "libewf_libcnotify.h"
40
#include "libewf_libhmac.h"
41
#include "libewf_media_values.h"
42
#include "libewf_section.h"
43
#include "libewf_section_descriptor.h"
44
#include "libewf_sector_range.h"
45
#include "libewf_single_files.h"
46
#include "libewf_unused.h"
47
48
#include "ewf_data.h"
49
#include "ewf_section.h"
50
51
/* Tests if a buffer entirely consists of zero values
52
 * Returns 1 if zero, 0 if not, or -1 on error
53
 */
54
int libewf_section_test_zero(
55
     const uint8_t *buffer,
56
     size_t buffer_size,
57
     libcerror_error_t **error )
58
3
{
59
3
  static char *function = "libewf_section_test_zero";
60
3
  size_t buffer_offset  = 0;
61
62
3
  if( buffer == NULL )
63
0
  {
64
0
    libcerror_error_set(
65
0
     error,
66
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
67
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
68
0
     "%s: invalid buffer.",
69
0
     function );
70
71
0
    return( -1 );
72
0
  }
73
3
  if( buffer_size > (size_t) SSIZE_MAX )
74
0
  {
75
0
    libcerror_error_set(
76
0
     error,
77
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
78
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
79
0
     "%s: invalid buffer size value exceeds maximum.",
80
0
     function );
81
82
0
    return( -1 );
83
0
  }
84
3
  for( buffer_offset = 0;
85
3
       buffer_offset < buffer_size;
86
3
       buffer_offset++ )
87
3
  {
88
3
    if( buffer[ buffer_offset ] != 0 )
89
3
    {
90
3
      return( 0 );
91
3
    }
92
3
  }
93
0
  return( 1 );
94
3
}
95
96
/* Reads the data of a section
97
 * The data is decrypted if necessary
98
 * Returns the number of bytes read or -1 on error
99
 */
100
ssize_t libewf_section_read_data(
101
         libewf_section_descriptor_t *section_descriptor,
102
         libewf_io_handle_t *io_handle,
103
         libbfio_pool_t *file_io_pool,
104
         int file_io_pool_entry,
105
         uint8_t **section_data,
106
         size_t *section_data_size,
107
         libcerror_error_t **error )
108
5.33k
{
109
5.33k
  uint8_t calculated_md5_hash[ 16 ];
110
111
5.33k
  uint8_t *safe_section_data = NULL;
112
5.33k
  static char *function      = "libewf_section_read_data";
113
5.33k
  ssize_t read_count         = 0;
114
115
5.33k
  if( section_descriptor == NULL )
116
0
  {
117
0
    libcerror_error_set(
118
0
     error,
119
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
120
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
121
0
     "%s: invalid section descriptor.",
122
0
     function );
123
124
0
    return( -1 );
125
0
  }
126
5.33k
  if( ( section_descriptor->data_size == 0 )
127
5.33k
   || ( section_descriptor->data_size > (size64_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
128
60
  {
129
60
    libcerror_error_set(
130
60
     error,
131
60
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
132
60
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
133
60
     "%s: invalid section descriptor - data size value out of bounds.",
134
60
     function );
135
136
60
    return( -1 );
137
60
  }
138
5.27k
  if( io_handle == NULL )
139
0
  {
140
0
    libcerror_error_set(
141
0
     error,
142
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
143
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
144
0
     "%s: invalid IO handle.",
145
0
     function );
146
147
0
    return( -1 );
148
0
  }
149
5.27k
  if( section_data == NULL )
150
0
  {
151
0
    libcerror_error_set(
152
0
     error,
153
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
154
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
155
0
     "%s: invalid section data.",
156
0
     function );
157
158
0
    return( -1 );
159
0
  }
160
5.27k
  if( *section_data != NULL )
161
0
  {
162
0
    libcerror_error_set(
163
0
     error,
164
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
165
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
166
0
     "%s: invalid section data value already set.",
167
0
     function );
168
169
0
    return( -1 );
170
0
  }
171
5.27k
  if( section_data_size == NULL )
172
0
  {
173
0
    libcerror_error_set(
174
0
     error,
175
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
176
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
177
0
     "%s: invalid section data size.",
178
0
     function );
179
180
0
    return( -1 );
181
0
  }
182
5.27k
  safe_section_data = (uint8_t *) memory_allocate(
183
5.27k
                                   sizeof( uint8_t ) * section_descriptor->data_size );
184
185
5.27k
  if( safe_section_data == NULL )
186
0
  {
187
0
    libcerror_error_set(
188
0
     error,
189
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
190
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
191
0
     "%s: unable to create section data.",
192
0
     function );
193
194
0
    goto on_error;
195
0
  }
196
5.27k
  read_count = libbfio_pool_read_buffer(
197
5.27k
                file_io_pool,
198
5.27k
                file_io_pool_entry,
199
5.27k
                safe_section_data,
200
5.27k
                (size_t) section_descriptor->data_size,
201
5.27k
                error );
202
203
5.27k
  if( read_count != (ssize_t) section_descriptor->data_size )
204
62
  {
205
62
    libcerror_error_set(
206
62
     error,
207
62
     LIBCERROR_ERROR_DOMAIN_IO,
208
62
     LIBCERROR_IO_ERROR_READ_FAILED,
209
62
     "%s: unable to read section data.",
210
62
     function );
211
212
62
    goto on_error;
213
62
  }
214
5.21k
  if( ( section_descriptor->data_flags & LIBEWF_SECTION_DATA_FLAGS_HAS_INTEGRITY_HASH ) != 0 )
215
0
  {
216
0
    if( libhmac_md5_calculate(
217
0
         safe_section_data,
218
0
         (size_t) section_descriptor->data_size,
219
0
         calculated_md5_hash,
220
0
         16,
221
0
         error ) != 1 )
222
0
    {
223
0
      libcerror_error_set(
224
0
       error,
225
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
226
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
227
0
       "%s: unable to calculate integrity hash.",
228
0
       function );
229
230
0
      goto on_error;
231
0
    }
232
#if defined( HAVE_DEBUG_OUTPUT )
233
    if( libcnotify_verbose != 0 )
234
    {
235
      libcnotify_printf(
236
       "%s: calculated MD5 hash:\n",
237
       function );
238
      libcnotify_print_data(
239
       calculated_md5_hash,
240
       16,
241
       0 );
242
    }
243
#endif
244
0
    if( memory_compare(
245
0
         section_descriptor->data_integrity_hash,
246
0
         calculated_md5_hash,
247
0
         16 ) != 0 )
248
0
    {
249
0
      libcerror_error_set(
250
0
       error,
251
0
       LIBCERROR_ERROR_DOMAIN_INPUT,
252
0
       LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
253
0
       "%s: mismatch in integrity hash.",
254
0
       function );
255
256
0
      goto on_error;
257
0
    }
258
0
  }
259
5.21k
  if( ( section_descriptor->data_flags & LIBEWF_SECTION_DATA_FLAGS_IS_ENCRYPTED ) != 0 )
260
0
  {
261
#if defined( HAVE_DEBUG_OUTPUT )
262
    if( libcnotify_verbose != 0 )
263
    {
264
      libcnotify_printf(
265
       "%s: encrypted data:\n",
266
       function );
267
      libcnotify_print_data(
268
       safe_section_data,
269
       (size_t) section_descriptor->data_size,
270
       0 );
271
    }
272
#endif
273
/* TODO decrypt */
274
0
    memory_free(
275
0
     safe_section_data );
276
277
0
    libcerror_error_set(
278
0
     error,
279
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
280
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
281
0
     "%s: invalid section descriptor - encrypted section currently not supported.",
282
0
     function );
283
284
0
    return( -1 );
285
0
  }
286
5.21k
  *section_data      = safe_section_data;
287
5.21k
  *section_data_size = (size_t) section_descriptor->data_size;
288
289
5.21k
  return( read_count );
290
291
62
on_error:
292
62
  if( safe_section_data != NULL )
293
62
  {
294
62
    memory_free(
295
62
     safe_section_data );
296
62
  }
297
62
  return( -1 );
298
5.21k
}
299
300
/* Writes the data of a section
301
 * The data is decrypted if necessary
302
 * Returns the number of bytes written or -1 on error
303
 */
304
ssize_t libewf_section_write_data(
305
         libewf_section_descriptor_t *section_descriptor,
306
         libewf_io_handle_t *io_handle,
307
         libbfio_pool_t *file_io_pool,
308
         int file_io_pool_entry,
309
         const uint8_t *section_data,
310
         size_t section_data_size,
311
         libcerror_error_t **error )
312
0
{
313
0
  static char *function = "libewf_section_write_data";
314
0
  ssize_t write_count   = 0;
315
316
0
  if( section_descriptor == NULL )
317
0
  {
318
0
    libcerror_error_set(
319
0
     error,
320
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
321
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
322
0
     "%s: invalid section descriptor.",
323
0
     function );
324
325
0
    return( -1 );
326
0
  }
327
/* TODO remove? */
328
0
  if( io_handle == NULL )
329
0
  {
330
0
    libcerror_error_set(
331
0
     error,
332
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
333
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
334
0
     "%s: invalid IO handle.",
335
0
     function );
336
337
0
    return( -1 );
338
0
  }
339
0
  if( section_data_size > (size_t) SSIZE_MAX )
340
0
  {
341
0
    libcerror_error_set(
342
0
     error,
343
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
344
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
345
0
     "%s: invalid section data size value exceeds maximum.",
346
0
     function );
347
348
0
    return( -1 );
349
0
  }
350
/* TODO MD5 hash */
351
0
  if( ( section_descriptor->data_flags & LIBEWF_SECTION_DATA_FLAGS_IS_ENCRYPTED ) != 0 )
352
0
  {
353
/* TODO encrypt */
354
#if defined( HAVE_DEBUG_OUTPUT )
355
    if( libcnotify_verbose != 0 )
356
    {
357
      libcnotify_printf(
358
       "%s: encrypted data:\n",
359
       function );
360
      libcnotify_print_data(
361
       section_data,
362
       section_data_size,
363
       0 );
364
    }
365
#endif
366
0
    return( 0 );
367
0
  }
368
0
  if( ( section_descriptor->data_flags & LIBEWF_SECTION_DATA_FLAGS_HAS_INTEGRITY_HASH ) != 0 )
369
0
  {
370
0
    if( libhmac_md5_calculate(
371
0
         section_data,
372
0
         section_data_size,
373
0
         section_descriptor->data_integrity_hash,
374
0
         16,
375
0
         error ) != 1 )
376
0
    {
377
0
      libcerror_error_set(
378
0
       error,
379
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
380
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
381
0
       "%s: unable to calculate integrity hash.",
382
0
       function );
383
384
0
      goto on_error;
385
0
    }
386
#if defined( HAVE_DEBUG_OUTPUT )
387
    if( libcnotify_verbose != 0 )
388
    {
389
      libcnotify_printf(
390
       "%s: calculated MD5 hash:\n",
391
       function );
392
      libcnotify_print_data(
393
       section_descriptor->data_integrity_hash,
394
       16,
395
       0 );
396
    }
397
#endif
398
0
  }
399
0
  write_count = libbfio_pool_write_buffer(
400
0
                 file_io_pool,
401
0
                 file_io_pool_entry,
402
0
                 section_data,
403
0
                 section_data_size,
404
0
                 error );
405
406
0
  if( write_count != (ssize_t) section_data_size )
407
0
  {
408
0
    libcerror_error_set(
409
0
     error,
410
0
     LIBCERROR_ERROR_DOMAIN_IO,
411
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
412
0
     "%s: unable to write section data.",
413
0
     function );
414
415
0
    goto on_error;
416
0
  }
417
0
  return( write_count );
418
419
0
on_error:
420
/* TODO free encrypted data */
421
0
  return( -1 );
422
0
}
423
424
/* Reads a compressed string section and decompresses it
425
 * Returns the number of bytes read or -1 on error
426
 */
427
ssize_t libewf_section_compressed_string_read(
428
         libewf_section_descriptor_t *section_descriptor,
429
         libewf_io_handle_t *io_handle,
430
         libbfio_pool_t *file_io_pool,
431
         int file_io_pool_entry,
432
         uint16_t compression_method,
433
         uint8_t **uncompressed_string,
434
         size_t *uncompressed_string_size,
435
         libcerror_error_t **error )
436
3.72k
{
437
3.72k
  uint8_t *section_data      = NULL;
438
3.72k
  static char *function      = "libewf_section_compressed_string_read";
439
3.72k
  void *reallocation         = NULL;
440
3.72k
  size_t section_data_size   = 0;
441
3.72k
  ssize_t read_count         = 0;
442
3.72k
  uint8_t number_of_attempts = 0;
443
3.72k
  int result                 = 0;
444
445
3.72k
  if( section_descriptor == NULL )
446
0
  {
447
0
    libcerror_error_set(
448
0
     error,
449
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
450
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
451
0
     "%s: invalid section descriptor.",
452
0
     function );
453
454
0
    return( -1 );
455
0
  }
456
3.72k
  if( uncompressed_string == NULL )
457
0
  {
458
0
    libcerror_error_set(
459
0
     error,
460
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
461
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
462
0
     "%s: invalid uncompressed string.",
463
0
     function );
464
465
0
    return( -1 );
466
0
  }
467
3.72k
  if( *uncompressed_string != NULL )
468
0
  {
469
0
    libcerror_error_set(
470
0
     error,
471
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
472
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
473
0
     "%s: invalid uncompressed string value already set.",
474
0
     function );
475
476
0
    return( -1 );
477
0
  }
478
3.72k
  if( uncompressed_string_size == NULL )
479
0
  {
480
0
    libcerror_error_set(
481
0
     error,
482
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
483
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
484
0
     "%s: invalid uncompressed string size.",
485
0
     function );
486
487
0
    return( -1 );
488
0
  }
489
3.72k
  read_count = libewf_section_read_data(
490
3.72k
                section_descriptor,
491
3.72k
                io_handle,
492
3.72k
                file_io_pool,
493
3.72k
                file_io_pool_entry,
494
3.72k
                &section_data,
495
3.72k
                &section_data_size,
496
3.72k
                error );
497
498
3.72k
  if( read_count == -1 )
499
110
  {
500
110
    libcerror_error_set(
501
110
     error,
502
110
     LIBCERROR_ERROR_DOMAIN_IO,
503
110
     LIBCERROR_IO_ERROR_READ_FAILED,
504
110
     "%s: unable to read section data.",
505
110
     function );
506
507
110
    goto on_error;
508
110
  }
509
3.61k
  else if( read_count == 0 )
510
0
  {
511
0
    return( 0 );
512
0
  }
513
3.61k
  if( section_data == NULL )
514
0
  {
515
0
    libcerror_error_set(
516
0
     error,
517
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
518
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
519
0
     "%s: missing section data.",
520
0
     function );
521
522
0
    goto on_error;
523
0
  }
524
3.61k
  if( ( section_data_size == 0 )
525
3.61k
   || ( section_data_size > MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
526
0
  {
527
0
    libcerror_error_set(
528
0
     error,
529
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
530
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
531
0
     "%s: invalid section data size value out of bounds.",
532
0
     function );
533
534
0
    goto on_error;
535
0
  }
536
#if defined( HAVE_DEBUG_OUTPUT )
537
  if( libcnotify_verbose != 0 )
538
  {
539
    libcnotify_printf(
540
     "%s: compressed string:\n",
541
     function );
542
    libcnotify_print_data(
543
     section_data,
544
     section_data_size,
545
     0 );
546
  }
547
#endif
548
  /* On average the uncompressed string will be more than twice as large as the compressed string
549
   */
550
3.61k
  *uncompressed_string_size = 4 * section_data_size;
551
552
3.61k
  *uncompressed_string = (uint8_t *) memory_allocate(
553
3.61k
                                      sizeof( uint8_t ) * *uncompressed_string_size );
554
555
3.61k
  if( *uncompressed_string == NULL )
556
0
  {
557
0
    libcerror_error_set(
558
0
     error,
559
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
560
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
561
0
     "%s: unable to create uncompressed string.",
562
0
     function );
563
564
0
    goto on_error;
565
0
  }
566
3.61k
  result = libewf_decompress_data(
567
3.61k
            section_data,
568
3.61k
            section_data_size,
569
3.61k
            compression_method,
570
3.61k
            *uncompressed_string,
571
3.61k
            uncompressed_string_size,
572
3.61k
            error );
573
574
3.61k
  while( ( result == 0 )
575
0
      && ( *uncompressed_string_size > 0 ) )
576
0
  {
577
0
    number_of_attempts++;
578
579
0
    reallocation = memory_reallocate(
580
0
                    *uncompressed_string,
581
0
                    sizeof( uint8_t ) * *uncompressed_string_size );
582
583
0
    if( reallocation == NULL )
584
0
    {
585
0
      libcerror_error_set(
586
0
       error,
587
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
588
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
589
0
       "%s: unable to resize uncompressed string.",
590
0
       function );
591
592
0
      goto on_error;
593
0
    }
594
0
    *uncompressed_string = (uint8_t *) reallocation;
595
596
0
    result = libewf_decompress_data(
597
0
              section_data,
598
0
              section_data_size,
599
0
              compression_method,
600
0
              *uncompressed_string,
601
0
              uncompressed_string_size,
602
0
              error );
603
604
0
    if( number_of_attempts >= 3 )
605
0
    {
606
0
      break;
607
0
    }
608
0
  }
609
3.61k
  if( result != 1 )
610
461
  {
611
461
    libcerror_error_set(
612
461
     error,
613
461
     LIBCERROR_ERROR_DOMAIN_COMPRESSION,
614
461
     LIBCERROR_COMPRESSION_ERROR_DECOMPRESS_FAILED,
615
461
     "%s: unable to decompress string.",
616
461
     function );
617
618
461
    goto on_error;
619
461
  }
620
#if defined( HAVE_DEBUG_OUTPUT )
621
  if( libcnotify_verbose != 0 )
622
  {
623
    libcnotify_printf(
624
     "%s: uncompressed string:\n",
625
     function );
626
    libcnotify_print_data(
627
     *uncompressed_string,
628
     *uncompressed_string_size,
629
     0 );
630
  }
631
#endif
632
3.14k
  memory_free(
633
3.14k
   section_data );
634
635
3.14k
  return( read_count );
636
637
571
on_error:
638
571
  if( *uncompressed_string != NULL )
639
461
  {
640
461
    memory_free(
641
461
     *uncompressed_string );
642
643
461
    *uncompressed_string = NULL;
644
461
  }
645
571
  if( section_data != NULL )
646
461
  {
647
461
    memory_free(
648
461
     section_data );
649
461
  }
650
571
  return( -1 );
651
3.61k
}
652
653
/* Writes a compressed string section
654
 * Returns the number of bytes written or -1 on error
655
 */
656
ssize_t libewf_section_write_compressed_string(
657
         libewf_section_descriptor_t *section_descriptor,
658
         libewf_io_handle_t *io_handle,
659
         libbfio_pool_t *file_io_pool,
660
         int file_io_pool_entry,
661
         uint8_t format_version,
662
         uint32_t type,
663
         const uint8_t *type_string,
664
         size_t type_string_length,
665
         off64_t section_offset,
666
         uint16_t compression_method,
667
         int8_t compression_level,
668
         uint8_t *uncompressed_string,
669
         size_t uncompressed_string_size,
670
         size_t fill_size,
671
         libcerror_error_t **error )
672
0
{
673
0
  uint8_t *compressed_string          = NULL;
674
0
  static char *function               = "libewf_section_write_compressed_string";
675
0
  void *reallocation                  = NULL;
676
0
  size_t compressed_string_offset     = 0;
677
0
  size_t compressed_string_size       = 0;
678
0
  size_t padding_size                 = 0;
679
0
  size_t section_descriptor_data_size = 0;
680
0
  ssize_t total_write_count           = 0;
681
0
  ssize_t write_count                 = 0;
682
0
  int result                          = 0;
683
684
0
  if( section_descriptor == NULL )
685
0
  {
686
0
    libcerror_error_set(
687
0
     error,
688
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
689
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
690
0
     "%s: invalid section descriptor.",
691
0
     function );
692
693
0
    return( -1 );
694
0
  }
695
0
  if( format_version == 1 )
696
0
  {
697
0
    section_descriptor_data_size = sizeof( ewf_section_descriptor_v1_t );
698
0
  }
699
0
  else if( format_version == 2 )
700
0
  {
701
0
    section_descriptor_data_size = sizeof( ewf_section_descriptor_v2_t );
702
0
  }
703
0
  else
704
0
  {
705
0
    libcerror_error_set(
706
0
     error,
707
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
708
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
709
0
     "%s: unsupported format version.",
710
0
     function );
711
712
0
    return( -1 );
713
0
  }
714
0
  if( uncompressed_string == NULL )
715
0
  {
716
0
    libcerror_error_set(
717
0
     error,
718
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
719
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
720
0
     "%s: invalid uncompressed string.",
721
0
     function );
722
723
0
    return( -1 );
724
0
  }
725
#if defined( HAVE_DEBUG_OUTPUT )
726
  if( libcnotify_verbose != 0 )
727
  {
728
    libcnotify_printf(
729
     "%s: uncompressed string:\n",
730
     function );
731
    libcnotify_print_data(
732
     uncompressed_string,
733
     uncompressed_string_size,
734
     0 );
735
  }
736
#endif
737
0
  if( fill_size > uncompressed_string_size )
738
0
  {
739
0
    compressed_string_size = fill_size;
740
0
  }
741
0
  else
742
0
  {
743
0
    compressed_string_size = uncompressed_string_size;
744
0
  }
745
0
  if( format_version == 2 )
746
0
  {
747
0
    padding_size = compressed_string_size % 16;
748
749
0
    if( padding_size != 0 )
750
0
    {
751
0
      padding_size            = 16 - padding_size;
752
0
      compressed_string_size += padding_size;
753
0
    }
754
0
  }
755
0
  if( ( compressed_string_size == 0 )
756
0
   || ( compressed_string_size > MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
757
0
  {
758
0
    libcerror_error_set(
759
0
     error,
760
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
761
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
762
0
     "%s: invalid compressed string size value out of bounds.",
763
0
     function );
764
765
0
    goto on_error;
766
0
  }
767
0
  compressed_string = (uint8_t *) memory_allocate(
768
0
                                   sizeof( uint8_t ) * compressed_string_size );
769
770
0
  if( compressed_string == NULL )
771
0
  {
772
0
    libcerror_error_set(
773
0
     error,
774
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
775
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
776
0
     "%s: unable to create compressed string.",
777
0
     function );
778
779
0
    goto on_error;
780
0
  }
781
0
  if( memory_set(
782
0
       compressed_string,
783
0
       0,
784
0
       compressed_string_size ) == NULL )
785
0
  {
786
0
    libcerror_error_set(
787
0
     error,
788
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
789
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
790
0
     "%s: unable to clear compressed string.",
791
0
     function );
792
793
0
    goto on_error;
794
0
  }
795
0
  result = libewf_compress_data(
796
0
            compressed_string,
797
0
            &compressed_string_size,
798
0
            compression_method,
799
0
            compression_level,
800
0
            uncompressed_string,
801
0
            uncompressed_string_size,
802
0
            error );
803
804
0
  if( result == 0 )
805
0
  {
806
0
    if( compressed_string_size <= uncompressed_string_size )
807
0
    {
808
0
      libcerror_error_set(
809
0
       error,
810
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
811
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
812
0
       "%s: invalid compressed string size value out of bounds.",
813
0
       function );
814
815
0
      goto on_error;
816
0
    }
817
0
    if( format_version == 2 )
818
0
    {
819
0
      padding_size = compressed_string_size % 16;
820
821
0
      if( padding_size != 0 )
822
0
      {
823
0
        padding_size            = 16 - padding_size;
824
0
        compressed_string_size += padding_size;
825
0
      }
826
0
    }
827
0
    reallocation = memory_reallocate(
828
0
                    compressed_string,
829
0
                    sizeof( uint8_t ) * compressed_string_size );
830
831
0
    if( reallocation == NULL )
832
0
    {
833
0
      libcerror_error_set(
834
0
       error,
835
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
836
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
837
0
       "%s: unable to resize compressed string.",
838
0
       function );
839
840
0
      goto on_error;
841
0
    }
842
0
    compressed_string = (uint8_t *) reallocation;
843
844
0
    if( memory_set(
845
0
         compressed_string,
846
0
         0,
847
0
         compressed_string_size ) == NULL )
848
0
    {
849
0
      libcerror_error_set(
850
0
       error,
851
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
852
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
853
0
       "%s: unable to clear compressed string.",
854
0
       function );
855
856
0
      goto on_error;
857
0
    }
858
0
    result = libewf_compress_data(
859
0
              compressed_string,
860
0
              &compressed_string_size,
861
0
              compression_method,
862
0
              compression_level,
863
0
              uncompressed_string,
864
0
              uncompressed_string_size,
865
0
              error );
866
0
  }
867
0
  if( result != 1 )
868
0
  {
869
0
    libcerror_error_set(
870
0
     error,
871
0
     LIBCERROR_ERROR_DOMAIN_COMPRESSION,
872
0
     LIBCERROR_COMPRESSION_ERROR_COMPRESS_FAILED,
873
0
     "%s: unable to compress string.",
874
0
     function );
875
876
0
    goto on_error;
877
0
  }
878
/* TODO bzip2 support
879
  if( compression_method == LIBEWF_COMPRESSION_METHOD_BZIP2 )
880
  {
881
    compressed_string_offset = 4;
882
    compressed_string_size  -= 4;
883
  }
884
*/
885
0
  if( fill_size != 0 )
886
0
  {
887
0
    if( compressed_string_size > fill_size )
888
0
    {
889
0
      libcerror_error_set(
890
0
       error,
891
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
892
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
893
0
       "%s: invalid compressed string size value exceeds fill size.",
894
0
       function );
895
896
0
      goto on_error;
897
0
    }
898
0
    padding_size           = fill_size - compressed_string_size;
899
0
    compressed_string_size = fill_size;
900
0
  }
901
0
  else if( format_version == 1 )
902
0
  {
903
0
    padding_size = 0;
904
0
  }
905
0
  else if( format_version == 2 )
906
0
  {
907
0
    padding_size = compressed_string_size % 16;
908
909
0
    if( padding_size != 0 )
910
0
    {
911
0
      padding_size            = 16 - padding_size;
912
0
      compressed_string_size += padding_size;
913
0
    }
914
0
  }
915
0
  if( libewf_section_descriptor_set(
916
0
       section_descriptor,
917
0
       type,
918
0
       type_string,
919
0
       type_string_length,
920
0
       section_offset,
921
0
       (size64_t) ( section_descriptor_data_size + compressed_string_size ),
922
0
       (size64_t) compressed_string_size,
923
0
       (uint32_t) padding_size,
924
0
       error ) != 1 )
925
0
  {
926
0
    libcerror_error_set(
927
0
     error,
928
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
929
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
930
0
     "%s: unable to set section descriptor.",
931
0
     function );
932
933
0
    goto on_error;
934
0
  }
935
0
  if( format_version == 1 )
936
0
  {
937
0
    write_count = libewf_section_descriptor_write_file_io_pool(
938
0
             section_descriptor,
939
0
             file_io_pool,
940
0
             file_io_pool_entry,
941
0
             format_version,
942
0
             error );
943
944
0
    if( write_count != (ssize_t) section_descriptor_data_size )
945
0
    {
946
0
      libcerror_error_set(
947
0
       error,
948
0
       LIBCERROR_ERROR_DOMAIN_IO,
949
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
950
0
       "%s: unable to write section descriptor.",
951
0
       function );
952
953
0
      goto on_error;
954
0
    }
955
0
    total_write_count += write_count;
956
0
  }
957
#if defined( HAVE_DEBUG_OUTPUT )
958
  if( libcnotify_verbose != 0 )
959
  {
960
    libcnotify_printf(
961
     "%s: compressed string:\n",
962
     function );
963
    libcnotify_print_data(
964
     &( compressed_string[ compressed_string_offset ] ),
965
     compressed_string_size,
966
     0 );
967
  }
968
#endif
969
0
  write_count = libewf_section_write_data(
970
0
                 section_descriptor,
971
0
                 io_handle,
972
0
                 file_io_pool,
973
0
                 file_io_pool_entry,
974
0
                 &( compressed_string[ compressed_string_offset ] ),
975
0
                 compressed_string_size,
976
0
                 error );
977
978
0
  if( write_count == -1 )
979
0
  {
980
0
    libcerror_error_set(
981
0
     error,
982
0
     LIBCERROR_ERROR_DOMAIN_IO,
983
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
984
0
     "%s: unable to write section data.",
985
0
     function );
986
987
0
    goto on_error;
988
0
  }
989
0
  total_write_count += write_count;
990
991
0
  memory_free(
992
0
   compressed_string );
993
994
0
  compressed_string = NULL;
995
996
0
  if( format_version == 2 )
997
0
  {
998
0
    write_count = libewf_section_descriptor_write_file_io_pool(
999
0
             section_descriptor,
1000
0
             file_io_pool,
1001
0
             file_io_pool_entry,
1002
0
             format_version,
1003
0
             error );
1004
1005
0
    if( write_count != (ssize_t) section_descriptor_data_size )
1006
0
    {
1007
0
      libcerror_error_set(
1008
0
       error,
1009
0
       LIBCERROR_ERROR_DOMAIN_IO,
1010
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
1011
0
       "%s: unable to write section descriptor.",
1012
0
       function );
1013
1014
0
      goto on_error;
1015
0
    }
1016
0
    total_write_count += write_count;
1017
0
  }
1018
0
  return( total_write_count );
1019
1020
0
on_error:
1021
0
  if( compressed_string != NULL )
1022
0
  {
1023
0
    memory_free(
1024
0
     compressed_string );
1025
0
  }
1026
0
  return( -1 );
1027
0
}
1028
1029
/* Reads a data section
1030
 * Returns the number of bytes read or -1 on error
1031
 */
1032
ssize_t libewf_section_data_read(
1033
         libewf_section_descriptor_t *section_descriptor,
1034
         libewf_io_handle_t *io_handle,
1035
         libbfio_pool_t *file_io_pool,
1036
         int file_io_pool_entry,
1037
         libewf_media_values_t *media_values,
1038
         int *set_identifier_change,
1039
         libcerror_error_t **error )
1040
574
{
1041
574
  uint8_t *section_data        = NULL;
1042
574
  static char *function        = "libewf_section_data_read";
1043
574
  size_t section_data_size     = 0;
1044
574
  ssize_t read_count           = 0;
1045
574
  uint64_t number_of_sectors   = 0;
1046
574
  uint32_t bytes_per_sector    = 0;
1047
574
  uint32_t calculated_checksum = 0;
1048
574
  uint32_t error_granularity   = 0;
1049
574
  uint32_t number_of_chunks    = 0;
1050
574
  uint32_t sectors_per_chunk   = 0;
1051
574
  uint32_t stored_checksum     = 0;
1052
1053
#if defined( HAVE_DEBUG_OUTPUT )
1054
  uint32_t value_32bit         = 0;
1055
#endif
1056
1057
574
  if( section_descriptor == NULL )
1058
0
  {
1059
0
    libcerror_error_set(
1060
0
     error,
1061
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1062
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1063
0
     "%s: invalid section descriptor.",
1064
0
     function );
1065
1066
0
    return( -1 );
1067
0
  }
1068
574
  if( io_handle == NULL )
1069
0
  {
1070
0
    libcerror_error_set(
1071
0
     error,
1072
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1073
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1074
0
     "%s: invalid IO handle.",
1075
0
     function );
1076
1077
0
    return( -1 );
1078
0
  }
1079
574
  if( media_values == NULL )
1080
0
  {
1081
0
    libcerror_error_set(
1082
0
     error,
1083
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1084
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1085
0
     "%s: invalid media values.",
1086
0
     function );
1087
1088
0
    return( -1 );
1089
0
  }
1090
574
  if( set_identifier_change == NULL )
1091
0
  {
1092
0
    libcerror_error_set(
1093
0
     error,
1094
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1095
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1096
0
     "%s: invalid set identifier change.",
1097
0
     function );
1098
1099
0
    return( -1 );
1100
0
  }
1101
574
  read_count = libewf_section_read_data(
1102
574
                section_descriptor,
1103
574
                io_handle,
1104
574
                file_io_pool,
1105
574
                file_io_pool_entry,
1106
574
                &section_data,
1107
574
                &section_data_size,
1108
574
                error );
1109
1110
574
  if( read_count == -1 )
1111
2
  {
1112
2
    libcerror_error_set(
1113
2
     error,
1114
2
     LIBCERROR_ERROR_DOMAIN_IO,
1115
2
     LIBCERROR_IO_ERROR_READ_FAILED,
1116
2
     "%s: unable to read section data.",
1117
2
     function );
1118
1119
2
    goto on_error;
1120
2
  }
1121
572
  else if( read_count == 0 )
1122
0
  {
1123
0
    return( 0 );
1124
0
  }
1125
572
  if( section_data == NULL )
1126
0
  {
1127
0
    libcerror_error_set(
1128
0
     error,
1129
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1130
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1131
0
     "%s: missing section data.",
1132
0
     function );
1133
1134
0
    goto on_error;
1135
0
  }
1136
572
  if( section_data_size != (ssize_t) sizeof( ewf_data_t ) )
1137
0
  {
1138
0
    libcerror_error_set(
1139
0
     error,
1140
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1141
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1142
0
     "%s: invalid section data size value out of bounds.",
1143
0
     function );
1144
1145
0
    goto on_error;
1146
0
  }
1147
#if defined( HAVE_DEBUG_OUTPUT )
1148
  if( libcnotify_verbose != 0 )
1149
  {
1150
    libcnotify_printf(
1151
     "%s: data:\n",
1152
     function );
1153
    libcnotify_print_data(
1154
     section_data,
1155
     section_data_size,
1156
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1157
  }
1158
#endif
1159
572
  byte_stream_copy_to_uint32_little_endian(
1160
572
   ( (ewf_data_t *) section_data )->checksum,
1161
572
   stored_checksum );
1162
1163
572
  byte_stream_copy_to_uint32_little_endian(
1164
572
   ( (ewf_data_t *) section_data )->number_of_chunks,
1165
572
   number_of_chunks );
1166
1167
572
  byte_stream_copy_to_uint32_little_endian(
1168
572
   ( (ewf_data_t *) section_data )->sectors_per_chunk,
1169
572
   sectors_per_chunk );
1170
1171
572
  byte_stream_copy_to_uint32_little_endian(
1172
572
   ( (ewf_data_t *) section_data )->bytes_per_sector,
1173
572
   bytes_per_sector );
1174
1175
572
  byte_stream_copy_to_uint64_little_endian(
1176
572
   ( (ewf_data_t *) section_data )->number_of_sectors,
1177
572
   number_of_sectors );
1178
1179
572
  byte_stream_copy_to_uint32_little_endian(
1180
572
   ( (ewf_data_t *) section_data )->error_granularity,
1181
572
   error_granularity );
1182
1183
#if defined( HAVE_DEBUG_OUTPUT )
1184
  if( libcnotify_verbose != 0 )
1185
  {
1186
    libcnotify_printf(
1187
     "%s: media type\t\t\t\t\t: 0x%02" PRIx8 "\n",
1188
     function,
1189
     ( (ewf_data_t *) section_data )->media_type );
1190
1191
    libcnotify_printf(
1192
     "%s: unknown1:\n",
1193
     function );
1194
    libcnotify_print_data(
1195
     ( (ewf_data_t *) section_data )->unknown1,
1196
     3,
1197
     0 );
1198
1199
    libcnotify_printf(
1200
     "%s: number of chunks\t\t\t\t: %" PRIu32 "\n",
1201
     function,
1202
     number_of_chunks );
1203
1204
    libcnotify_printf(
1205
     "%s: sectors per chunk\t\t\t\t: %" PRIu32 "\n",
1206
     function,
1207
     sectors_per_chunk );
1208
1209
    libcnotify_printf(
1210
     "%s: bytes per sector\t\t\t\t: %" PRIu32 "\n",
1211
     function,
1212
     bytes_per_sector );
1213
1214
    libcnotify_printf(
1215
     "%s: number of sectors\t\t\t\t: %" PRIu64 "\n",
1216
     function,
1217
     number_of_sectors );
1218
1219
    byte_stream_copy_to_uint32_little_endian(
1220
     ( (ewf_data_t *) section_data )->chs_cylinders,
1221
     value_32bit );
1222
    libcnotify_printf(
1223
     "%s: CHS number of cylinders\t\t\t: %" PRIu32 "\n",
1224
     function,
1225
     value_32bit );
1226
1227
    byte_stream_copy_to_uint32_little_endian(
1228
     ( (ewf_data_t *) section_data )->chs_heads,
1229
     value_32bit );
1230
    libcnotify_printf(
1231
     "%s: CHS number of heads\t\t\t\t: %" PRIu32 "\n",
1232
     function,
1233
     value_32bit );
1234
1235
    byte_stream_copy_to_uint32_little_endian(
1236
     ( (ewf_data_t *) section_data )->chs_sectors,
1237
     value_32bit );
1238
    libcnotify_printf(
1239
     "%s: CHS number of sectors\t\t\t\t: %" PRIu32 "\n",
1240
     function,
1241
     value_32bit );
1242
1243
    libcnotify_printf(
1244
     "%s: media flags\t\t\t\t\t: 0x%02" PRIx8 "\n",
1245
     function,
1246
     ( (ewf_data_t *) section_data )->media_flags );
1247
1248
    libcnotify_printf(
1249
     "%s: unknown2:\n",
1250
     function );
1251
    libcnotify_print_data(
1252
     ( (ewf_data_t *) section_data )->unknown2,
1253
     3,
1254
     0 );
1255
1256
    byte_stream_copy_to_uint32_little_endian(
1257
     ( (ewf_data_t *) section_data )->palm_volume_start_sector,
1258
     value_32bit );
1259
    libcnotify_printf(
1260
     "%s: PALM volume start sector\t\t\t: %" PRIu32 "\n",
1261
     function,
1262
     value_32bit );
1263
1264
    libcnotify_printf(
1265
     "%s: unknown3:\n",
1266
     function );
1267
    libcnotify_print_data(
1268
     ( (ewf_data_t *) section_data )->unknown3,
1269
     4,
1270
     0 );
1271
1272
    byte_stream_copy_to_uint32_little_endian(
1273
     ( (ewf_data_t *) section_data )->smart_logs_start_sector,
1274
     value_32bit );
1275
    libcnotify_printf(
1276
     "%s: SMART logs start sector\t\t\t: %" PRIu32 "\n",
1277
     function,
1278
     value_32bit );
1279
1280
    libcnotify_printf(
1281
     "%s: compression level\t\t\t\t: 0x%02" PRIx8 "\n",
1282
     function,
1283
     ( (ewf_data_t *) section_data )->compression_level );
1284
1285
    libcnotify_printf(
1286
     "%s: unknown4:\n",
1287
     function );
1288
    libcnotify_print_data(
1289
     ( (ewf_data_t *) section_data )->unknown4,
1290
     3,
1291
     0 );
1292
1293
    libcnotify_printf(
1294
     "%s: error granularity\t\t\t\t: %" PRIu32 "\n",
1295
     function,
1296
     error_granularity );
1297
1298
    libcnotify_printf(
1299
     "%s: unknown5:\n",
1300
     function );
1301
    libcnotify_print_data(
1302
     ( (ewf_data_t *) section_data )->unknown5,
1303
     4,
1304
     0 );
1305
1306
    libcnotify_printf(
1307
     "%s: set identifier:\n",
1308
     function );
1309
    libcnotify_print_data(
1310
     ( (ewf_data_t *) section_data )->set_identifier,
1311
     16,
1312
     0 );
1313
1314
    libcnotify_printf(
1315
     "%s: unknown6:\n",
1316
     function );
1317
    libcnotify_print_data(
1318
     ( (ewf_data_t *) section_data )->unknown6,
1319
     963,
1320
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1321
1322
    libcnotify_printf(
1323
     "%s: signature:\n",
1324
     function );
1325
    libcnotify_print_data(
1326
     ( (ewf_data_t *) section_data )->signature,
1327
     5,
1328
     0 );
1329
1330
    libcnotify_printf(
1331
     "%s: checksum\t\t\t\t\t: 0x%08" PRIx32 "\n",
1332
     function,
1333
     stored_checksum );
1334
1335
    libcnotify_printf(
1336
     "\n" );
1337
  }
1338
#endif
1339
572
  if( stored_checksum != 0 )
1340
78
  {
1341
78
    if( libewf_checksum_calculate_adler32(
1342
78
         &calculated_checksum,
1343
78
         section_data,
1344
78
         section_data_size - 4,
1345
78
         1,
1346
78
         error ) != 1 )
1347
0
    {
1348
0
      libcerror_error_set(
1349
0
       error,
1350
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1351
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1352
0
       "%s: unable to calculate checksum.",
1353
0
       function );
1354
1355
0
      goto on_error;
1356
0
    }
1357
78
    if( stored_checksum != calculated_checksum )
1358
34
    {
1359
34
      libcerror_error_set(
1360
34
       error,
1361
34
       LIBCERROR_ERROR_DOMAIN_INPUT,
1362
34
       LIBCERROR_INPUT_ERROR_CHECKSUM_MISMATCH,
1363
34
       "%s: checksum does not match (stored: 0x%08" PRIx32 ", calculated: 0x%08" PRIx32 ").",
1364
34
       function,
1365
34
       stored_checksum,
1366
34
       calculated_checksum );
1367
1368
34
      goto on_error;
1369
34
    }
1370
78
  }
1371
538
  *set_identifier_change = 0;
1372
1373
538
  if( ( ( (ewf_data_t *) section_data )->set_identifier[ 0 ] != 0 )
1374
530
   || ( ( (ewf_data_t *) section_data )->set_identifier[ 1 ] != 0 )
1375
529
   || ( ( (ewf_data_t *) section_data )->set_identifier[ 2 ] != 0 )
1376
521
   || ( ( (ewf_data_t *) section_data )->set_identifier[ 3 ] != 0 )
1377
520
   || ( ( (ewf_data_t *) section_data )->set_identifier[ 4 ] != 0 )
1378
512
   || ( ( (ewf_data_t *) section_data )->set_identifier[ 5 ] != 0 )
1379
504
   || ( ( (ewf_data_t *) section_data )->set_identifier[ 6 ] != 0 )
1380
496
   || ( ( (ewf_data_t *) section_data )->set_identifier[ 7 ] != 0 )
1381
490
   || ( ( (ewf_data_t *) section_data )->set_identifier[ 8 ] != 0 )
1382
483
   || ( ( (ewf_data_t *) section_data )->set_identifier[ 9 ] != 0 )
1383
475
   || ( ( (ewf_data_t *) section_data )->set_identifier[ 10 ] != 0 )
1384
467
   || ( ( (ewf_data_t *) section_data )->set_identifier[ 11 ] != 0 )
1385
459
   || ( ( (ewf_data_t *) section_data )->set_identifier[ 12 ] != 0 )
1386
451
   || ( ( (ewf_data_t *) section_data )->set_identifier[ 13 ] != 0 )
1387
450
   || ( ( (ewf_data_t *) section_data )->set_identifier[ 14 ] != 0 )
1388
442
   || ( ( (ewf_data_t *) section_data )->set_identifier[ 15 ] != 0 ) )
1389
104
  {
1390
104
    if( memory_compare(
1391
104
         media_values->set_identifier,
1392
104
         ( (ewf_data_t *) section_data )->set_identifier,
1393
104
         16 ) != 0 )
1394
104
    {
1395
#if defined( HAVE_DEBUG_OUTPUT )
1396
      if( libcnotify_verbose != 0 )
1397
      {
1398
        libcnotify_printf(
1399
         "%s: set identifier change.",
1400
         function );
1401
      }
1402
#endif
1403
104
      *set_identifier_change = 1;
1404
104
    }
1405
104
  }
1406
538
  if( *set_identifier_change != 0 )
1407
104
  {
1408
/* TODO part of error tolerability changes
1409
    media_values->media_type        = ( (ewf_data_t *) section_data )->media_type;
1410
    media_values->number_of_chunks  = number_of_chunks;
1411
    media_values->sectors_per_chunk = sectors_per_chunk;
1412
    media_values->bytes_per_sector  = bytes_per_sector;
1413
    media_values->number_of_sectors = number_of_sectors;
1414
    media_values->media_flags       = ( (ewf_data_t *) section_data )->media_flags;
1415
    io_handle->compression_level    = ( (ewf_data_t *) section_data )->compression_level;
1416
    media_values->error_granularity = error_granularity;
1417
*/
1418
104
  }
1419
434
  else
1420
434
  {
1421
434
    if( ( ( (ewf_data_t *) section_data )->media_type != 0 )
1422
277
     && ( ( (ewf_data_t *) section_data )->media_type != media_values->media_type ) )
1423
2
    {
1424
2
      libcerror_error_set(
1425
2
       error,
1426
2
       LIBCERROR_ERROR_DOMAIN_INPUT,
1427
2
       LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
1428
2
       "%s: media type does not match.",
1429
2
       function );
1430
1431
2
      goto on_error;
1432
2
    }
1433
432
    if( ( number_of_chunks != 0 )
1434
263
     && ( (uint64_t) number_of_chunks != media_values->number_of_chunks ) )
1435
46
    {
1436
46
      libcerror_error_set(
1437
46
       error,
1438
46
       LIBCERROR_ERROR_DOMAIN_INPUT,
1439
46
       LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
1440
46
       "%s: number of chunks does not match.",
1441
46
       function );
1442
1443
46
      goto on_error;
1444
46
    }
1445
386
    if( ( sectors_per_chunk != 0 )
1446
240
     && ( sectors_per_chunk != media_values->sectors_per_chunk ) )
1447
62
    {
1448
62
      libcerror_error_set(
1449
62
       error,
1450
62
       LIBCERROR_ERROR_DOMAIN_INPUT,
1451
62
       LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
1452
62
       "%s: sectors per chunk does not match.",
1453
62
       function );
1454
1455
62
      goto on_error;
1456
62
    }
1457
324
    if( ( bytes_per_sector != 0 )
1458
199
     && ( bytes_per_sector != media_values->bytes_per_sector ) )
1459
72
    {
1460
72
      libcerror_error_set(
1461
72
       error,
1462
72
       LIBCERROR_ERROR_DOMAIN_INPUT,
1463
72
       LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
1464
72
       "%s: bytes per sector does not match.",
1465
72
       function );
1466
1467
72
      goto on_error;
1468
72
    }
1469
252
    if( ( number_of_sectors != 0 )
1470
196
     && ( number_of_sectors != media_values->number_of_sectors ) )
1471
131
    {
1472
131
      libcerror_error_set(
1473
131
       error,
1474
131
       LIBCERROR_ERROR_DOMAIN_INPUT,
1475
131
       LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
1476
131
       "%s: number of sectors does not match.",
1477
131
       function );
1478
1479
131
      goto on_error;
1480
131
    }
1481
121
    if( ( ( (ewf_data_t *) section_data )->media_flags != 0 )
1482
65
     && ( ( (ewf_data_t *) section_data )->media_flags != media_values->media_flags ) )
1483
6
    {
1484
6
      libcerror_error_set(
1485
6
       error,
1486
6
       LIBCERROR_ERROR_DOMAIN_INPUT,
1487
6
       LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
1488
6
       "%s: media flags do not match.",
1489
6
       function );
1490
1491
6
      goto on_error;
1492
6
    }
1493
115
    if( ( ( (ewf_data_t *) section_data )->compression_level != 0 )
1494
61
     && ( ( (ewf_data_t *) section_data )->compression_level != io_handle->compression_level ) )
1495
8
    {
1496
8
      libcerror_error_set(
1497
8
       error,
1498
8
       LIBCERROR_ERROR_DOMAIN_INPUT,
1499
8
       LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
1500
8
       "%s: compression level does not match.",
1501
8
       function );
1502
1503
8
      goto on_error;
1504
8
    }
1505
107
    if( ( error_granularity != 0 )
1506
106
     && ( error_granularity != media_values->error_granularity ) )
1507
62
    {
1508
62
      libcerror_error_set(
1509
62
       error,
1510
62
       LIBCERROR_ERROR_DOMAIN_INPUT,
1511
62
       LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
1512
62
       "%s: error granularity does not match.",
1513
62
       function );
1514
1515
62
      goto on_error;
1516
62
    }
1517
107
  }
1518
149
  memory_free(
1519
149
   section_data );
1520
1521
149
  return( read_count );
1522
1523
425
on_error:
1524
425
  if( section_data != NULL )
1525
423
  {
1526
423
    memory_free(
1527
423
     section_data );
1528
423
  }
1529
425
  return( -1 );
1530
538
}
1531
1532
/* Writes a data section
1533
 * Returns the number of bytes written or -1 on error
1534
 */
1535
ssize_t libewf_section_data_write(
1536
         libewf_section_descriptor_t *section_descriptor,
1537
         libewf_io_handle_t *io_handle,
1538
         libbfio_pool_t *file_io_pool,
1539
         int file_io_pool_entry,
1540
         off64_t section_offset,
1541
         libewf_media_values_t *media_values,
1542
         ewf_data_t **cached_data_section,
1543
         libcerror_error_t **error )
1544
0
{
1545
0
  static char *function        = "libewf_section_data_write";
1546
0
  ssize_t total_write_count    = 0;
1547
0
  ssize_t write_count          = 0;
1548
0
  uint32_t calculated_checksum = 0;
1549
1550
0
  if( section_descriptor == NULL )
1551
0
  {
1552
0
    libcerror_error_set(
1553
0
     error,
1554
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1555
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1556
0
     "%s: invalid section descriptor.",
1557
0
     function );
1558
1559
0
    return( -1 );
1560
0
  }
1561
0
  if( io_handle == NULL )
1562
0
  {
1563
0
    libcerror_error_set(
1564
0
     error,
1565
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1566
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1567
0
     "%s: invalid IO handle.",
1568
0
     function );
1569
1570
0
    return( -1 );
1571
0
  }
1572
0
  if( media_values == NULL )
1573
0
  {
1574
0
    libcerror_error_set(
1575
0
     error,
1576
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1577
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1578
0
     "%s: invalid media values.",
1579
0
     function );
1580
1581
0
    return( -1 );
1582
0
  }
1583
0
  if( media_values->number_of_chunks > (uint64_t) UINT32_MAX )
1584
0
  {
1585
0
    libcerror_error_set(
1586
0
     error,
1587
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1588
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1589
0
     "%s: invalid media values - number of chunks value out of bounds.",
1590
0
     function );
1591
1592
0
    return( -1 );
1593
0
  }
1594
0
  if( cached_data_section == NULL )
1595
0
  {
1596
0
    libcerror_error_set(
1597
0
     error,
1598
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1599
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1600
0
     "%s: invalid caches data section.",
1601
0
     function );
1602
1603
0
    return( -1 );
1604
0
  }
1605
0
  if( libewf_section_descriptor_set(
1606
0
       section_descriptor,
1607
0
       0,
1608
0
       (uint8_t *) "data",
1609
0
       4,
1610
0
       section_offset,
1611
0
       (size64_t) ( sizeof( ewf_section_descriptor_v1_t ) + sizeof( ewf_data_t ) ),
1612
0
       (size64_t) sizeof( ewf_data_t ),
1613
0
       0,
1614
0
       error ) != 1 )
1615
0
  {
1616
0
    libcerror_error_set(
1617
0
     error,
1618
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1619
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1620
0
     "%s: unable to set section descriptor.",
1621
0
     function );
1622
1623
0
    return( -1 );
1624
0
  }
1625
0
  write_count = libewf_section_descriptor_write_file_io_pool(
1626
0
                 section_descriptor,
1627
0
                 file_io_pool,
1628
0
                 file_io_pool_entry,
1629
0
                 1,
1630
0
                 error );
1631
1632
0
  if( write_count != (ssize_t) sizeof( ewf_section_descriptor_v1_t ) )
1633
0
  {
1634
0
    libcerror_error_set(
1635
0
     error,
1636
0
     LIBCERROR_ERROR_DOMAIN_IO,
1637
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
1638
0
     "%s: unable to write section descriptor.",
1639
0
     function );
1640
1641
0
    return( -1 );
1642
0
  }
1643
0
  total_write_count += write_count;
1644
1645
0
  if( *cached_data_section == NULL )
1646
0
  {
1647
0
    *cached_data_section = memory_allocate_structure(
1648
0
                            ewf_data_t );
1649
1650
0
    if( *cached_data_section == NULL )
1651
0
    {
1652
0
      libcerror_error_set(
1653
0
       error,
1654
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1655
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1656
0
       "%s: unable to create cached data section.",
1657
0
       function );
1658
1659
0
      return( -1 );
1660
0
    }
1661
0
    if( memory_set(
1662
0
         *cached_data_section,
1663
0
         0,
1664
0
         sizeof( ewf_data_t ) ) == NULL )
1665
0
    {
1666
0
      libcerror_error_set(
1667
0
       error,
1668
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1669
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
1670
0
       "%s: unable to clear data.",
1671
0
       function );
1672
1673
0
      memory_free(
1674
0
       *cached_data_section );
1675
1676
0
      *cached_data_section = NULL;
1677
1678
0
      return( -1 );
1679
0
    }
1680
#if defined( HAVE_DEBUG_OUTPUT )
1681
    if( libcnotify_verbose != 0 )
1682
    {
1683
      libcnotify_printf(
1684
       "%s: media type\t\t\t\t\t: 0x%02" PRIx8 "\n",
1685
       function,
1686
       media_values->media_type );
1687
1688
      libcnotify_printf(
1689
       "%s: number of chunks\t\t\t\t: %" PRIu64 "\n",
1690
       function,
1691
       media_values->number_of_chunks );
1692
1693
      libcnotify_printf(
1694
       "%s: sectors per chunk\t\t\t\t: %" PRIu32 "\n",
1695
       function,
1696
       media_values->sectors_per_chunk );
1697
1698
      libcnotify_printf(
1699
       "%s: bytes per sector\t\t\t\t: %" PRIu32 "\n",
1700
       function,
1701
       media_values->bytes_per_sector );
1702
1703
      libcnotify_printf(
1704
       "%s: number of sectors\t\t\t\t: %" PRIu64 "\n",
1705
       function,
1706
       media_values->number_of_sectors );
1707
1708
      libcnotify_printf(
1709
       "%s: media flags\t\t\t\t\t: 0x%02" PRIx8 "\n",
1710
       function,
1711
       media_values->media_flags );
1712
1713
      libcnotify_printf(
1714
       "%s: compression level\t\t\t\t: 0x%02" PRIx8 "\n",
1715
       function,
1716
       io_handle->compression_level );
1717
1718
      libcnotify_printf(
1719
       "%s: error granularity\t\t\t\t: %" PRIu32 "\n",
1720
       function,
1721
       media_values->error_granularity );
1722
1723
      libcnotify_printf(
1724
       "%s: set identifier:\n",
1725
       function );
1726
      libcnotify_print_data(
1727
       media_values->set_identifier,
1728
       16,
1729
       0 );
1730
1731
      libcnotify_printf(
1732
       "\n" );
1733
    }
1734
#endif
1735
0
    ( *cached_data_section )->media_type = media_values->media_type;
1736
0
    ( *cached_data_section )->media_flags = media_values->media_flags;
1737
1738
0
    byte_stream_copy_from_uint32_little_endian(
1739
0
     ( *cached_data_section )->number_of_chunks,
1740
0
     (uint32_t) media_values->number_of_chunks );
1741
1742
0
    byte_stream_copy_from_uint32_little_endian(
1743
0
     ( *cached_data_section )->sectors_per_chunk,
1744
0
     media_values->sectors_per_chunk );
1745
1746
0
    byte_stream_copy_from_uint32_little_endian(
1747
0
     ( *cached_data_section )->bytes_per_sector,
1748
0
     media_values->bytes_per_sector );
1749
1750
0
    byte_stream_copy_from_uint64_little_endian(
1751
0
     ( *cached_data_section )->number_of_sectors,
1752
0
     media_values->number_of_sectors );
1753
1754
0
    if( ( io_handle->format == LIBEWF_FORMAT_ENCASE5 )
1755
0
     || ( io_handle->format == LIBEWF_FORMAT_ENCASE6 )
1756
0
     || ( io_handle->format == LIBEWF_FORMAT_ENCASE7 )
1757
0
     || ( io_handle->format == LIBEWF_FORMAT_LINEN5 )
1758
0
     || ( io_handle->format == LIBEWF_FORMAT_LINEN6 )
1759
0
     || ( io_handle->format == LIBEWF_FORMAT_LINEN7 )
1760
0
     || ( io_handle->format == LIBEWF_FORMAT_EWFX ) )
1761
0
    {
1762
0
      byte_stream_copy_from_uint32_little_endian(
1763
0
       ( *cached_data_section )->error_granularity,
1764
0
       media_values->error_granularity );
1765
1766
0
      ( *cached_data_section )->compression_level = (uint8_t) io_handle->compression_level;
1767
1768
0
      if( memory_copy(
1769
0
           ( *cached_data_section )->set_identifier,
1770
0
           media_values->set_identifier,
1771
0
           16 ) == NULL )
1772
0
      {
1773
0
        libcerror_error_set(
1774
0
         error,
1775
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
1776
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1777
0
         "%s: unable to copy set identifier.",
1778
0
         function );
1779
1780
0
        memory_free(
1781
0
         *cached_data_section );
1782
1783
0
        *cached_data_section = NULL;
1784
1785
0
        return( -1 );
1786
0
      }
1787
0
    }
1788
0
    if( libewf_checksum_calculate_adler32(
1789
0
         &calculated_checksum,
1790
0
         (uint8_t *) *cached_data_section,
1791
0
         sizeof( ewf_data_t ) - 4,
1792
0
         1,
1793
0
         error ) != 1 )
1794
0
    {
1795
0
      libcerror_error_set(
1796
0
       error,
1797
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1798
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1799
0
       "%s: unable to calculate checksum.",
1800
0
       function );
1801
1802
0
      memory_free(
1803
0
       *cached_data_section );
1804
1805
0
      *cached_data_section = NULL;
1806
1807
0
      return( -1 );
1808
0
    }
1809
0
    byte_stream_copy_from_uint32_little_endian(
1810
0
     ( *cached_data_section )->checksum,
1811
0
     calculated_checksum );
1812
0
  }
1813
0
  write_count = libewf_section_write_data(
1814
0
                 section_descriptor,
1815
0
                 io_handle,
1816
0
                 file_io_pool,
1817
0
                 file_io_pool_entry,
1818
0
                 (uint8_t *) *cached_data_section,
1819
0
                 sizeof( ewf_data_t ),
1820
0
                 error );
1821
1822
0
  if( write_count == -1 )
1823
0
  {
1824
0
    libcerror_error_set(
1825
0
     error,
1826
0
     LIBCERROR_ERROR_DOMAIN_IO,
1827
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
1828
0
     "%s: unable to write section data.",
1829
0
     function );
1830
1831
0
    return( -1 );
1832
0
  }
1833
0
  total_write_count += write_count;
1834
1835
0
  return( total_write_count );
1836
0
}
1837
1838
/* Writes a sectors section
1839
 * Does not write the actual data in the sectors section
1840
 * Returns the number of bytes written or -1 on error
1841
 */
1842
ssize_t libewf_section_sectors_write(
1843
         libewf_section_descriptor_t *section_descriptor,
1844
         libbfio_pool_t *file_io_pool,
1845
         int file_io_pool_entry,
1846
         uint8_t format_version,
1847
         off64_t section_offset,
1848
         size64_t chunks_data_size,
1849
         uint32_t chunks_padding_size,
1850
         libcerror_error_t **error )
1851
0
{
1852
0
  static char *function               = "libewf_section_sectors_write";
1853
0
  size_t section_descriptor_data_size = 0;
1854
0
  ssize_t write_count                 = 0;
1855
1856
0
  if( section_descriptor == NULL )
1857
0
  {
1858
0
    libcerror_error_set(
1859
0
     error,
1860
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1861
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1862
0
     "%s: invalid section descriptor.",
1863
0
     function );
1864
1865
0
    return( -1 );
1866
0
  }
1867
0
  if( format_version == 1 )
1868
0
  {
1869
0
    section_descriptor_data_size = sizeof( ewf_section_descriptor_v1_t );
1870
0
  }
1871
0
  else if( format_version == 2 )
1872
0
  {
1873
0
    section_descriptor_data_size = sizeof( ewf_section_descriptor_v2_t );
1874
0
  }
1875
0
  else
1876
0
  {
1877
0
    libcerror_error_set(
1878
0
     error,
1879
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1880
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1881
0
     "%s: unsupported format version.",
1882
0
     function );
1883
1884
0
    return( -1 );
1885
0
  }
1886
0
  if( libewf_section_descriptor_set(
1887
0
       section_descriptor,
1888
0
       LIBEWF_SECTION_TYPE_SECTOR_DATA,
1889
0
       (uint8_t *) "sectors",
1890
0
       7,
1891
0
       section_offset,
1892
0
       section_descriptor_data_size + chunks_data_size,
1893
0
       chunks_data_size,
1894
0
       chunks_padding_size,
1895
0
       error ) != 1 )
1896
0
  {
1897
0
    libcerror_error_set(
1898
0
     error,
1899
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1900
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1901
0
     "%s: unable to set section descriptor.",
1902
0
     function );
1903
1904
0
    return( -1 );
1905
0
  }
1906
0
  write_count = libewf_section_descriptor_write_file_io_pool(
1907
0
                 section_descriptor,
1908
0
                 file_io_pool,
1909
0
                 file_io_pool_entry,
1910
0
                 format_version,
1911
0
                 error );
1912
1913
0
  if( write_count != (ssize_t) section_descriptor_data_size )
1914
0
  {
1915
0
    libcerror_error_set(
1916
0
     error,
1917
0
     LIBCERROR_ERROR_DOMAIN_IO,
1918
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
1919
0
     "%s: unable to write section descriptor data.",
1920
0
     function );
1921
1922
0
    return( -1 );
1923
0
  }
1924
0
  return( write_count );
1925
0
}
1926