Coverage Report

Created: 2025-08-28 07:10

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