Coverage Report

Created: 2026-07-25 07:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libewf/libewf/libewf_volume_section.c
Line
Count
Source
1
/*
2
 * Volume section functions
3
 *
4
 * Copyright (C) 2006-2026, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <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
759
{
51
759
  static char *function        = "libewf_volume_section_e01_read_data";
52
759
  uint32_t calculated_checksum = 0;
53
759
  uint32_t stored_checksum     = 0;
54
55
#if defined( HAVE_DEBUG_OUTPUT )
56
  uint32_t value_32bit         = 0;
57
#endif
58
59
759
  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
759
  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
759
  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
759
  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
759
  media_values->media_type = ( (ewf_volume_t *) data )->media_type;
116
117
759
  byte_stream_copy_to_uint32_little_endian(
118
759
   ( (ewf_volume_t *) data )->number_of_chunks,
119
759
   media_values->number_of_chunks );
120
121
759
  byte_stream_copy_to_uint32_little_endian(
122
759
   ( (ewf_volume_t *) data )->sectors_per_chunk,
123
759
   media_values->sectors_per_chunk );
124
125
759
  byte_stream_copy_to_uint32_little_endian(
126
759
   ( (ewf_volume_t *) data )->bytes_per_sector,
127
759
   media_values->bytes_per_sector );
128
129
759
  byte_stream_copy_to_uint64_little_endian(
130
759
   ( (ewf_volume_t *) data )->number_of_sectors,
131
759
   media_values->number_of_sectors );
132
133
759
  media_values->media_flags = ( (ewf_volume_t *) data )->media_flags;
134
135
759
  io_handle->compression_level = (int8_t) ( (ewf_volume_t *) data )->compression_level;
136
137
759
  byte_stream_copy_to_uint32_little_endian(
138
759
   ( (ewf_volume_t *) data )->error_granularity,
139
759
   media_values->error_granularity );
140
141
759
  if( memory_copy(
142
759
       media_values->set_identifier,
143
759
       ( (ewf_volume_t *) data )->set_identifier,
144
759
       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
759
  byte_stream_copy_to_uint32_little_endian(
156
759
   ( (ewf_volume_t *) data )->checksum,
157
759
   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
759
  if( libewf_checksum_calculate_adler32(
317
759
       &calculated_checksum,
318
759
       data,
319
759
       data_size - 4,
320
759
       1,
321
759
       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
759
  if( stored_checksum != calculated_checksum )
333
42
  {
334
42
    libcerror_error_set(
335
42
     error,
336
42
     LIBCERROR_ERROR_DOMAIN_INPUT,
337
42
     LIBCERROR_INPUT_ERROR_CHECKSUM_MISMATCH,
338
42
     "%s: checksum does not match (stored: 0x%08" PRIx32 ", calculated: 0x%08" PRIx32 ").",
339
42
     function,
340
42
     stored_checksum,
341
42
     calculated_checksum );
342
343
42
    return( -1 );
344
42
  }
345
717
  return( 1 );
346
759
}
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
760
{
359
760
  uint8_t *section_data    = NULL;
360
760
  static char *function    = "libewf_volume_section_e01_read_file_io_pool";
361
760
  size_t section_data_size = 0;
362
760
  ssize_t read_count       = 0;
363
364
760
  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
760
  read_count = libewf_section_read_data(
376
760
                section_descriptor,
377
760
                io_handle,
378
760
                file_io_pool,
379
760
                file_io_pool_entry,
380
760
                &section_data,
381
760
                &section_data_size,
382
760
                error );
383
384
760
  if( read_count == -1 )
385
1
  {
386
1
    libcerror_error_set(
387
1
     error,
388
1
     LIBCERROR_ERROR_DOMAIN_IO,
389
1
     LIBCERROR_IO_ERROR_READ_FAILED,
390
1
     "%s: unable to read section data.",
391
1
     function );
392
393
1
    goto on_error;
394
1
  }
395
759
  else if( read_count != 0 )
396
759
  {
397
759
    if( libewf_volume_section_e01_read_data(
398
759
         section_data,
399
759
         section_data_size,
400
759
         io_handle,
401
759
         media_values,
402
759
         error ) != 1 )
403
42
    {
404
42
      libcerror_error_set(
405
42
       error,
406
42
       LIBCERROR_ERROR_DOMAIN_IO,
407
42
       LIBCERROR_IO_ERROR_READ_FAILED,
408
42
       "%s: unable to read EWF-E01 volume section.",
409
42
       function );
410
411
42
      goto on_error;
412
42
    }
413
717
    memory_free(
414
717
     section_data );
415
717
  }
416
717
  return( read_count );
417
418
43
on_error:
419
43
  if( section_data != NULL )
420
42
  {
421
42
    memory_free(
422
42
     section_data );
423
42
  }
424
43
  return( -1 );
425
760
}
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
  size_t section_data_size  = 0;
653
0
  ssize_t total_write_count = 0;
654
0
  ssize_t write_count       = 0;
655
656
0
  if( section_descriptor == NULL )
657
0
  {
658
0
    libcerror_error_set(
659
0
     error,
660
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
661
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
662
0
     "%s: invalid section descriptor.",
663
0
     function );
664
665
0
    return( -1 );
666
0
  }
667
0
  if( io_handle == NULL )
668
0
  {
669
0
    libcerror_error_set(
670
0
     error,
671
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
672
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
673
0
     "%s: invalid IO handle.",
674
0
     function );
675
676
0
    return( -1 );
677
0
  }
678
0
  if( media_values == NULL )
679
0
  {
680
0
    libcerror_error_set(
681
0
     error,
682
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
683
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
684
0
     "%s: invalid media values.",
685
0
     function );
686
687
0
    return( -1 );
688
0
  }
689
0
  if( media_values->number_of_chunks > (uint64_t) UINT32_MAX )
690
0
  {
691
0
    libcerror_error_set(
692
0
     error,
693
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
694
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
695
0
     "%s: invalid media values - number of chunks value out of bounds.",
696
0
     function );
697
698
0
    return( -1 );
699
0
  }
700
0
  if( libewf_section_descriptor_set(
701
0
       section_descriptor,
702
0
       0,
703
0
       (uint8_t *) "volume",
704
0
       6,
705
0
       section_offset,
706
0
       (size64_t) ( sizeof( ewf_section_descriptor_v1_t ) + sizeof( ewf_volume_t ) ),
707
0
       (size64_t) sizeof( ewf_volume_t ),
708
0
       0,
709
0
       error ) != 1 )
710
0
  {
711
0
    libcerror_error_set(
712
0
     error,
713
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
714
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
715
0
     "%s: unable to set section descriptor.",
716
0
     function );
717
718
0
    goto on_error;
719
0
  }
720
0
  write_count = libewf_section_descriptor_write_file_io_pool(
721
0
                 section_descriptor,
722
0
                 file_io_pool,
723
0
                 file_io_pool_entry,
724
0
                 1,
725
0
                 error );
726
727
0
  if( write_count != (ssize_t) sizeof( ewf_section_descriptor_v1_t ) )
728
0
  {
729
0
    libcerror_error_set(
730
0
     error,
731
0
     LIBCERROR_ERROR_DOMAIN_IO,
732
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
733
0
     "%s: unable to write section descriptor.",
734
0
     function );
735
736
0
    goto on_error;
737
0
  }
738
0
  total_write_count += write_count;
739
740
0
  section_data_size = sizeof( ewf_volume_t );
741
742
0
  section_data = (uint8_t *) memory_allocate(
743
0
                              section_data_size );
744
745
0
  if( section_data == NULL )
746
0
  {
747
0
    libcerror_error_set(
748
0
     error,
749
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
750
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
751
0
     "%s: unable to create section data.",
752
0
     function );
753
754
0
    goto on_error;
755
0
  }
756
0
  if( libewf_volume_section_e01_write_data(
757
0
       section_data,
758
0
       section_data_size,
759
0
       io_handle,
760
0
       media_values,
761
0
       error ) != 1 )
762
0
  {
763
0
    libcerror_error_set(
764
0
     error,
765
0
     LIBCERROR_ERROR_DOMAIN_IO,
766
0
     LIBCERROR_IO_ERROR_READ_FAILED,
767
0
     "%s: unable to write section data.",
768
0
     function );
769
770
0
    goto on_error;
771
0
  }
772
0
  write_count = libewf_section_write_data(
773
0
                 section_descriptor,
774
0
                 io_handle,
775
0
                 file_io_pool,
776
0
                 file_io_pool_entry,
777
0
                 section_data,
778
0
                 section_data_size,
779
0
                 error );
780
781
0
  if( write_count == -1 )
782
0
  {
783
0
    libcerror_error_set(
784
0
     error,
785
0
     LIBCERROR_ERROR_DOMAIN_IO,
786
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
787
0
     "%s: unable to write section data.",
788
0
     function );
789
790
0
    goto on_error;
791
0
  }
792
0
  total_write_count += write_count;
793
794
0
  memory_free(
795
0
   section_data );
796
797
0
  return( total_write_count );
798
799
0
on_error:
800
0
  if( section_data != NULL )
801
0
  {
802
0
    memory_free(
803
0
     section_data );
804
0
  }
805
0
  return( -1 );
806
0
}
807
808
/* Reads an EWF-S01 (SMART) volume section
809
 * Returns 1 if successful or -1 on error
810
 */
811
int libewf_volume_section_s01_read_data(
812
     const uint8_t *data,
813
     size_t data_size,
814
     libewf_io_handle_t *io_handle,
815
     libewf_media_values_t *media_values,
816
     libcerror_error_t **error )
817
0
{
818
0
  static char *function        = "libewf_volume_section_s01_read_data";
819
0
  uint32_t calculated_checksum = 0;
820
0
  uint32_t stored_checksum     = 0;
821
822
0
  if( data == NULL )
823
0
  {
824
0
    libcerror_error_set(
825
0
     error,
826
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
827
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
828
0
     "%s: missing data.",
829
0
     function );
830
831
0
    return( -1 );
832
0
  }
833
0
  if( data_size != (size_t) sizeof( ewf_volume_smart_t ) )
834
0
  {
835
0
    libcerror_error_set(
836
0
     error,
837
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
838
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
839
0
     "%s: invalid data size value out of bounds.",
840
0
     function );
841
842
0
    return( -1 );
843
0
  }
844
0
  if( io_handle == NULL )
845
0
  {
846
0
    libcerror_error_set(
847
0
     error,
848
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
849
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
850
0
     "%s: invalid IO handle.",
851
0
     function );
852
853
0
    return( -1 );
854
0
  }
855
0
  if( media_values == NULL )
856
0
  {
857
0
    libcerror_error_set(
858
0
     error,
859
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
860
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
861
0
     "%s: invalid media values.",
862
0
     function );
863
864
0
    return( -1 );
865
0
  }
866
#if defined( HAVE_DEBUG_OUTPUT )
867
  if( libcnotify_verbose != 0 )
868
  {
869
    libcnotify_printf(
870
     "%s: volume data:\n",
871
     function );
872
    libcnotify_print_data(
873
     data,
874
     data_size,
875
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
876
  }
877
#endif
878
0
  byte_stream_copy_to_uint32_little_endian(
879
0
   ( (ewf_volume_smart_t *) data )->number_of_chunks,
880
0
   media_values->number_of_chunks );
881
882
0
  byte_stream_copy_to_uint32_little_endian(
883
0
   ( (ewf_volume_smart_t *) data )->sectors_per_chunk,
884
0
   media_values->sectors_per_chunk );
885
886
0
  byte_stream_copy_to_uint32_little_endian(
887
0
   ( (ewf_volume_smart_t *) data )->bytes_per_sector,
888
0
   media_values->bytes_per_sector );
889
890
0
  byte_stream_copy_to_uint32_little_endian(
891
0
   ( (ewf_volume_smart_t *) data )->number_of_sectors,
892
0
   media_values->number_of_sectors );
893
894
0
  byte_stream_copy_to_uint32_little_endian(
895
0
   ( (ewf_volume_smart_t *) data )->checksum,
896
0
   stored_checksum );
897
898
#if defined( HAVE_DEBUG_OUTPUT )
899
  if( libcnotify_verbose != 0 )
900
  {
901
    libcnotify_printf(
902
     "%s: unknown1:\n",
903
     function );
904
    libcnotify_print_data(
905
     ( (ewf_volume_smart_t *) data )->unknown1,
906
     4,
907
     0 );
908
909
    libcnotify_printf(
910
     "%s: number of chunks\t\t: %" PRIu64 "\n",
911
     function,
912
     media_values->number_of_chunks );
913
914
    libcnotify_printf(
915
     "%s: sectors per chunk\t\t: %" PRIu32 "\n",
916
     function,
917
     media_values->sectors_per_chunk );
918
919
    libcnotify_printf(
920
     "%s: bytes per sector\t\t: %" PRIu32 "\n",
921
     function,
922
     media_values->bytes_per_sector );
923
924
    libcnotify_printf(
925
     "%s: number of sectors\t\t: %" PRIu64 "\n",
926
     function,
927
     media_values->number_of_sectors );
928
929
    libcnotify_printf(
930
     "%s: unknown2:\n",
931
     function );
932
    libcnotify_print_data(
933
     ( (ewf_volume_smart_t *) data )->unknown2,
934
     20,
935
     0 );
936
937
    libcnotify_printf(
938
     "%s: unknown3:\n",
939
     function );
940
    libcnotify_print_data(
941
     ( (ewf_volume_smart_t *) data )->unknown3,
942
     45,
943
     0 );
944
945
    libcnotify_printf(
946
     "%s: signature:\n",
947
     function );
948
    libcnotify_print_data(
949
     ( (ewf_volume_smart_t *) data )->signature,
950
     5,
951
     0 );
952
953
    libcnotify_printf(
954
     "%s: checksum\t\t\t\t: 0x%08" PRIx32 "\n",
955
     function,
956
     stored_checksum );
957
958
    libcnotify_printf(
959
     "\n" );
960
  }
961
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
962
963
0
  if( memory_compare(
964
0
       (void *) ( (ewf_volume_smart_t *) data )->signature,
965
0
       (void *) "SMART",
966
0
       5 ) == 0 )
967
0
  {
968
0
    io_handle->format = LIBEWF_FORMAT_SMART;
969
0
  }
970
0
  else
971
0
  {
972
0
    io_handle->format = LIBEWF_FORMAT_EWF;
973
0
  }
974
0
  if( libewf_checksum_calculate_adler32(
975
0
       &calculated_checksum,
976
0
       data,
977
0
       data_size - 4,
978
0
       1,
979
0
       error ) != 1 )
980
0
  {
981
0
    libcerror_error_set(
982
0
     error,
983
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
984
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
985
0
     "%s: unable to calculate checksum.",
986
0
     function );
987
988
0
    return( -1 );
989
0
  }
990
0
  if( stored_checksum != calculated_checksum )
991
0
  {
992
0
    libcerror_error_set(
993
0
     error,
994
0
     LIBCERROR_ERROR_DOMAIN_INPUT,
995
0
     LIBCERROR_INPUT_ERROR_CHECKSUM_MISMATCH,
996
0
     "%s: checksum does not match (stored: 0x%08" PRIx32 ", calculated: 0x%08" PRIx32 ").",
997
0
     function,
998
0
     stored_checksum,
999
0
     calculated_checksum );
1000
1001
0
    return( -1 );
1002
0
  }
1003
0
  return( 1 );
1004
0
}
1005
1006
/* Reads an EWF-S01 (SMART) volume section
1007
 * Returns the number of bytes read or -1 on error
1008
 */
1009
ssize_t libewf_volume_section_s01_read_file_io_pool(
1010
         libewf_section_descriptor_t *section_descriptor,
1011
         libewf_io_handle_t *io_handle,
1012
         libbfio_pool_t *file_io_pool,
1013
         int file_io_pool_entry,
1014
         libewf_media_values_t *media_values,
1015
         libcerror_error_t **error )
1016
0
{
1017
0
  uint8_t *section_data    = NULL;
1018
0
  static char *function    = "libewf_volume_section_s01_read_file_io_pool";
1019
0
  size_t section_data_size = 0;
1020
0
  ssize_t read_count       = 0;
1021
1022
0
  if( section_descriptor == NULL )
1023
0
  {
1024
0
    libcerror_error_set(
1025
0
     error,
1026
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1027
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1028
0
     "%s: invalid section descriptor.",
1029
0
     function );
1030
1031
0
    return( -1 );
1032
0
  }
1033
0
  read_count = libewf_section_read_data(
1034
0
                section_descriptor,
1035
0
                io_handle,
1036
0
                file_io_pool,
1037
0
                file_io_pool_entry,
1038
0
                &section_data,
1039
0
                &section_data_size,
1040
0
                error );
1041
1042
0
  if( read_count == -1 )
1043
0
  {
1044
0
    libcerror_error_set(
1045
0
     error,
1046
0
     LIBCERROR_ERROR_DOMAIN_IO,
1047
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1048
0
     "%s: unable to read section data.",
1049
0
     function );
1050
1051
0
    goto on_error;
1052
0
  }
1053
0
  else if( read_count == 0 )
1054
0
  {
1055
0
    return( 0 );
1056
0
  }
1057
0
  if( libewf_volume_section_s01_read_data(
1058
0
       section_data,
1059
0
       section_data_size,
1060
0
       io_handle,
1061
0
       media_values,
1062
0
       error ) != 1 )
1063
0
  {
1064
0
    libcerror_error_set(
1065
0
     error,
1066
0
     LIBCERROR_ERROR_DOMAIN_IO,
1067
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1068
0
     "%s: unable to read EWF-S01 volume section.",
1069
0
     function );
1070
1071
0
    goto on_error;
1072
0
  }
1073
0
  memory_free(
1074
0
   section_data );
1075
1076
0
  return( read_count );
1077
1078
0
on_error:
1079
0
  if( section_data != NULL )
1080
0
  {
1081
0
    memory_free(
1082
0
     section_data );
1083
0
  }
1084
0
  return( -1 );
1085
0
}
1086
1087
/* Writes an EWF-S01 (SMART) volume section
1088
 * Returns 1 if successful or -1 on error
1089
 */
1090
int libewf_volume_section_s01_write_data(
1091
     uint8_t *data,
1092
     size_t data_size,
1093
     libewf_io_handle_t *io_handle,
1094
     libewf_media_values_t *media_values,
1095
     libcerror_error_t **error )
1096
0
{
1097
0
  static char *function        = "libewf_volume_section_s01_write_data";
1098
0
  uint32_t calculated_checksum = 0;
1099
1100
0
  if( data == NULL )
1101
0
  {
1102
0
    libcerror_error_set(
1103
0
     error,
1104
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1105
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1106
0
     "%s: missing data.",
1107
0
     function );
1108
1109
0
    return( -1 );
1110
0
  }
1111
0
  if( data_size != (size_t) sizeof( ewf_volume_smart_t ) )
1112
0
  {
1113
0
    libcerror_error_set(
1114
0
     error,
1115
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1116
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1117
0
     "%s: invalid data size value out of bounds.",
1118
0
     function );
1119
1120
0
    return( -1 );
1121
0
  }
1122
0
  if( io_handle == NULL )
1123
0
  {
1124
0
    libcerror_error_set(
1125
0
     error,
1126
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1127
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1128
0
     "%s: invalid IO handle.",
1129
0
     function );
1130
1131
0
    return( -1 );
1132
0
  }
1133
0
  if( media_values == NULL )
1134
0
  {
1135
0
    libcerror_error_set(
1136
0
     error,
1137
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1138
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1139
0
     "%s: invalid media values.",
1140
0
     function );
1141
1142
0
    return( -1 );
1143
0
  }
1144
0
  if( memory_set(
1145
0
       data,
1146
0
       0,
1147
0
       data_size ) == NULL )
1148
0
  {
1149
0
    libcerror_error_set(
1150
0
     error,
1151
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1152
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
1153
0
     "%s: unable to clear data.",
1154
0
     function );
1155
1156
0
    return( -1 );
1157
0
  }
1158
#if defined( HAVE_DEBUG_OUTPUT )
1159
  if( libcnotify_verbose != 0 )
1160
  {
1161
    libcnotify_printf(
1162
     "%s: media type\t\t\t\t: 0x%02" PRIx8 "\n",
1163
     function,
1164
     media_values->media_type );
1165
1166
    libcnotify_printf(
1167
     "%s: number of chunks\t\t\t: %" PRIu64 "\n",
1168
     function,
1169
     media_values->number_of_chunks );
1170
1171
    libcnotify_printf(
1172
     "%s: sectors per chunk\t\t\t: %" PRIu32 "\n",
1173
     function,
1174
     media_values->sectors_per_chunk );
1175
1176
    libcnotify_printf(
1177
     "%s: bytes per sector\t\t\t: %" PRIu32 "\n",
1178
     function,
1179
     media_values->bytes_per_sector );
1180
1181
    libcnotify_printf(
1182
     "%s: number of sectors\t\t\t: %" PRIu64 "\n",
1183
     function,
1184
     media_values->number_of_sectors );
1185
1186
    libcnotify_printf(
1187
     "\n" );
1188
  }
1189
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1190
1191
0
  ( (ewf_volume_smart_t *) data )->unknown1[ 0 ] = 1;
1192
1193
0
  byte_stream_copy_from_uint32_little_endian(
1194
0
   ( (ewf_volume_smart_t *) data )->number_of_chunks,
1195
0
   (uint32_t) media_values->number_of_chunks );
1196
1197
0
  byte_stream_copy_from_uint32_little_endian(
1198
0
   ( (ewf_volume_smart_t *) data )->sectors_per_chunk,
1199
0
   media_values->sectors_per_chunk );
1200
1201
0
  byte_stream_copy_from_uint32_little_endian(
1202
0
   ( (ewf_volume_smart_t *) data )->bytes_per_sector,
1203
0
   media_values->bytes_per_sector );
1204
1205
0
  byte_stream_copy_from_uint32_little_endian(
1206
0
   ( (ewf_volume_smart_t *) data )->number_of_sectors,
1207
0
   media_values->number_of_sectors );
1208
1209
0
  if( io_handle->format == LIBEWF_FORMAT_SMART )
1210
0
  {
1211
0
    ( (ewf_volume_smart_t *) data )->signature[ 0 ] = (uint8_t) 'S';
1212
0
    ( (ewf_volume_smart_t *) data )->signature[ 1 ] = (uint8_t) 'M';
1213
0
    ( (ewf_volume_smart_t *) data )->signature[ 2 ] = (uint8_t) 'A';
1214
0
    ( (ewf_volume_smart_t *) data )->signature[ 3 ] = (uint8_t) 'R';
1215
0
    ( (ewf_volume_smart_t *) data )->signature[ 4 ] = (uint8_t) 'T';
1216
0
  }
1217
0
  if( libewf_checksum_calculate_adler32(
1218
0
       &calculated_checksum,
1219
0
       data,
1220
0
       data_size - 4,
1221
0
       1,
1222
0
       error ) != 1 )
1223
0
  {
1224
0
    libcerror_error_set(
1225
0
     error,
1226
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1227
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1228
0
     "%s: unable to calculate checksum.",
1229
0
     function );
1230
1231
0
    return( -1 );
1232
0
  }
1233
0
  byte_stream_copy_from_uint32_little_endian(
1234
0
   ( (ewf_volume_smart_t *) data )->checksum,
1235
0
   calculated_checksum );
1236
1237
#if defined( HAVE_DEBUG_OUTPUT )
1238
  if( libcnotify_verbose != 0 )
1239
  {
1240
    libcnotify_printf(
1241
     "%s: volume has %" PRIu64 " chunks of %" PRIi32 " bytes (%" PRIi32 " sectors) each.\n",
1242
     function,
1243
     media_values->number_of_chunks,
1244
     media_values->chunk_size,
1245
     media_values->sectors_per_chunk );
1246
1247
    libcnotify_printf(
1248
     "%s: volume has %" PRIu64 " sectors of %" PRIi32 " bytes each.\n",
1249
     function,
1250
     media_values->number_of_sectors,
1251
     media_values->bytes_per_sector );
1252
  }
1253
#endif
1254
0
  return( 1 );
1255
0
}
1256
1257
/* Writes an EWF-S01 (SMART) volume section
1258
 * Returns the number of bytes written or -1 on error
1259
 */
1260
ssize_t libewf_volume_section_s01_write_file_io_pool(
1261
         libewf_section_descriptor_t *section_descriptor,
1262
         libewf_io_handle_t *io_handle,
1263
         libbfio_pool_t *file_io_pool,
1264
         int file_io_pool_entry,
1265
         off64_t section_offset,
1266
         libewf_media_values_t *media_values,
1267
         libcerror_error_t **error )
1268
0
{
1269
0
  uint8_t *section_data     = NULL;
1270
0
  static char *function     = "libewf_volume_section_s01_write_file_io_pool";
1271
0
  size_t section_data_size  = 0;
1272
0
  ssize_t total_write_count = 0;
1273
0
  ssize_t write_count       = 0;
1274
1275
0
  if( section_descriptor == NULL )
1276
0
  {
1277
0
    libcerror_error_set(
1278
0
     error,
1279
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1280
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1281
0
     "%s: invalid section descriptor.",
1282
0
     function );
1283
1284
0
    return( -1 );
1285
0
  }
1286
0
  if( io_handle == NULL )
1287
0
  {
1288
0
    libcerror_error_set(
1289
0
     error,
1290
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1291
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1292
0
     "%s: invalid IO handle.",
1293
0
     function );
1294
1295
0
    return( -1 );
1296
0
  }
1297
0
  if( media_values == NULL )
1298
0
  {
1299
0
    libcerror_error_set(
1300
0
     error,
1301
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1302
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1303
0
     "%s: invalid media values.",
1304
0
     function );
1305
1306
0
    return( -1 );
1307
0
  }
1308
0
  if( media_values->number_of_chunks > (uint64_t) UINT32_MAX )
1309
0
  {
1310
0
    libcerror_error_set(
1311
0
     error,
1312
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1313
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1314
0
     "%s: invalid media values - number of chunks value out of bounds.",
1315
0
     function );
1316
1317
0
    return( -1 );
1318
0
  }
1319
0
  if( libewf_section_descriptor_set(
1320
0
       section_descriptor,
1321
0
       0,
1322
0
       (uint8_t *) "volume",
1323
0
       6,
1324
0
       section_offset,
1325
0
       (size64_t) ( sizeof( ewf_section_descriptor_v1_t ) + sizeof( ewf_volume_smart_t ) ),
1326
0
       (size64_t) sizeof( ewf_volume_smart_t ),
1327
0
       0,
1328
0
       error ) != 1 )
1329
0
  {
1330
0
    libcerror_error_set(
1331
0
     error,
1332
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1333
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1334
0
     "%s: unable to set section descriptor.",
1335
0
     function );
1336
1337
0
    goto on_error;
1338
0
  }
1339
0
  write_count = libewf_section_descriptor_write_file_io_pool(
1340
0
                 section_descriptor,
1341
0
                 file_io_pool,
1342
0
                 file_io_pool_entry,
1343
0
                 1,
1344
0
                 error );
1345
1346
0
  if( write_count != (ssize_t) sizeof( ewf_section_descriptor_v1_t ) )
1347
0
  {
1348
0
    libcerror_error_set(
1349
0
     error,
1350
0
     LIBCERROR_ERROR_DOMAIN_IO,
1351
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
1352
0
     "%s: unable to write section descriptor.",
1353
0
     function );
1354
1355
0
    goto on_error;
1356
0
  }
1357
0
  total_write_count += write_count;
1358
1359
0
  section_data_size = sizeof( ewf_volume_smart_t );
1360
1361
0
  section_data = (uint8_t *) memory_allocate(
1362
0
                              section_data_size );
1363
1364
0
  if( section_data == NULL )
1365
0
  {
1366
0
    libcerror_error_set(
1367
0
     error,
1368
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1369
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1370
0
     "%s: unable to create section data.",
1371
0
     function );
1372
1373
0
    goto on_error;
1374
0
  }
1375
0
  if( libewf_volume_section_s01_write_data(
1376
0
       section_data,
1377
0
       section_data_size,
1378
0
       io_handle,
1379
0
       media_values,
1380
0
       error ) != 1 )
1381
0
  {
1382
0
    libcerror_error_set(
1383
0
     error,
1384
0
     LIBCERROR_ERROR_DOMAIN_IO,
1385
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1386
0
     "%s: unable to write section data.",
1387
0
     function );
1388
1389
0
    goto on_error;
1390
0
  }
1391
0
  write_count = libewf_section_write_data(
1392
0
                 section_descriptor,
1393
0
                 io_handle,
1394
0
                 file_io_pool,
1395
0
                 file_io_pool_entry,
1396
0
                 section_data,
1397
0
                 section_data_size,
1398
0
                 error );
1399
1400
0
  if( write_count == -1 )
1401
0
  {
1402
0
    libcerror_error_set(
1403
0
     error,
1404
0
     LIBCERROR_ERROR_DOMAIN_IO,
1405
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
1406
0
     "%s: unable to write section data.",
1407
0
     function );
1408
1409
0
    goto on_error;
1410
0
  }
1411
0
  total_write_count += write_count;
1412
1413
0
  memory_free(
1414
0
   section_data );
1415
1416
0
  return( total_write_count );
1417
1418
0
on_error:
1419
0
  if( section_data != NULL )
1420
0
  {
1421
0
    memory_free(
1422
0
     section_data );
1423
0
  }
1424
0
  return( -1 );
1425
0
}
1426