Coverage Report

Created: 2024-02-25 07:20

/src/libewf/libewf/libewf_segment_file.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Segment file reading/writing functions
3
 *
4
 * Copyright (C) 2006-2023, 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 <types.h>
26
27
#if defined( HAVE_SYS_TIME_H )
28
#include <sys/time.h>
29
#endif
30
31
#include <time.h>
32
33
#include "libewf_case_data.h"
34
#include "libewf_chunk_data.h"
35
#include "libewf_debug.h"
36
#include "libewf_definitions.h"
37
#include "libewf_device_information.h"
38
#include "libewf_digest_section.h"
39
#include "libewf_error2_section.h"
40
#include "libewf_hash_values.h"
41
#include "libewf_header_values.h"
42
#include "libewf_io_handle.h"
43
#include "libewf_libbfio.h"
44
#include "libewf_libcdata.h"
45
#include "libewf_libcerror.h"
46
#include "libewf_libcnotify.h"
47
#include "libewf_libfcache.h"
48
#include "libewf_libfdata.h"
49
#include "libewf_libfguid.h"
50
#include "libewf_libfvalue.h"
51
#include "libewf_libuna.h"
52
#include "libewf_md5_hash_section.h"
53
#include "libewf_section.h"
54
#include "libewf_section_descriptor.h"
55
#include "libewf_segment_file.h"
56
#include "libewf_segment_table.h"
57
#include "libewf_session_section.h"
58
#include "libewf_sha1_hash_section.h"
59
#include "libewf_single_files.h"
60
#include "libewf_table_section.h"
61
#include "libewf_unused.h"
62
#include "libewf_volume_section.h"
63
64
#include "ewf_file_header.h"
65
#include "ewf_section.h"
66
#include "ewf_volume.h"
67
68
const uint8_t ewf1_dvf_file_signature[ 8 ] = { 0x64, 0x76, 0x66, 0x09, 0x0d, 0x0a, 0xff, 0x00 };
69
const uint8_t ewf1_evf_file_signature[ 8 ] = { 0x45, 0x56, 0x46, 0x09, 0x0d, 0x0a, 0xff, 0x00 };
70
const uint8_t ewf1_lvf_file_signature[ 8 ] = { 0x4c, 0x56, 0x46, 0x09, 0x0d, 0x0a, 0xff, 0x00 };
71
const uint8_t ewf2_evf_file_signature[ 8 ] = { 0x45, 0x56, 0x46, 0x32, 0x0d, 0x0a, 0x81, 0x00 };
72
const uint8_t ewf2_lef_file_signature[ 8 ] = { 0x4c, 0x45, 0x46, 0x32, 0x0d, 0x0a, 0x81, 0x00 };
73
74
/* Creates a segment file
75
 * Make sure the value segment_file is referencing, is set to NULL
76
 * Returns 1 if successful or -1 on error
77
 */
78
int libewf_segment_file_initialize(
79
     libewf_segment_file_t **segment_file,
80
     libewf_io_handle_t *io_handle,
81
     libcerror_error_t **error )
82
6.01k
{
83
6.01k
  static char *function = "libewf_segment_file_initialize";
84
85
6.01k
  if( segment_file == NULL )
86
0
  {
87
0
    libcerror_error_set(
88
0
     error,
89
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
90
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
91
0
     "%s: invalid segment file.",
92
0
     function );
93
94
0
    return( -1 );
95
0
  }
96
6.01k
  if( *segment_file != NULL )
97
0
  {
98
0
    libcerror_error_set(
99
0
     error,
100
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
101
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
102
0
     "%s: invalid segment file value already set.",
103
0
     function );
104
105
0
    return( -1 );
106
0
  }
107
6.01k
  if( io_handle == NULL )
108
0
  {
109
0
    libcerror_error_set(
110
0
     error,
111
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
112
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
113
0
     "%s: invalid IO handle.",
114
0
     function );
115
116
0
    return( -1 );
117
0
  }
118
6.01k
  *segment_file = memory_allocate_structure(
119
6.01k
                   libewf_segment_file_t );
120
121
6.01k
  if( *segment_file == NULL )
122
0
  {
123
0
    libcerror_error_set(
124
0
     error,
125
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
126
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
127
0
     "%s: unable to create segment file.",
128
0
     function );
129
130
0
    goto on_error;
131
0
  }
132
6.01k
  if( memory_set(
133
6.01k
       *segment_file,
134
6.01k
       0,
135
6.01k
       sizeof( libewf_segment_file_t ) ) == NULL )
136
0
  {
137
0
    libcerror_error_set(
138
0
     error,
139
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
140
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
141
0
     "%s: unable to clear segment file.",
142
0
     function );
143
144
0
    memory_free(
145
0
     *segment_file );
146
147
0
    *segment_file = NULL;
148
149
0
    return( -1 );
150
0
  }
151
6.01k
  if( libfdata_list_initialize(
152
6.01k
       &( ( *segment_file )->sections_list ),
153
6.01k
       (intptr_t *) *segment_file,
154
6.01k
       NULL,
155
6.01k
       NULL,
156
6.01k
       (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfdata_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libewf_segment_file_read_section_element_data,
157
6.01k
       NULL,
158
6.01k
       LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
159
6.01k
       error ) != 1 )
160
0
  {
161
0
    libcerror_error_set(
162
0
     error,
163
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
164
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
165
0
     "%s: unable to create sections list.",
166
0
     function );
167
168
0
    goto on_error;
169
0
  }
170
6.01k
  if( libfdata_list_initialize(
171
6.01k
       &( ( *segment_file )->chunk_groups_list ),
172
6.01k
       (intptr_t *) *segment_file,
173
6.01k
       NULL,
174
6.01k
       NULL,
175
6.01k
       (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfdata_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libewf_segment_file_read_chunk_group_element_data,
176
6.01k
       NULL,
177
6.01k
       LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
178
6.01k
       error ) != 1 )
179
0
  {
180
0
    libcerror_error_set(
181
0
     error,
182
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
183
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
184
0
     "%s: unable to create chunk groups list.",
185
0
     function );
186
187
0
    goto on_error;
188
0
  }
189
6.01k
  if( libfcache_cache_initialize(
190
6.01k
       &( ( *segment_file )->chunk_groups_cache ),
191
6.01k
       LIBEWF_MAXIMUM_CACHE_ENTRIES_CHUNK_GROUPS,
192
6.01k
       error ) != 1 )
193
0
  {
194
0
    libcerror_error_set(
195
0
     error,
196
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
197
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
198
0
     "%s: unable to create chunk groups cache.",
199
0
     function );
200
201
0
    goto on_error;
202
0
  }
203
6.01k
  ( *segment_file )->io_handle                        = io_handle;
204
6.01k
  ( *segment_file )->device_information_section_index = -1;
205
6.01k
  ( *segment_file )->previous_last_chunk_filled       = -1;
206
6.01k
  ( *segment_file )->last_chunk_filled                = -1;
207
6.01k
  ( *segment_file )->last_chunk_compared              = -1;
208
209
6.01k
  return( 1 );
210
211
0
on_error:
212
0
  if( *segment_file != NULL )
213
0
  {
214
0
    if( ( *segment_file )->chunk_groups_list != NULL )
215
0
    {
216
0
      libfdata_list_free(
217
0
       &( ( *segment_file )->chunk_groups_list ),
218
0
       NULL );
219
0
    }
220
0
    if( ( *segment_file )->sections_list != NULL )
221
0
    {
222
0
      libfdata_list_free(
223
0
       &( ( *segment_file )->sections_list ),
224
0
       NULL );
225
0
    }
226
0
    memory_free(
227
0
     *segment_file );
228
229
0
    *segment_file = NULL;
230
0
  }
231
0
  return( -1 );
232
6.01k
}
233
234
/* Frees a segment file
235
 * Returns 1 if successful or -1 on error
236
 */
237
int libewf_segment_file_free(
238
     libewf_segment_file_t **segment_file,
239
     libcerror_error_t **error )
240
6.01k
{
241
6.01k
  static char *function = "libewf_segment_file_free";
242
6.01k
  int result            = 1;
243
244
6.01k
  if( segment_file == NULL )
245
0
  {
246
0
    libcerror_error_set(
247
0
     error,
248
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
249
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
250
0
     "%s: invalid segment file.",
251
0
     function );
252
253
0
    return( -1 );
254
0
  }
255
6.01k
  if( *segment_file != NULL )
256
6.01k
  {
257
    /* The io_handle reference is freed elsewhere
258
     */
259
6.01k
    if( libfdata_list_free(
260
6.01k
         &( ( *segment_file )->sections_list ),
261
6.01k
         error ) != 1 )
262
0
    {
263
0
      libcerror_error_set(
264
0
       error,
265
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
266
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
267
0
       "%s: unable to free sections list.",
268
0
       function );
269
270
0
      result = -1;
271
0
    }
272
6.01k
    if( libfdata_list_free(
273
6.01k
         &( ( *segment_file )->chunk_groups_list ),
274
6.01k
         error ) != 1 )
275
0
    {
276
0
      libcerror_error_set(
277
0
       error,
278
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
279
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
280
0
       "%s: unable to free chunk groups list.",
281
0
       function );
282
283
0
      result = -1;
284
0
    }
285
6.01k
    if( libfcache_cache_free(
286
6.01k
         &( ( *segment_file )->chunk_groups_cache ),
287
6.01k
         error ) != 1 )
288
0
    {
289
0
      libcerror_error_set(
290
0
       error,
291
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
292
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
293
0
       "%s: unable to free chunk groups cache.",
294
0
       function );
295
296
0
      result = -1;
297
0
    }
298
6.01k
    memory_free(
299
6.01k
     *segment_file );
300
301
6.01k
    *segment_file = NULL;
302
6.01k
  }
303
6.01k
  return( result );
304
6.01k
}
305
306
/* Clones the segment file
307
 * Returns 1 if successful or -1 on error
308
 */
309
int libewf_segment_file_clone(
310
     libewf_segment_file_t **destination_segment_file,
311
     libewf_segment_file_t *source_segment_file,
312
     libcerror_error_t **error )
313
0
{
314
0
  static char *function       = "libewf_segment_file_clone";
315
0
  size64_t list_element_size  = 0;
316
0
  size64_t mapped_size        = 0;
317
0
  off64_t list_element_offset = 0;
318
0
  uint32_t list_element_flags = 0;
319
0
  int element_index           = 0;
320
0
  int list_element_file_index = 0;
321
0
  int list_element_index      = 0;
322
0
  int number_of_list_elements = 0;
323
324
0
  if( destination_segment_file == NULL )
325
0
  {
326
0
    libcerror_error_set(
327
0
     error,
328
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
329
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
330
0
     "%s: invalid destination segment file.",
331
0
     function );
332
333
0
    return( -1 );
334
0
  }
335
0
  if( *destination_segment_file != NULL )
336
0
  {
337
0
    libcerror_error_set(
338
0
     error,
339
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
340
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
341
0
     "%s: invalid destination segment file value already set.",
342
0
     function );
343
344
0
    return( -1 );
345
0
  }
346
0
  if( source_segment_file == NULL )
347
0
  {
348
0
    *destination_segment_file = NULL;
349
350
0
    return( 1 );
351
0
  }
352
0
  *destination_segment_file = memory_allocate_structure(
353
0
                               libewf_segment_file_t );
354
355
0
  if( *destination_segment_file == NULL )
356
0
  {
357
0
    libcerror_error_set(
358
0
     error,
359
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
360
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
361
0
     "%s: unable to create destination segment file.",
362
0
     function );
363
364
0
    goto on_error;
365
0
  }
366
0
  if( memory_copy(
367
0
       *destination_segment_file,
368
0
       source_segment_file,
369
0
       sizeof( libewf_segment_file_t ) ) == NULL )
370
0
  {
371
0
    libcerror_error_set(
372
0
     error,
373
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
374
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
375
0
     "%s: unable to copy source to destination segment file.",
376
0
     function );
377
378
0
    memory_free(
379
0
     *destination_segment_file );
380
381
0
    *destination_segment_file = NULL;
382
383
0
    return( -1 );
384
0
  }
385
0
  ( *destination_segment_file )->sections_list             = NULL;
386
0
  ( *destination_segment_file )->chunk_groups_list         = NULL;
387
0
  ( *destination_segment_file )->chunk_groups_cache        = NULL;
388
0
  ( *destination_segment_file )->current_chunk_group_index = 0;
389
390
0
  if( libfdata_list_initialize(
391
0
       &( ( *destination_segment_file )->sections_list ),
392
0
       (intptr_t *) *destination_segment_file,
393
0
       NULL,
394
0
       NULL,
395
0
       (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfdata_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libewf_segment_file_read_section_element_data,
396
0
       NULL,
397
0
       LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
398
0
       error ) != 1 )
399
0
  {
400
0
    libcerror_error_set(
401
0
     error,
402
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
403
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
404
0
     "%s: unable to create destination sections list.",
405
0
     function );
406
407
0
    goto on_error;
408
0
  }
409
0
  if( libfdata_list_get_number_of_elements(
410
0
       source_segment_file->sections_list,
411
0
       &number_of_list_elements,
412
0
       error ) != 1 )
413
0
  {
414
0
    libcerror_error_set(
415
0
     error,
416
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
417
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
418
0
     "%s: unable to retrieve the number of elements from source sections list.",
419
0
     function );
420
421
0
    goto on_error;
422
0
  }
423
0
  for( list_element_index = 0;
424
0
       list_element_index < number_of_list_elements;
425
0
       list_element_index++ )
426
0
  {
427
0
    if( libfdata_list_get_element_by_index(
428
0
         source_segment_file->sections_list,
429
0
         list_element_index,
430
0
         &list_element_file_index,
431
0
         &list_element_offset,
432
0
         &list_element_size,
433
0
         &list_element_flags,
434
0
         error ) != 1 )
435
0
    {
436
0
      libcerror_error_set(
437
0
       error,
438
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
439
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
440
0
       "%s: unable to retrieve element: %d from source sections list.",
441
0
       function,
442
0
       list_element_index );
443
444
0
      goto on_error;
445
0
    }
446
0
    if( libfdata_list_append_element(
447
0
         ( *destination_segment_file )->sections_list,
448
0
         &element_index,
449
0
         list_element_file_index,
450
0
         list_element_offset,
451
0
         list_element_size,
452
0
         list_element_flags,
453
0
         error ) != 1 )
454
0
    {
455
0
      libcerror_error_set(
456
0
       error,
457
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
458
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
459
0
       "%s: unable to append element: %d to destination sections list.",
460
0
       function,
461
0
       list_element_index );
462
463
0
      goto on_error;
464
0
    }
465
0
  }
466
0
  if( libfdata_list_initialize(
467
0
       &( ( *destination_segment_file )->chunk_groups_list ),
468
0
       (intptr_t *) *destination_segment_file,
469
0
       NULL,
470
0
       NULL,
471
0
       (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfdata_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libewf_segment_file_read_chunk_group_element_data,
472
0
       NULL,
473
0
       LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
474
0
       error ) != 1 )
475
0
  {
476
0
    libcerror_error_set(
477
0
     error,
478
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
479
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
480
0
     "%s: unable to create destination chunk groups list.",
481
0
     function );
482
483
0
    goto on_error;
484
0
  }
485
0
  if( libfdata_list_get_number_of_elements(
486
0
       source_segment_file->chunk_groups_list,
487
0
       &number_of_list_elements,
488
0
       error ) != 1 )
489
0
  {
490
0
    libcerror_error_set(
491
0
     error,
492
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
493
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
494
0
     "%s: unable to retrieve the number of elements from source chunk groups list.",
495
0
     function );
496
497
0
    goto on_error;
498
0
  }
499
0
  for( list_element_index = 0;
500
0
       list_element_index < number_of_list_elements;
501
0
       list_element_index++ )
502
0
  {
503
0
    if( libfdata_list_get_element_by_index(
504
0
         source_segment_file->chunk_groups_list,
505
0
         list_element_index,
506
0
         &list_element_file_index,
507
0
         &list_element_offset,
508
0
         &list_element_size,
509
0
         &list_element_flags,
510
0
         error ) != 1 )
511
0
    {
512
0
      libcerror_error_set(
513
0
       error,
514
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
515
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
516
0
       "%s: unable to retrieve element: %d from source chunk groups list.",
517
0
       function,
518
0
       list_element_index );
519
520
0
      goto on_error;
521
0
    }
522
0
    if( libfdata_list_get_mapped_size_by_index(
523
0
         source_segment_file->chunk_groups_list,
524
0
         list_element_index,
525
0
         &mapped_size,
526
0
         error ) != 1 )
527
0
    {
528
0
      libcerror_error_set(
529
0
       error,
530
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
531
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
532
0
       "%s: unable to retrieve mappped size: %d from source chunk groups list.",
533
0
       function,
534
0
       list_element_index );
535
536
0
      goto on_error;
537
0
    }
538
0
    if( libfdata_list_append_element_with_mapped_size(
539
0
         ( *destination_segment_file )->chunk_groups_list,
540
0
         &element_index,
541
0
         list_element_file_index,
542
0
         list_element_offset,
543
0
         list_element_size,
544
0
         list_element_flags,
545
0
         mapped_size,
546
0
         error ) != 1 )
547
0
    {
548
0
      libcerror_error_set(
549
0
       error,
550
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
551
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
552
0
       "%s: unable to append element: %d to destination chunk groups list.",
553
0
       function,
554
0
       list_element_index );
555
556
0
      goto on_error;
557
0
    }
558
0
  }
559
0
  if( libfcache_cache_clone(
560
0
       &( ( *destination_segment_file )->chunk_groups_cache ),
561
0
       source_segment_file->chunk_groups_cache,
562
0
       error ) != 1 )
563
0
  {
564
0
    libcerror_error_set(
565
0
     error,
566
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
567
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
568
0
     "%s: unable to create destination chunk groups cache.",
569
0
     function );
570
571
0
    goto on_error;
572
0
  }
573
0
  return( 1 );
574
575
0
on_error:
576
0
  if( *destination_segment_file != NULL )
577
0
  {
578
0
    if( ( *destination_segment_file )->chunk_groups_list != NULL )
579
0
    {
580
0
      libfdata_list_free(
581
0
       &( ( *destination_segment_file )->chunk_groups_list ),
582
0
       NULL );
583
0
    }
584
0
    if( ( *destination_segment_file )->sections_list != NULL )
585
0
    {
586
0
      libfdata_list_free(
587
0
       &( ( *destination_segment_file )->sections_list ),
588
0
       NULL );
589
0
    }
590
0
    memory_free(
591
0
     *destination_segment_file );
592
593
0
    *destination_segment_file = NULL;
594
0
  }
595
0
  return( -1 );
596
0
}
597
598
/* Retrieves the number of segments
599
 * Returns 1 if successful or -1 on error
600
 */
601
int libewf_segment_file_get_number_of_sections(
602
     libewf_segment_file_t *segment_file,
603
     int *number_of_sections,
604
     libcerror_error_t **error )
605
0
{
606
0
  static char *function = "libewf_segment_file_get_number_of_sections";
607
608
0
  if( segment_file == NULL )
609
0
  {
610
0
    libcerror_error_set(
611
0
     error,
612
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
613
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
614
0
     "%s: invalid segment file.",
615
0
     function );
616
617
0
    return( -1 );
618
0
  }
619
0
  if( libfdata_list_get_number_of_elements(
620
0
       segment_file->sections_list,
621
0
       number_of_sections,
622
0
       error ) != 1 )
623
0
  {
624
0
    libcerror_error_set(
625
0
     error,
626
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
627
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
628
0
     "%s: unable to retrieve the number of elements from sections list.",
629
0
     function );
630
631
0
    return( -1 );
632
0
  }
633
0
  return( 1 );
634
0
}
635
636
/* Retrieves a specific section from the segment file
637
 * Returns 1 if successful or -1 on error
638
 */
639
int libewf_segment_file_get_section_by_index(
640
     libewf_segment_file_t *segment_file,
641
     int section_index,
642
     libbfio_pool_t *file_io_pool,
643
     libfcache_cache_t *sections_cache,
644
     libewf_section_descriptor_t **section_descriptor,
645
     libcerror_error_t **error )
646
0
{
647
0
  static char *function = "libewf_segment_file_get_section_by_index";
648
649
0
  if( segment_file == NULL )
650
0
  {
651
0
    libcerror_error_set(
652
0
     error,
653
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
654
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
655
0
     "%s: invalid segment file.",
656
0
     function );
657
658
0
    return( -1 );
659
0
  }
660
0
  if( libfdata_list_get_element_value_by_index(
661
0
       segment_file->sections_list,
662
0
       (intptr_t *) file_io_pool,
663
0
       (libfdata_cache_t *) sections_cache,
664
0
       section_index,
665
0
       (intptr_t **) section_descriptor,
666
0
       0,
667
0
       error ) != 1 )
668
0
  {
669
0
    libcerror_error_set(
670
0
     error,
671
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
672
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
673
0
     "%s: unable to retrieve element: %d from sections list.",
674
0
     function,
675
0
     section_index );
676
677
0
    return( -1 );
678
0
  }
679
0
  return( 1 );
680
0
}
681
682
/* Reads the segment file header
683
 * Returns 1 if successful or -1 on error
684
 */
685
int libewf_segment_file_read_file_header_data(
686
     libewf_segment_file_t *segment_file,
687
     const uint8_t *data,
688
     size_t data_size,
689
     libcerror_error_t **error )
690
5.91k
{
691
5.91k
  static char *function = "libewf_segment_file_read_file_header_data";
692
693
#if defined( HAVE_DEBUG_OUTPUT )
694
  uint16_t value_16bit  = 0;
695
#endif
696
697
5.91k
  if( segment_file == NULL )
698
0
  {
699
0
    libcerror_error_set(
700
0
     error,
701
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
702
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
703
0
     "%s: invalid segment file.",
704
0
     function );
705
706
0
    return( -1 );
707
0
  }
708
5.91k
  if( data == NULL )
709
0
  {
710
0
    libcerror_error_set(
711
0
     error,
712
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
713
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
714
0
     "%s: missing data.",
715
0
     function );
716
717
0
    return( -1 );
718
0
  }
719
5.91k
  if( ( data_size != sizeof( ewf_file_header_v1_t ) )
720
5.91k
   && ( data_size != sizeof( ewf_file_header_v2_t ) ) )
721
0
  {
722
0
    libcerror_error_set(
723
0
     error,
724
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
725
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
726
0
     "%s: invalid data size value out of bounds.",
727
0
     function );
728
729
0
    return( -1 );
730
0
  }
731
#if defined( HAVE_DEBUG_OUTPUT )
732
  if( libcnotify_verbose != 0 )
733
  {
734
    libcnotify_printf(
735
     "%s: file header:\n",
736
     function );
737
    libcnotify_print_data(
738
     data,
739
     data_size,
740
     0 );
741
  }
742
#endif
743
5.91k
  if( data_size == sizeof( ewf_file_header_v1_t ) )
744
5.22k
  {
745
5.22k
    byte_stream_copy_to_uint16_little_endian(
746
5.22k
     ( (ewf_file_header_v1_t *) data )->segment_number,
747
5.22k
     segment_file->segment_number );
748
749
5.22k
    segment_file->major_version      = 1;
750
5.22k
    segment_file->minor_version      = 0;
751
5.22k
    segment_file->compression_method = LIBEWF_COMPRESSION_METHOD_DEFLATE;
752
5.22k
  }
753
690
  else if( data_size == sizeof( ewf_file_header_v2_t ) )
754
690
  {
755
690
    segment_file->major_version = ( (ewf_file_header_v2_t *) data )->major_version;
756
690
    segment_file->minor_version = ( (ewf_file_header_v2_t *) data )->minor_version;
757
758
690
    byte_stream_copy_to_uint16_little_endian(
759
690
     ( (ewf_file_header_v2_t *) data )->compression_method,
760
690
     segment_file->compression_method );
761
762
690
    byte_stream_copy_to_uint32_little_endian(
763
690
     ( (ewf_file_header_v2_t *) data )->segment_number,
764
690
     segment_file->segment_number );
765
766
690
    if( memory_copy(
767
690
         segment_file->set_identifier,
768
690
         ( (ewf_file_header_v2_t *) data )->set_identifier,
769
690
         16 ) == NULL )
770
0
    {
771
0
      libcerror_error_set(
772
0
       error,
773
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
774
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
775
0
       "%s: unable to copy set identifier.",
776
0
       function );
777
778
0
      return( -1 );
779
0
    }
780
690
  }
781
#if defined( HAVE_DEBUG_OUTPUT )
782
  if( libcnotify_verbose != 0 )
783
  {
784
    libcnotify_printf(
785
     "%s: signature:\n",
786
     function );
787
    libcnotify_print_data(
788
     data,
789
     8,
790
     0 );
791
792
    if( data_size == sizeof( ewf_file_header_v1_t ) )
793
    {
794
      libcnotify_printf(
795
       "%s: fields start\t\t\t: 0x%02" PRIx8 "\n",
796
       function,
797
       ( (ewf_file_header_v1_t *) data )->fields_start );
798
    }
799
    else if( data_size == sizeof( ewf_file_header_v2_t ) )
800
    {
801
      libcnotify_printf(
802
       "%s: major version\t\t: %" PRIu8 "\n",
803
       function,
804
       segment_file->major_version );
805
806
      libcnotify_printf(
807
       "%s: minor version\t\t: %" PRIu8 "\n",
808
       function,
809
       segment_file->minor_version );
810
811
      libcnotify_printf(
812
       "%s: compression method\t\t: %" PRIu16 " (",
813
       function,
814
       segment_file->compression_method );
815
      libewf_debug_print_compression_method(
816
       segment_file->compression_method );
817
      libcnotify_printf(
818
       ")\n" );
819
    }
820
    libcnotify_printf(
821
     "%s: segment number\t\t: %" PRIu32 "\n",
822
     function,
823
     segment_file->segment_number );
824
825
    if( data_size == sizeof( ewf_file_header_v1_t ) )
826
    {
827
      byte_stream_copy_to_uint16_little_endian(
828
       ( (ewf_file_header_v1_t *) data )->fields_end,
829
       value_16bit );
830
      libcnotify_printf(
831
       "%s: fields end\t\t\t: 0x%04" PRIx16 "\n",
832
       function,
833
       value_16bit );
834
    }
835
    else if( data_size == sizeof( ewf_file_header_v2_t ) )
836
    {
837
      if( libewf_debug_print_guid_value(
838
           function,
839
           "set identifier\t\t",
840
           segment_file->set_identifier,
841
           16,
842
           LIBFGUID_ENDIAN_LITTLE,
843
           LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
844
           error ) != 1 )
845
      {
846
        libcerror_error_set(
847
         error,
848
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
849
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
850
         "%s: unable to print GUID value.",
851
         function );
852
853
        return( -1 );
854
      }
855
    }
856
    libcnotify_printf(
857
     "\n" );
858
  }
859
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
860
861
5.91k
  return( 1 );
862
5.91k
}
863
864
/* Reads the segment file header
865
 * Returns the number of bytes read if successful, or -1 on error
866
 */
867
ssize_t libewf_segment_file_read_file_header_file_io_pool(
868
         libewf_segment_file_t *segment_file,
869
         libbfio_pool_t *file_io_pool,
870
         int file_io_pool_entry,
871
         libcerror_error_t **error )
872
6.01k
{
873
6.01k
  uint8_t file_header_data[ sizeof( ewf_file_header_v2_t ) ];
874
875
6.01k
  static char *function        = "libewf_segment_file_read_file_header_file_io_pool";
876
6.01k
  size_t file_header_data_size = 0;
877
6.01k
  ssize_t read_count           = 0;
878
879
6.01k
  if( segment_file == NULL )
880
0
  {
881
0
    libcerror_error_set(
882
0
     error,
883
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
884
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
885
0
     "%s: invalid segment file.",
886
0
     function );
887
888
0
    return( -1 );
889
0
  }
890
#if defined( HAVE_DEBUG_OUTPUT )
891
  if( libcnotify_verbose != 0 )
892
  {
893
    libcnotify_printf(
894
     "%s: reading file header at offset: 0 (0x00000000)\n",
895
     function );
896
  }
897
#endif
898
6.01k
  read_count = libbfio_pool_read_buffer_at_offset(
899
6.01k
                file_io_pool,
900
6.01k
                file_io_pool_entry,
901
6.01k
                file_header_data,
902
6.01k
                8,
903
6.01k
                0,
904
6.01k
                error );
905
906
6.01k
  if( read_count != (ssize_t) 8 )
907
6
  {
908
6
    libcerror_error_set(
909
6
     error,
910
6
     LIBCERROR_ERROR_DOMAIN_IO,
911
6
     LIBCERROR_IO_ERROR_READ_FAILED,
912
6
     "%s: unable to read file header signature at offset 0 (0x00000000).",
913
6
     function );
914
915
6
    return( -1 );
916
6
  }
917
6.00k
  segment_file->current_offset = read_count;
918
919
6.00k
  if( memory_compare(
920
6.00k
       ewf1_evf_file_signature,
921
6.00k
       file_header_data,
922
6.00k
       8 ) == 0 )
923
5.05k
  {
924
5.05k
    segment_file->type    = LIBEWF_SEGMENT_FILE_TYPE_EWF1;
925
5.05k
    file_header_data_size = sizeof( ewf_file_header_v1_t );
926
5.05k
  }
927
953
  else if( memory_compare(
928
953
            ewf1_lvf_file_signature,
929
953
            file_header_data,
930
953
            8 ) == 0 )
931
176
  {
932
176
    segment_file->type    = LIBEWF_SEGMENT_FILE_TYPE_EWF1_LOGICAL;
933
176
    file_header_data_size = sizeof( ewf_file_header_v1_t );
934
176
  }
935
777
  else if( memory_compare(
936
777
            ewf2_evf_file_signature,
937
777
            file_header_data,
938
777
            8 ) == 0 )
939
221
  {
940
221
    segment_file->type    = LIBEWF_SEGMENT_FILE_TYPE_EWF2;
941
221
    file_header_data_size = sizeof( ewf_file_header_v2_t );
942
221
  }
943
556
  else if( memory_compare(
944
556
            ewf2_lef_file_signature,
945
556
            file_header_data,
946
556
            8 ) == 0 )
947
476
  {
948
476
    segment_file->type    = LIBEWF_SEGMENT_FILE_TYPE_EWF2_LOGICAL;
949
476
    file_header_data_size = sizeof( ewf_file_header_v2_t );
950
476
  }
951
80
  else
952
80
  {
953
80
    libcerror_error_set(
954
80
     error,
955
80
     LIBCERROR_ERROR_DOMAIN_INPUT,
956
80
     LIBCERROR_INPUT_ERROR_SIGNATURE_MISMATCH,
957
80
     "%s: unsupported file header signature.",
958
80
     function );
959
960
80
    return( -1 );
961
80
  }
962
5.92k
  read_count = libbfio_pool_read_buffer(
963
5.92k
                file_io_pool,
964
5.92k
                file_io_pool_entry,
965
5.92k
                &( file_header_data[ 8 ] ),
966
5.92k
                file_header_data_size - 8,
967
5.92k
                error );
968
969
5.92k
  if( read_count != (ssize_t) ( file_header_data_size - 8 ) )
970
10
  {
971
10
    libcerror_error_set(
972
10
     error,
973
10
     LIBCERROR_ERROR_DOMAIN_IO,
974
10
     LIBCERROR_IO_ERROR_READ_FAILED,
975
10
     "%s: unable to read file header data.",
976
10
     function );
977
978
10
    return( -1 );
979
10
  }
980
5.91k
  segment_file->current_offset += read_count;
981
982
5.91k
  if( libewf_segment_file_read_file_header_data(
983
5.91k
       segment_file,
984
5.91k
       file_header_data,
985
5.91k
       file_header_data_size,
986
5.91k
       error ) != 1 )
987
0
  {
988
0
    libcerror_error_set(
989
0
     error,
990
0
     LIBCERROR_ERROR_DOMAIN_IO,
991
0
     LIBCERROR_IO_ERROR_READ_FAILED,
992
0
     "%s: unable to read file header.",
993
0
     function );
994
995
0
    return( -1 );
996
0
  }
997
5.91k
  return( (ssize_t) file_header_data_size );
998
5.91k
}
999
1000
/* Writes the segment file header
1001
 * Returns the number of bytes written if successful, or -1 on error
1002
 */
1003
ssize_t libewf_segment_file_write_file_header(
1004
         libewf_segment_file_t *segment_file,
1005
         libbfio_pool_t *file_io_pool,
1006
         int file_io_pool_entry,
1007
         libcerror_error_t **error )
1008
0
{
1009
0
  uint8_t *file_header_data     = NULL;
1010
0
  static char *function         = "libewf_segment_file_write_file_header";
1011
0
  const uint8_t *file_signature = NULL;
1012
0
  size_t file_header_data_size  = 0;
1013
0
  ssize_t write_count           = 0;
1014
1015
#if defined( HAVE_DEBUG_OUTPUT )
1016
  uint16_t value_16bit          = 0;
1017
#endif
1018
1019
0
  if( segment_file == 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 segment file.",
1026
0
     function );
1027
1028
0
    return( -1 );
1029
0
  }
1030
0
  if( segment_file->major_version == 1 )
1031
0
  {
1032
0
    file_header_data_size = sizeof( ewf_file_header_v1_t );
1033
0
  }
1034
0
  else if( segment_file->major_version == 2 )
1035
0
  {
1036
0
    file_header_data_size = sizeof( ewf_file_header_v2_t );
1037
0
  }
1038
0
  else
1039
0
  {
1040
0
    libcerror_error_set(
1041
0
     error,
1042
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1043
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1044
0
     "%s: unsupported format version.",
1045
0
     function );
1046
1047
0
    return( -1 );
1048
0
  }
1049
0
  if( segment_file->segment_number == 0 )
1050
0
  {
1051
0
    libcerror_error_set(
1052
0
     error,
1053
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1054
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1055
0
     "%s: invalid segment file - segment number value out of bounds.",
1056
0
     function );
1057
1058
0
    return( -1 );
1059
0
  }
1060
0
  if( segment_file->major_version == 1 )
1061
0
  {
1062
0
    if( ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1 )
1063
0
     || ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART ) )
1064
0
    {
1065
0
      file_signature = ewf1_evf_file_signature;
1066
0
    }
1067
0
    else if( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_LOGICAL )
1068
0
    {
1069
0
      file_signature = ewf1_lvf_file_signature;
1070
0
    }
1071
0
  }
1072
0
  else if( segment_file->major_version == 2 )
1073
0
  {
1074
0
    if( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF2 )
1075
0
    {
1076
0
      file_signature = ewf2_evf_file_signature;
1077
0
    }
1078
0
    else if( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF2_LOGICAL )
1079
0
    {
1080
0
      file_signature = ewf2_lef_file_signature;
1081
0
    }
1082
0
  }
1083
0
  if( file_signature == NULL )
1084
0
  {
1085
0
    libcerror_error_set(
1086
0
     error,
1087
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1088
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1089
0
     "%s: unsupported segment file type.",
1090
0
     function );
1091
1092
0
    goto on_error;
1093
0
  }
1094
0
  file_header_data = (uint8_t *) memory_allocate(
1095
0
                                  file_header_data_size );
1096
1097
0
  if( file_header_data == NULL )
1098
0
  {
1099
0
    libcerror_error_set(
1100
0
     error,
1101
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1102
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1103
0
     "%s: unable to create file header data.",
1104
0
     function );
1105
1106
0
    goto on_error;
1107
0
  }
1108
0
  if( memory_set(
1109
0
       file_header_data,
1110
0
       0,
1111
0
       file_header_data_size ) == NULL )
1112
0
  {
1113
0
    libcerror_error_set(
1114
0
     error,
1115
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1116
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
1117
0
     "%s: unable to clear file header data.",
1118
0
     function );
1119
1120
0
    goto on_error;
1121
0
  }
1122
0
  if( memory_set(
1123
0
       file_header_data,
1124
0
       0,
1125
0
       file_header_data_size ) == NULL )
1126
0
  {
1127
0
    libcerror_error_set(
1128
0
     error,
1129
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1130
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
1131
0
     "%s: unable to clear file header data.",
1132
0
     function );
1133
1134
0
    goto on_error;
1135
0
  }
1136
0
  if( memory_copy(
1137
0
       file_header_data,
1138
0
       file_signature,
1139
0
       8 ) == NULL )
1140
0
  {
1141
0
    libcerror_error_set(
1142
0
     error,
1143
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1144
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1145
0
     "%s: unable to copy file signature.",
1146
0
     function );
1147
1148
0
    goto on_error;
1149
0
  }
1150
0
  if( segment_file->major_version == 1 )
1151
0
  {
1152
0
    ( (ewf_file_header_v1_t *) file_header_data )->fields_start = 1;
1153
1154
0
    byte_stream_copy_from_uint16_little_endian(
1155
0
     ( (ewf_file_header_v1_t *) file_header_data )->segment_number,
1156
0
     segment_file->segment_number );
1157
0
  }
1158
0
  else if( segment_file->major_version == 2 )
1159
0
  {
1160
0
    ( (ewf_file_header_v2_t *) file_header_data )->major_version = segment_file->major_version;
1161
0
    ( (ewf_file_header_v2_t *) file_header_data )->minor_version = segment_file->minor_version;
1162
1163
0
    byte_stream_copy_from_uint32_little_endian(
1164
0
     ( (ewf_file_header_v2_t *) file_header_data )->segment_number,
1165
0
     segment_file->segment_number );
1166
1167
0
    byte_stream_copy_from_uint16_little_endian(
1168
0
     ( (ewf_file_header_v2_t *) file_header_data )->compression_method,
1169
0
     segment_file->compression_method );
1170
1171
0
    if( memory_copy(
1172
0
         ( (ewf_file_header_v2_t *) file_header_data )->set_identifier,
1173
0
         segment_file->set_identifier,
1174
0
         16 ) == NULL )
1175
0
    {
1176
0
      libcerror_error_set(
1177
0
       error,
1178
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1179
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1180
0
       "%s: unable to copy set identifier.",
1181
0
       function );
1182
1183
0
      goto on_error;
1184
0
    }
1185
0
  }
1186
#if defined( HAVE_DEBUG_OUTPUT )
1187
  if( libcnotify_verbose != 0 )
1188
  {
1189
    libcnotify_printf(
1190
     "%s: file header:\n",
1191
     function );
1192
    libcnotify_print_data(
1193
     file_header_data,
1194
     file_header_data_size,
1195
     0 );
1196
  }
1197
#endif
1198
#if defined( HAVE_DEBUG_OUTPUT )
1199
  if( libcnotify_verbose != 0 )
1200
  {
1201
    libcnotify_printf(
1202
     "%s: signature:\n",
1203
     function );
1204
    libcnotify_print_data(
1205
     file_header_data,
1206
     8,
1207
     0 );
1208
1209
    if( segment_file->major_version == 1 )
1210
    {
1211
      libcnotify_printf(
1212
       "%s: fields start\t\t\t: 0x%02" PRIx8 "\n",
1213
       function,
1214
       ( (ewf_file_header_v1_t *) file_header_data )->fields_start );
1215
    }
1216
    else if( segment_file->major_version == 2 )
1217
    {
1218
      libcnotify_printf(
1219
       "%s: major version\t\t: %" PRIu8 "\n",
1220
       function,
1221
       segment_file->major_version );
1222
1223
      libcnotify_printf(
1224
       "%s: minor version\t\t: %" PRIu8 "\n",
1225
       function,
1226
       segment_file->minor_version );
1227
1228
      libcnotify_printf(
1229
       "%s: compression method\t\t: %" PRIu16 " (",
1230
       function,
1231
       segment_file->compression_method );
1232
      libewf_debug_print_compression_method(
1233
       segment_file->compression_method );
1234
      libcnotify_printf(
1235
       ")\n" );
1236
    }
1237
    libcnotify_printf(
1238
     "%s: segment number\t\t\t: %" PRIu32 "\n",
1239
     function,
1240
     segment_file->segment_number );
1241
1242
    if( segment_file->major_version == 1 )
1243
    {
1244
      byte_stream_copy_to_uint16_little_endian(
1245
       ( (ewf_file_header_v1_t *) file_header_data )->fields_end,
1246
       value_16bit );
1247
      libcnotify_printf(
1248
       "%s: fields end\t\t\t: 0x%04" PRIx16 "\n",
1249
       function,
1250
       value_16bit );
1251
    }
1252
    else if( segment_file->major_version == 2 )
1253
    {
1254
      if( libewf_debug_print_guid_value(
1255
           function,
1256
           "set identifier\t\t",
1257
           segment_file->set_identifier,
1258
           16,
1259
           LIBFGUID_ENDIAN_LITTLE,
1260
           LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
1261
           error ) != 1 )
1262
      {
1263
        libcerror_error_set(
1264
         error,
1265
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1266
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1267
         "%s: unable to print GUID value.",
1268
         function );
1269
1270
        return( -1 );
1271
      }
1272
    }
1273
    libcnotify_printf(
1274
     "\n" );
1275
  }
1276
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1277
1278
0
  write_count = libbfio_pool_write_buffer(
1279
0
                 file_io_pool,
1280
0
                 file_io_pool_entry,
1281
0
                 file_header_data,
1282
0
                 file_header_data_size,
1283
0
                 error );
1284
1285
0
  if( write_count != (ssize_t) file_header_data_size )
1286
0
  {
1287
0
    libcerror_error_set(
1288
0
     error,
1289
0
     LIBCERROR_ERROR_DOMAIN_IO,
1290
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
1291
0
     "%s: unable to write file header.",
1292
0
     function );
1293
1294
0
    goto on_error;
1295
0
  }
1296
0
  segment_file->current_offset += write_count;
1297
1298
0
  memory_free(
1299
0
   file_header_data );
1300
1301
0
  return( write_count );
1302
1303
0
on_error:
1304
0
  if( file_header_data != NULL )
1305
0
  {
1306
0
    memory_free(
1307
0
     file_header_data );
1308
0
  }
1309
0
  return( -1 );
1310
0
}
1311
1312
/* Seeks the offset in the segment file
1313
 * Returns the offset if seek is successful or -1 on error
1314
 */
1315
off64_t libewf_segment_file_seek_offset(
1316
         libewf_segment_file_t *segment_file,
1317
         libbfio_pool_t *file_io_pool,
1318
         int file_io_pool_entry,
1319
         off64_t offset,
1320
         libcerror_error_t **error )
1321
8.62k
{
1322
8.62k
  static char *function = "libewf_segment_file_seek_offset";
1323
1324
8.62k
  if( segment_file == NULL )
1325
0
  {
1326
0
    libcerror_error_set(
1327
0
     error,
1328
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1329
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1330
0
     "%s: invalid segment file.",
1331
0
     function );
1332
1333
0
    return( -1 );
1334
0
  }
1335
8.62k
  if( libbfio_pool_seek_offset(
1336
8.62k
       file_io_pool,
1337
8.62k
       file_io_pool_entry,
1338
8.62k
       offset,
1339
8.62k
       SEEK_SET,
1340
8.62k
       error ) == -1 )
1341
0
  {
1342
0
    libcerror_error_set(
1343
0
     error,
1344
0
     LIBCERROR_ERROR_DOMAIN_IO,
1345
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
1346
0
     "%s: unable to seek section data offset: %" PRIi64 ".",
1347
0
     function,
1348
0
     offset );
1349
1350
0
    return( -1 );
1351
0
  }
1352
8.62k
  segment_file->current_offset = offset;
1353
1354
8.62k
  return( offset );
1355
8.62k
}
1356
1357
/* Reads the table section
1358
 * Returns the number of bytes read or -1 on error
1359
 */
1360
ssize_t libewf_segment_file_read_table_section(
1361
         libewf_segment_file_t *segment_file,
1362
         libewf_section_descriptor_t *section_descriptor,
1363
         libbfio_pool_t *file_io_pool,
1364
         int file_io_pool_entry,
1365
         size32_t chunk_size,
1366
         libcerror_error_t **error )
1367
859
{
1368
859
  libewf_table_section_t *table_section = NULL;
1369
859
  static char *function                 = "libewf_segment_file_read_table_section";
1370
859
  size64_t chunk_group_data_size        = 0;
1371
859
  size64_t storage_media_size           = 0;
1372
859
  ssize_t read_count                    = 0;
1373
859
  off64_t chunk_group_data_offset       = 0;
1374
859
  uint32_t range_flags                  = 0;
1375
1376
859
  if( segment_file == NULL )
1377
0
  {
1378
0
    libcerror_error_set(
1379
0
     error,
1380
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1381
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1382
0
     "%s: invalid segment file.",
1383
0
     function );
1384
1385
0
    return( -1 );
1386
0
  }
1387
859
  if( segment_file->chunk_groups_list == NULL )
1388
0
  {
1389
0
    libcerror_error_set(
1390
0
     error,
1391
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1392
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1393
0
     "%s: invalid segment file - missing chunk groups list.",
1394
0
     function );
1395
1396
0
    return( -1 );
1397
0
  }
1398
859
  if( section_descriptor == NULL )
1399
0
  {
1400
0
    libcerror_error_set(
1401
0
     error,
1402
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1403
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1404
0
     "%s: invalid section.",
1405
0
     function );
1406
1407
0
    return( -1 );
1408
0
  }
1409
859
  if( libewf_table_section_initialize(
1410
859
       &table_section,
1411
859
       error ) != 1 )
1412
0
  {
1413
0
    libcerror_error_set(
1414
0
     error,
1415
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1416
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1417
0
     "%s: unable to create table section.",
1418
0
     function );
1419
1420
0
    goto on_error;
1421
0
  }
1422
859
  segment_file->previous_last_chunk_filled = segment_file->last_chunk_filled;
1423
1424
859
  read_count = libewf_table_section_read_file_io_pool(
1425
859
                table_section,
1426
859
                segment_file->io_handle,
1427
859
                file_io_pool,
1428
859
                file_io_pool_entry,
1429
859
                segment_file->major_version,
1430
859
                segment_file->type,
1431
859
                section_descriptor->data_size,
1432
859
                section_descriptor->data_flags,
1433
859
                error );
1434
1435
859
  if( read_count == -1 )
1436
139
  {
1437
139
    libcerror_error_set(
1438
139
     error,
1439
139
     LIBCERROR_ERROR_DOMAIN_IO,
1440
139
     LIBCERROR_IO_ERROR_READ_FAILED,
1441
139
     "%s: unable to read table section.",
1442
139
     function );
1443
1444
139
    goto on_error;
1445
139
  }
1446
720
  segment_file->current_offset += read_count;
1447
1448
720
  if( segment_file->major_version == 1 )
1449
720
  {
1450
    /* For EWF version 1 the entire table section is considered the group
1451
     * because the section descriptor is need to determine the chunk data
1452
     * offset and size values
1453
     */
1454
720
    chunk_group_data_offset = section_descriptor->start_offset;
1455
720
    chunk_group_data_size   = (size64_t) section_descriptor->size;
1456
720
  }
1457
0
  else if( segment_file->major_version == 2 )
1458
0
  {
1459
    /* For EWF version 2 the table (section data) is considered the group
1460
     */
1461
0
    chunk_group_data_offset = section_descriptor->start_offset;
1462
0
    chunk_group_data_size   = (size64_t) section_descriptor->data_size;
1463
1464
0
    if( segment_file->last_chunk_filled == -1 )
1465
0
    {
1466
0
      segment_file->last_chunk_filled = (int64_t) table_section->first_chunk_index;
1467
0
    }
1468
0
    else if( (int64_t) table_section->first_chunk_index != segment_file->last_chunk_filled )
1469
0
    {
1470
0
      libcerror_error_set(
1471
0
       error,
1472
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1473
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1474
0
       "%s: out of order first chunk number not yet supported.",
1475
0
       function );
1476
1477
0
      return( -1 );
1478
0
    }
1479
0
  }
1480
720
  if( table_section->entries_corrupted != 0 )
1481
694
  {
1482
694
    segment_file->flags |= LIBEWF_SEGMENT_FILE_FLAG_IS_CORRUPTED;
1483
1484
694
    range_flags = LIBEWF_RANGE_FLAG_IS_TAINTED;
1485
694
  }
1486
720
  if( table_section->number_of_entries > 0 )
1487
720
  {
1488
720
    storage_media_size = (size64_t) chunk_size * table_section->number_of_entries;
1489
1490
720
    if( libfdata_list_append_element_with_mapped_size(
1491
720
         segment_file->chunk_groups_list,
1492
720
         &( segment_file->current_chunk_group_index ),
1493
720
         file_io_pool_entry,
1494
720
         chunk_group_data_offset,
1495
720
         chunk_group_data_size,
1496
720
         range_flags,
1497
720
         storage_media_size,
1498
720
         error ) != 1 )
1499
0
    {
1500
0
      libcerror_error_set(
1501
0
       error,
1502
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1503
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1504
0
       "%s: unable to append element with mapped size to chunk groups list.",
1505
0
       function );
1506
1507
0
      goto on_error;
1508
0
    }
1509
720
    segment_file->storage_media_size += storage_media_size;
1510
720
    segment_file->number_of_chunks   += (uint64_t) table_section->number_of_entries;
1511
720
    segment_file->last_chunk_filled  += (int64_t) table_section->number_of_entries;
1512
720
  }
1513
720
  if( libewf_table_section_free(
1514
720
       &table_section,
1515
720
       error ) != 1 )
1516
0
  {
1517
0
    libcerror_error_set(
1518
0
     error,
1519
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1520
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1521
0
     "%s: unable to free table section.",
1522
0
     function );
1523
1524
0
    goto on_error;
1525
0
  }
1526
720
  return( 1 );
1527
1528
139
on_error:
1529
139
  if( table_section != NULL )
1530
139
  {
1531
139
    libewf_table_section_free(
1532
139
     &table_section,
1533
139
     NULL );
1534
139
  }
1535
139
  return( -1 );
1536
720
}
1537
1538
/* Reads the table2 section
1539
 * Returns the number of bytes read or -1 on error
1540
 */
1541
ssize_t libewf_segment_file_read_table2_section(
1542
         libewf_segment_file_t *segment_file,
1543
         libewf_section_descriptor_t *section_descriptor,
1544
         libbfio_pool_t *file_io_pool,
1545
         int file_io_pool_entry,
1546
         libcerror_error_t **error )
1547
671
{
1548
671
  libewf_table_section_t *table_section = NULL;
1549
671
  static char *function                 = "libewf_segment_file_read_table2_section";
1550
671
  size64_t chunk_group_data_size        = 0;
1551
671
  ssize_t read_count                    = 0;
1552
671
  off64_t chunk_group_data_offset       = 0;
1553
671
  int64_t chunk_group_number_of_entries = 0;
1554
671
  uint32_t chunk_group_range_flags      = 0;
1555
671
  uint8_t number_of_entries_mismatch    = 0;
1556
671
  int chunk_group_file_io_pool_entry    = 0;
1557
671
  int result                            = 0;
1558
1559
671
  if( segment_file == NULL )
1560
0
  {
1561
0
    libcerror_error_set(
1562
0
     error,
1563
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1564
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1565
0
     "%s: invalid segment file.",
1566
0
     function );
1567
1568
0
    return( -1 );
1569
0
  }
1570
671
  if( segment_file->chunk_groups_list == NULL )
1571
0
  {
1572
0
    libcerror_error_set(
1573
0
     error,
1574
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1575
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1576
0
     "%s: invalid segment file - missing chunk groups list.",
1577
0
     function );
1578
1579
0
    return( -1 );
1580
0
  }
1581
671
  if( segment_file->major_version != 1 )
1582
0
  {
1583
0
    libcerror_error_set(
1584
0
     error,
1585
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1586
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1587
0
     "%s: invalid segment file - unsupported major version.",
1588
0
     function );
1589
1590
0
    return( -1 );
1591
0
  }
1592
671
  if( section_descriptor == NULL )
1593
0
  {
1594
0
    libcerror_error_set(
1595
0
     error,
1596
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1597
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1598
0
     "%s: invalid section.",
1599
0
     function );
1600
1601
0
    return( -1 );
1602
0
  }
1603
671
  if( segment_file->last_chunk_filled < segment_file->previous_last_chunk_filled )
1604
0
  {
1605
0
    libcerror_error_set(
1606
0
     error,
1607
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1608
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1609
0
     "%s: invalid chunk group - last chunk filled value out of bounds.",
1610
0
     function );
1611
1612
0
    return( -1 );
1613
0
  }
1614
671
  if( libewf_table_section_initialize(
1615
671
       &table_section,
1616
671
       error ) != 1 )
1617
0
  {
1618
0
    libcerror_error_set(
1619
0
     error,
1620
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1621
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1622
0
     "%s: unable to create table section.",
1623
0
     function );
1624
1625
0
    goto on_error;
1626
0
  }
1627
671
  read_count = libewf_table_section_read_file_io_pool(
1628
671
                table_section,
1629
671
                segment_file->io_handle,
1630
671
                file_io_pool,
1631
671
                file_io_pool_entry,
1632
671
                segment_file->major_version,
1633
671
                segment_file->type,
1634
671
                section_descriptor->data_size,
1635
671
                section_descriptor->data_flags,
1636
671
                error );
1637
1638
671
  if( read_count == -1 )
1639
14
  {
1640
14
    libcerror_error_set(
1641
14
     error,
1642
14
     LIBCERROR_ERROR_DOMAIN_IO,
1643
14
     LIBCERROR_IO_ERROR_READ_FAILED,
1644
14
     "%s: unable to read table2 section.",
1645
14
     function );
1646
1647
14
    goto on_error;
1648
14
  }
1649
657
  segment_file->current_offset += read_count;
1650
1651
657
  chunk_group_number_of_entries = segment_file->last_chunk_filled
1652
657
                                - segment_file->previous_last_chunk_filled;
1653
1654
657
  if( (int64_t) table_section->number_of_entries != chunk_group_number_of_entries )
1655
0
  {
1656
#if defined( HAVE_DEBUG_OUTPUT )
1657
    if( libcnotify_verbose != 0 )
1658
    {
1659
      libcnotify_printf(
1660
       "%s: mismatch between number of entries in table and table2\n.",
1661
       function );
1662
    }
1663
#endif
1664
0
    if( ( chunk_group_range_flags & LIBEWF_RANGE_FLAG_IS_TAINTED ) == 0 )
1665
0
    {
1666
0
      number_of_entries_mismatch = 1;
1667
1668
0
      segment_file->flags |= LIBEWF_SEGMENT_FILE_FLAG_IS_CORRUPTED;
1669
0
    }
1670
0
  }
1671
657
  if( libfdata_list_get_element_by_index(
1672
657
       segment_file->chunk_groups_list,
1673
657
       segment_file->current_chunk_group_index,
1674
657
       &chunk_group_file_io_pool_entry,
1675
657
       &chunk_group_data_offset,
1676
657
       &chunk_group_data_size,
1677
657
       &chunk_group_range_flags,
1678
657
       error ) != 1 )
1679
0
  {
1680
0
    libcerror_error_set(
1681
0
     error,
1682
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1683
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1684
0
     "%s: unable to retrieve element: %d from chunk groups list.",
1685
0
     function,
1686
0
     segment_file->current_chunk_group_index );
1687
1688
0
    goto on_error;
1689
0
  }
1690
657
  result = 1;
1691
1692
657
  if( table_section->entries_corrupted != 0 )
1693
647
  {
1694
647
    segment_file->flags |= LIBEWF_SEGMENT_FILE_FLAG_IS_CORRUPTED;
1695
1696
647
    table_section->number_of_entries = (uint32_t) chunk_group_number_of_entries;
1697
647
  }
1698
10
  else if( number_of_entries_mismatch != 0 )
1699
0
  {
1700
/* TODO improve to handle this corruption */
1701
0
    if( chunk_group_number_of_entries != 0 )
1702
0
    {
1703
      /* If the number of entries in the table section are not 0 prefer the table section
1704
       */
1705
0
      table_section->number_of_entries = (uint32_t) chunk_group_number_of_entries;
1706
0
    }
1707
0
    else
1708
0
    {
1709
      /* If the number of entries in the table section are 0 prefer the table2 section
1710
       */
1711
0
      chunk_group_range_flags = LIBEWF_RANGE_FLAG_IS_TAINTED;
1712
0
    }
1713
0
  }
1714
657
  if( ( chunk_group_range_flags & LIBEWF_RANGE_FLAG_IS_TAINTED ) != 0 )
1715
633
  {
1716
633
    if( table_section->entries_corrupted == 0 )
1717
8
    {
1718
8
      segment_file->last_chunk_filled = segment_file->previous_last_chunk_filled + table_section->number_of_entries;
1719
1720
      /* For EWF version 1 the entire table2 section is considered the group
1721
       * because the section descriptor is need to determine the chunk data
1722
       * offset and size values
1723
       */
1724
8
      chunk_group_data_offset = section_descriptor->start_offset;
1725
8
      chunk_group_data_size   = (size64_t) section_descriptor->size;
1726
1727
#if defined( HAVE_DEBUG_OUTPUT )
1728
      if( libcnotify_verbose != 0 )
1729
      {
1730
        libcnotify_printf(
1731
         "%s: table section was corrupted using table2 section.\n",
1732
         function );
1733
      }
1734
#endif
1735
8
      result = libfdata_list_set_element_by_index(
1736
8
          segment_file->chunk_groups_list,
1737
8
          segment_file->current_chunk_group_index,
1738
8
          file_io_pool_entry,
1739
8
          chunk_group_data_offset,
1740
8
          chunk_group_data_size,
1741
8
          0,
1742
8
          error );
1743
8
    }
1744
625
    else
1745
625
    {
1746
#if defined( HAVE_DEBUG_OUTPUT )
1747
      if( libcnotify_verbose != 0 )
1748
      {
1749
        libcnotify_printf(
1750
         "%s: both the table and table2 sections are corrupted.\n",
1751
         function );
1752
      }
1753
#endif
1754
625
      result = libfdata_list_set_element_by_index(
1755
625
          segment_file->chunk_groups_list,
1756
625
          segment_file->current_chunk_group_index,
1757
625
          chunk_group_file_io_pool_entry,
1758
625
          chunk_group_data_offset,
1759
625
          chunk_group_data_size,
1760
625
          LIBEWF_RANGE_FLAG_IS_CORRUPTED,
1761
625
          error );
1762
625
    }
1763
633
    if( result != 1 )
1764
0
    {
1765
0
      libcerror_error_set(
1766
0
       error,
1767
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1768
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1769
0
       "%s: unable to set element: %d in chunk groups list.",
1770
0
       function,
1771
0
       segment_file->current_chunk_group_index );
1772
1773
0
      goto on_error;
1774
0
    }
1775
633
  }
1776
657
  segment_file->last_chunk_compared += (int64_t) table_section->number_of_entries;
1777
1778
657
  if( libewf_table_section_free(
1779
657
       &table_section,
1780
657
       error ) != 1 )
1781
0
  {
1782
0
    libcerror_error_set(
1783
0
     error,
1784
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1785
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1786
0
     "%s: unable to free table section.",
1787
0
     function );
1788
1789
0
    goto on_error;
1790
0
  }
1791
657
  return( 1 );
1792
1793
14
on_error:
1794
14
  if( table_section != NULL )
1795
14
  {
1796
14
    libewf_table_section_free(
1797
14
     &table_section,
1798
14
     NULL );
1799
14
  }
1800
14
  return( -1 );
1801
657
}
1802
1803
/* Reads a volume section
1804
 * Returns the number of bytes read if successful or -1 on error
1805
 */
1806
ssize_t libewf_segment_file_read_volume_section(
1807
         libewf_segment_file_t *segment_file,
1808
         libewf_section_descriptor_t *section_descriptor,
1809
         libbfio_pool_t *file_io_pool,
1810
         int file_io_pool_entry,
1811
         libewf_media_values_t *media_values,
1812
         libcerror_error_t **error )
1813
894
{
1814
894
  static char *function = "libewf_segment_file_read_volume_section";
1815
894
  ssize_t read_count    = 0;
1816
1817
894
  if( segment_file == NULL )
1818
0
  {
1819
0
    libcerror_error_set(
1820
0
     error,
1821
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1822
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1823
0
     "%s: invalid segment file.",
1824
0
     function );
1825
1826
0
    return( -1 );
1827
0
  }
1828
894
  if( section_descriptor == NULL )
1829
0
  {
1830
0
    libcerror_error_set(
1831
0
     error,
1832
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1833
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1834
0
     "%s: invalid section.",
1835
0
     function );
1836
1837
0
    return( -1 );
1838
0
  }
1839
894
  if( media_values == NULL )
1840
0
  {
1841
0
    libcerror_error_set(
1842
0
     error,
1843
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1844
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1845
0
     "%s: invalid media values.",
1846
0
     function );
1847
1848
0
    return( -1 );
1849
0
  }
1850
894
  if( section_descriptor->data_size == (size64_t) sizeof( ewf_volume_t ) )
1851
892
  {
1852
892
    read_count = libewf_volume_section_e01_read_file_io_pool(
1853
892
                  section_descriptor,
1854
892
                  segment_file->io_handle,
1855
892
                  file_io_pool,
1856
892
                  file_io_pool_entry,
1857
892
                  media_values,
1858
892
                  error );
1859
1860
892
    if( read_count != (ssize_t) section_descriptor->data_size )
1861
54
    {
1862
54
      libcerror_error_set(
1863
54
       error,
1864
54
       LIBCERROR_ERROR_DOMAIN_IO,
1865
54
       LIBCERROR_IO_ERROR_READ_FAILED,
1866
54
       "%s: unable to read EWF-E01 volume section.",
1867
54
       function );
1868
1869
54
      return( -1 );
1870
54
    }
1871
892
  }
1872
2
  else if( section_descriptor->data_size == (size64_t) sizeof( ewf_volume_smart_t ) )
1873
0
  {
1874
0
    read_count = libewf_volume_section_s01_read_file_io_pool(
1875
0
                  section_descriptor,
1876
0
                  segment_file->io_handle,
1877
0
                  file_io_pool,
1878
0
                  file_io_pool_entry,
1879
0
                  media_values,
1880
0
                  error );
1881
1882
0
    if( read_count != (ssize_t) section_descriptor->data_size )
1883
0
    {
1884
0
      libcerror_error_set(
1885
0
       error,
1886
0
       LIBCERROR_ERROR_DOMAIN_IO,
1887
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1888
0
       "%s: unable to read EWF-S01 volume section.",
1889
0
       function );
1890
1891
0
      return( -1 );
1892
0
    }
1893
0
    segment_file->type = LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART;
1894
0
  }
1895
2
  else
1896
2
  {
1897
2
    libcerror_error_set(
1898
2
     error,
1899
2
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1900
2
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1901
2
     "%s: invalid section size value out of bounds.",
1902
2
     function );
1903
1904
2
    return( -1 );
1905
2
  }
1906
838
  segment_file->current_offset += read_count;
1907
1908
838
  return( read_count );
1909
894
}
1910
1911
/* Writes a device information section to file
1912
 * Returns the number of bytes written or -1 on error
1913
 */
1914
ssize_t libewf_segment_file_write_device_information_section(
1915
         libewf_segment_file_t *segment_file,
1916
         libbfio_pool_t *file_io_pool,
1917
         int file_io_pool_entry,
1918
         uint8_t **device_information,
1919
         size_t *device_information_size,
1920
         libewf_media_values_t *media_values,
1921
         libfvalue_table_t *header_values,
1922
         libcerror_error_t **error )
1923
0
{
1924
0
  libewf_section_descriptor_t *section_descriptor = NULL;
1925
0
  static char *function                           = "libewf_segment_file_write_device_information_section";
1926
0
  ssize_t write_count                             = 0;
1927
0
  int element_index                               = 0;
1928
1929
0
  if( segment_file == NULL )
1930
0
  {
1931
0
    libcerror_error_set(
1932
0
     error,
1933
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1934
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1935
0
     "%s: invalid segment file.",
1936
0
     function );
1937
1938
0
    return( -1 );
1939
0
  }
1940
0
  if( segment_file->io_handle == NULL )
1941
0
  {
1942
0
    libcerror_error_set(
1943
0
     error,
1944
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1945
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1946
0
     "%s: invalid segment file - missing IO handle.",
1947
0
     function );
1948
1949
0
    return( -1 );
1950
0
  }
1951
0
  if( device_information == NULL )
1952
0
  {
1953
0
    libcerror_error_set(
1954
0
     error,
1955
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1956
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1957
0
     "%s: invalid device information.",
1958
0
     function );
1959
1960
0
    return( -1 );
1961
0
  }
1962
0
  if( device_information_size == NULL )
1963
0
  {
1964
0
    libcerror_error_set(
1965
0
     error,
1966
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1967
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1968
0
     "%s: invalid device information size.",
1969
0
     function );
1970
1971
0
    return( -1 );
1972
0
  }
1973
0
  if( *device_information == NULL )
1974
0
  {
1975
0
    if( libewf_device_information_generate(
1976
0
         device_information,
1977
0
         device_information_size,
1978
0
         media_values,
1979
0
         header_values,
1980
0
         error ) != 1 )
1981
0
    {
1982
0
      libcerror_error_set(
1983
0
       error,
1984
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1985
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1986
0
       "%s: unable to generate device information.",
1987
0
       function );
1988
1989
0
      goto on_error;
1990
0
    }
1991
0
  }
1992
0
  if( libewf_section_descriptor_initialize(
1993
0
       &section_descriptor,
1994
0
       error ) != 1 )
1995
0
  {
1996
0
    libcerror_error_set(
1997
0
     error,
1998
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1999
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2000
0
     "%s: unable to create section descriptor.",
2001
0
     function );
2002
2003
0
    goto on_error;
2004
0
  }
2005
  /* Do not include the end of string character in the compressed data
2006
   */
2007
0
  write_count = libewf_section_write_compressed_string(
2008
0
                 section_descriptor,
2009
0
                 segment_file->io_handle,
2010
0
                 file_io_pool,
2011
0
                 file_io_pool_entry,
2012
0
                 2,
2013
0
                 LIBEWF_SECTION_TYPE_DEVICE_INFORMATION,
2014
0
                 NULL,
2015
0
                 0,
2016
0
                 segment_file->current_offset,
2017
0
                 segment_file->io_handle->compression_method,
2018
0
                 LIBEWF_COMPRESSION_LEVEL_DEFAULT,
2019
0
                 *device_information,
2020
0
                 *device_information_size - 2,
2021
0
                 0,
2022
0
                 error );
2023
2024
0
  if( write_count == -1 )
2025
0
  {
2026
0
    libcerror_error_set(
2027
0
     error,
2028
0
     LIBCERROR_ERROR_DOMAIN_IO,
2029
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
2030
0
     "%s: unable to write device information section.",
2031
0
     function );
2032
2033
0
    goto on_error;
2034
0
  }
2035
0
  segment_file->current_offset += write_count;
2036
2037
0
  if( libewf_section_descriptor_free(
2038
0
       &section_descriptor,
2039
0
       error ) != 1 )
2040
0
  {
2041
0
    libcerror_error_set(
2042
0
     error,
2043
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2044
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2045
0
     "%s: unable to free section.",
2046
0
     function );
2047
2048
0
    goto on_error;
2049
0
  }
2050
0
  if( libfdata_list_append_element(
2051
0
       segment_file->sections_list,
2052
0
       &element_index,
2053
0
       file_io_pool_entry,
2054
0
       segment_file->current_offset - sizeof( ewf_section_descriptor_v2_t ),
2055
0
       sizeof( ewf_section_descriptor_v2_t ),
2056
0
       0,
2057
0
       error ) != 1 )
2058
0
  {
2059
0
    libcerror_error_set(
2060
0
     error,
2061
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2062
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2063
0
     "%s: unable to append element to sections list.",
2064
0
     function );
2065
2066
0
    goto on_error;
2067
0
  }
2068
0
  return( write_count );
2069
2070
0
on_error:
2071
0
  if( section_descriptor != NULL )
2072
0
  {
2073
0
    libewf_section_descriptor_free(
2074
0
     &section_descriptor,
2075
0
     NULL );
2076
0
  }
2077
0
  return( -1 );
2078
0
}
2079
2080
/* Writes a case data section to file
2081
 * Returns the number of bytes written or -1 on error
2082
 */
2083
ssize_t libewf_segment_file_write_case_data_section(
2084
         libewf_segment_file_t *segment_file,
2085
         libbfio_pool_t *file_io_pool,
2086
         int file_io_pool_entry,
2087
         uint8_t **case_data,
2088
         size_t *case_data_size,
2089
         libewf_media_values_t *media_values,
2090
         libfvalue_table_t *header_values,
2091
         time_t timestamp,
2092
         libcerror_error_t **error )
2093
0
{
2094
0
  libewf_section_descriptor_t *section_descriptor = NULL;
2095
0
  static char *function                           = "libewf_segment_file_write_case_data_section";
2096
0
  ssize_t write_count                             = 0;
2097
0
  int element_index                               = 0;
2098
2099
0
  if( segment_file == NULL )
2100
0
  {
2101
0
    libcerror_error_set(
2102
0
     error,
2103
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2104
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2105
0
     "%s: invalid segment file.",
2106
0
     function );
2107
2108
0
    return( -1 );
2109
0
  }
2110
0
  if( segment_file->io_handle == NULL )
2111
0
  {
2112
0
    libcerror_error_set(
2113
0
     error,
2114
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2115
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2116
0
     "%s: invalid segment file - missing IO handle.",
2117
0
     function );
2118
2119
0
    return( -1 );
2120
0
  }
2121
0
  if( case_data == NULL )
2122
0
  {
2123
0
    libcerror_error_set(
2124
0
     error,
2125
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2126
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2127
0
     "%s: invalid case data.",
2128
0
     function );
2129
2130
0
    return( -1 );
2131
0
  }
2132
0
  if( case_data_size == NULL )
2133
0
  {
2134
0
    libcerror_error_set(
2135
0
     error,
2136
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2137
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2138
0
     "%s: invalid case data size.",
2139
0
     function );
2140
2141
0
    return( -1 );
2142
0
  }
2143
0
  if( *case_data == NULL )
2144
0
  {
2145
0
    if( libewf_case_data_generate(
2146
0
         case_data,
2147
0
         case_data_size,
2148
0
         media_values,
2149
0
         header_values,
2150
0
         timestamp,
2151
0
         segment_file->io_handle->format,
2152
0
         error ) != 1 )
2153
0
    {
2154
0
      libcerror_error_set(
2155
0
       error,
2156
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2157
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2158
0
       "%s: unable to generate case data.",
2159
0
       function );
2160
2161
0
      goto on_error;
2162
0
    }
2163
0
  }
2164
0
  if( libewf_section_descriptor_initialize(
2165
0
       &section_descriptor,
2166
0
       error ) != 1 )
2167
0
  {
2168
0
    libcerror_error_set(
2169
0
     error,
2170
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2171
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2172
0
     "%s: unable to create section descriptor.",
2173
0
     function );
2174
2175
0
    goto on_error;
2176
0
  }
2177
  /* Do not include the end of string character in the compressed data
2178
   */
2179
0
  write_count = libewf_section_write_compressed_string(
2180
0
                 section_descriptor,
2181
0
                 segment_file->io_handle,
2182
0
                 file_io_pool,
2183
0
                 file_io_pool_entry,
2184
0
                 2,
2185
0
                 LIBEWF_SECTION_TYPE_CASE_DATA,
2186
0
                 NULL,
2187
0
                 0,
2188
0
                 segment_file->current_offset,
2189
0
                 segment_file->io_handle->compression_method,
2190
0
                 LIBEWF_COMPRESSION_LEVEL_DEFAULT,
2191
0
                 *case_data,
2192
0
                 *case_data_size - 2,
2193
0
                 0,
2194
0
                 error );
2195
2196
0
  if( write_count == -1 )
2197
0
  {
2198
0
    libcerror_error_set(
2199
0
     error,
2200
0
     LIBCERROR_ERROR_DOMAIN_IO,
2201
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
2202
0
     "%s: unable to write case data section.",
2203
0
     function );
2204
2205
0
    goto on_error;
2206
0
  }
2207
0
  segment_file->current_offset += write_count;
2208
2209
0
  if( libewf_section_descriptor_free(
2210
0
       &section_descriptor,
2211
0
       error ) != 1 )
2212
0
  {
2213
0
    libcerror_error_set(
2214
0
     error,
2215
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2216
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2217
0
     "%s: unable to free section.",
2218
0
     function );
2219
2220
0
    goto on_error;
2221
0
  }
2222
0
  if( libfdata_list_append_element(
2223
0
       segment_file->sections_list,
2224
0
       &element_index,
2225
0
       file_io_pool_entry,
2226
0
       segment_file->current_offset - sizeof( ewf_section_descriptor_v2_t ),
2227
0
       sizeof( ewf_section_descriptor_v2_t ),
2228
0
       0,
2229
0
       error ) != 1 )
2230
0
  {
2231
0
    libcerror_error_set(
2232
0
     error,
2233
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2234
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2235
0
     "%s: unable to append element to sections list.",
2236
0
     function );
2237
2238
0
    goto on_error;
2239
0
  }
2240
0
  return( write_count );
2241
2242
0
on_error:
2243
0
  if( section_descriptor != NULL )
2244
0
  {
2245
0
    libewf_section_descriptor_free(
2246
0
     &section_descriptor,
2247
0
     NULL );
2248
0
  }
2249
0
  return( -1 );
2250
0
}
2251
2252
/* Writes a header section to file
2253
 * Returns the number of bytes written or -1 on error
2254
 */
2255
ssize_t libewf_segment_file_write_header_section(
2256
         libewf_segment_file_t *segment_file,
2257
         libbfio_pool_t *file_io_pool,
2258
         int file_io_pool_entry,
2259
         libewf_header_sections_t *header_sections,
2260
         int8_t compression_level,
2261
         libcerror_error_t **error )
2262
0
{
2263
0
  libewf_section_descriptor_t *section_descriptor = NULL;
2264
0
  static char *function                           = "libewf_segment_file_write_header_section";
2265
0
  ssize_t write_count                             = 0;
2266
0
  int element_index                               = 0;
2267
2268
0
  if( segment_file == NULL )
2269
0
  {
2270
0
    libcerror_error_set(
2271
0
     error,
2272
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2273
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2274
0
     "%s: invalid segment file.",
2275
0
     function );
2276
2277
0
    return( -1 );
2278
0
  }
2279
0
  if( segment_file->io_handle == NULL )
2280
0
  {
2281
0
    libcerror_error_set(
2282
0
     error,
2283
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2284
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2285
0
     "%s: invalid segment file - missing IO handle.",
2286
0
     function );
2287
2288
0
    return( -1 );
2289
0
  }
2290
0
  if( header_sections == NULL )
2291
0
  {
2292
0
    libcerror_error_set(
2293
0
     error,
2294
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2295
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2296
0
     "%s: invalid header sections.",
2297
0
     function );
2298
2299
0
    return( -1 );
2300
0
  }
2301
0
  if( ( header_sections->header == NULL )
2302
0
   || ( header_sections->header_size == 0 ) )
2303
0
  {
2304
0
    libcerror_error_set(
2305
0
     error,
2306
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2307
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2308
0
     "%s: invalid header sections - missing header.",
2309
0
     function );
2310
2311
0
    return( -1 );
2312
0
  }
2313
0
  if( libewf_section_descriptor_initialize(
2314
0
       &section_descriptor,
2315
0
       error ) != 1 )
2316
0
  {
2317
0
    libcerror_error_set(
2318
0
     error,
2319
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2320
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2321
0
     "%s: unable to create section descriptor.",
2322
0
     function );
2323
2324
0
    goto on_error;
2325
0
  }
2326
  /* Do not include the end of string character in the compressed data
2327
   */
2328
0
  write_count = libewf_section_write_compressed_string(
2329
0
                 section_descriptor,
2330
0
                 segment_file->io_handle,
2331
0
                 file_io_pool,
2332
0
                 file_io_pool_entry,
2333
0
                 1,
2334
0
                 0,
2335
0
                 (uint8_t *) "header",
2336
0
                 6,
2337
0
                 segment_file->current_offset,
2338
0
                 segment_file->io_handle->compression_method,
2339
0
                 compression_level,
2340
0
                 header_sections->header,
2341
0
                 header_sections->header_size - 1,
2342
0
                 0,
2343
0
                 error );
2344
2345
0
  if( write_count == -1 )
2346
0
  {
2347
0
    libcerror_error_set(
2348
0
     error,
2349
0
     LIBCERROR_ERROR_DOMAIN_IO,
2350
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
2351
0
     "%s: unable to write header section.",
2352
0
     function );
2353
2354
0
    goto on_error;
2355
0
  }
2356
0
  if( libfdata_list_append_element(
2357
0
       segment_file->sections_list,
2358
0
       &element_index,
2359
0
       file_io_pool_entry,
2360
0
       segment_file->current_offset,
2361
0
       sizeof( ewf_section_descriptor_v1_t ),
2362
0
       0,
2363
0
       error ) != 1 )
2364
0
  {
2365
0
    libcerror_error_set(
2366
0
     error,
2367
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2368
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2369
0
     "%s: unable to append element to sections list.",
2370
0
     function );
2371
2372
0
    goto on_error;
2373
0
  }
2374
0
  segment_file->current_offset += write_count;
2375
2376
0
  if( libewf_section_descriptor_free(
2377
0
       &section_descriptor,
2378
0
       error ) != 1 )
2379
0
  {
2380
0
    libcerror_error_set(
2381
0
     error,
2382
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2383
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2384
0
     "%s: unable to free section.",
2385
0
     function );
2386
2387
0
    goto on_error;
2388
0
  }
2389
0
  header_sections->number_of_header_sections += 1;
2390
2391
#if defined( HAVE_DEBUG_OUTPUT )
2392
  if( libcnotify_verbose != 0 )
2393
  {
2394
    if( libewf_debug_byte_stream_print(
2395
         "Header",
2396
         header_sections->header,
2397
         header_sections->header_size,
2398
         error ) != 1 )
2399
    {
2400
      libcerror_error_set(
2401
       error,
2402
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2403
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
2404
       "%s: unable to print header.",
2405
       function );
2406
2407
      goto on_error;
2408
    }
2409
  }
2410
#endif
2411
0
  return( write_count );
2412
2413
0
on_error:
2414
0
  if( section_descriptor != NULL )
2415
0
  {
2416
0
    libewf_section_descriptor_free(
2417
0
     &section_descriptor,
2418
0
     NULL );
2419
0
  }
2420
0
  return( -1 );
2421
0
}
2422
2423
/* Writes a header2 section to file
2424
 * Returns the number of bytes written or -1 on error
2425
 */
2426
ssize_t libewf_segment_file_write_header2_section(
2427
         libewf_segment_file_t *segment_file,
2428
         libbfio_pool_t *file_io_pool,
2429
         int file_io_pool_entry,
2430
         libewf_header_sections_t *header_sections,
2431
         libcerror_error_t **error )
2432
0
{
2433
0
  libewf_section_descriptor_t *section_descriptor = NULL;
2434
0
  static char *function                           = "libewf_segment_file_write_header2_section";
2435
0
  ssize_t write_count                             = 0;
2436
0
  int element_index                               = 0;
2437
2438
0
  if( segment_file == NULL )
2439
0
  {
2440
0
    libcerror_error_set(
2441
0
     error,
2442
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2443
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2444
0
     "%s: invalid segment file.",
2445
0
     function );
2446
2447
0
    return( -1 );
2448
0
  }
2449
0
  if( segment_file->io_handle == NULL )
2450
0
  {
2451
0
    libcerror_error_set(
2452
0
     error,
2453
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2454
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2455
0
     "%s: invalid segment file - missing IO handle.",
2456
0
     function );
2457
2458
0
    return( -1 );
2459
0
  }
2460
0
  if( header_sections == NULL )
2461
0
  {
2462
0
    libcerror_error_set(
2463
0
     error,
2464
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2465
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2466
0
     "%s: invalid header sections.",
2467
0
     function );
2468
2469
0
    return( -1 );
2470
0
  }
2471
0
  if( ( header_sections->header2 == NULL )
2472
0
   || ( header_sections->header2_size == 0 ) )
2473
0
  {
2474
0
    libcerror_error_set(
2475
0
     error,
2476
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2477
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2478
0
     "%s: invalid header sections - missing header2.",
2479
0
     function );
2480
2481
0
    return( -1 );
2482
0
  }
2483
0
  if( libewf_section_descriptor_initialize(
2484
0
       &section_descriptor,
2485
0
       error ) != 1 )
2486
0
  {
2487
0
    libcerror_error_set(
2488
0
     error,
2489
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2490
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2491
0
     "%s: unable to create section descriptor.",
2492
0
     function );
2493
2494
0
    goto on_error;
2495
0
  }
2496
  /* Do not include the end of string character in the compressed data
2497
   */
2498
0
  write_count = libewf_section_write_compressed_string(
2499
0
                 section_descriptor,
2500
0
                 segment_file->io_handle,
2501
0
                 file_io_pool,
2502
0
                 file_io_pool_entry,
2503
0
                 1,
2504
0
                 0,
2505
0
                 (uint8_t *) "header2",
2506
0
                 7,
2507
0
                 segment_file->current_offset,
2508
0
                 segment_file->io_handle->compression_method,
2509
0
                 LIBEWF_COMPRESSION_LEVEL_DEFAULT,
2510
0
                 header_sections->header2,
2511
0
                 header_sections->header2_size - 2,
2512
0
                 0,
2513
0
                 error );
2514
2515
0
  if( write_count == -1 )
2516
0
  {
2517
0
    libcerror_error_set(
2518
0
     error,
2519
0
     LIBCERROR_ERROR_DOMAIN_IO,
2520
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
2521
0
     "%s: unable to write header2 section.",
2522
0
     function );
2523
2524
0
    goto on_error;
2525
0
  }
2526
0
  if( libfdata_list_append_element(
2527
0
       segment_file->sections_list,
2528
0
       &element_index,
2529
0
       file_io_pool_entry,
2530
0
       segment_file->current_offset,
2531
0
       sizeof( ewf_section_descriptor_v1_t ),
2532
0
       0,
2533
0
       error ) != 1 )
2534
0
  {
2535
0
    libcerror_error_set(
2536
0
     error,
2537
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2538
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2539
0
     "%s: unable to append element to sections list.",
2540
0
     function );
2541
2542
0
    goto on_error;
2543
0
  }
2544
0
  segment_file->current_offset += write_count;
2545
2546
0
  if( libewf_section_descriptor_free(
2547
0
       &section_descriptor,
2548
0
       error ) != 1 )
2549
0
  {
2550
0
    libcerror_error_set(
2551
0
     error,
2552
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2553
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2554
0
     "%s: unable to free section.",
2555
0
     function );
2556
2557
0
    goto on_error;
2558
0
  }
2559
0
  header_sections->number_of_header_sections += 1;
2560
2561
#if defined( HAVE_DEBUG_OUTPUT )
2562
  if( libcnotify_verbose != 0 )
2563
  {
2564
    if( libewf_debug_utf16_stream_print(
2565
         "Header2",
2566
         header_sections->header2,
2567
         header_sections->header2_size,
2568
         LIBUNA_ENDIAN_LITTLE,
2569
         error ) != 1 )
2570
    {
2571
      libcerror_error_set(
2572
       error,
2573
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2574
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
2575
       "%s: unable to print header2.",
2576
       function );
2577
2578
      goto on_error;
2579
    }
2580
  }
2581
#endif
2582
0
  return( write_count );
2583
2584
0
on_error:
2585
0
  if( section_descriptor != NULL )
2586
0
  {
2587
0
    libewf_section_descriptor_free(
2588
0
     &section_descriptor,
2589
0
     NULL );
2590
0
  }
2591
0
  return( -1 );
2592
0
}
2593
2594
/* Writes a xheader section to file
2595
 * Returns the number of bytes written or -1 on error
2596
 */
2597
ssize_t libewf_segment_file_write_xheader_section(
2598
         libewf_segment_file_t *segment_file,
2599
         libbfio_pool_t *file_io_pool,
2600
         int file_io_pool_entry,
2601
         libewf_header_sections_t *header_sections,
2602
         libcerror_error_t **error )
2603
0
{
2604
0
  libewf_section_descriptor_t *section_descriptor = NULL;
2605
0
  static char *function                           = "libewf_segment_file_write_xheader_section";
2606
0
  ssize_t write_count                             = 0;
2607
0
  int element_index                               = 0;
2608
2609
0
  if( segment_file == NULL )
2610
0
  {
2611
0
    libcerror_error_set(
2612
0
     error,
2613
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2614
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2615
0
     "%s: invalid segment file.",
2616
0
     function );
2617
2618
0
    return( -1 );
2619
0
  }
2620
0
  if( segment_file->io_handle == NULL )
2621
0
  {
2622
0
    libcerror_error_set(
2623
0
     error,
2624
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2625
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2626
0
     "%s: invalid segment file - missing IO handle.",
2627
0
     function );
2628
2629
0
    return( -1 );
2630
0
  }
2631
0
  if( header_sections == NULL )
2632
0
  {
2633
0
    libcerror_error_set(
2634
0
     error,
2635
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2636
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2637
0
     "%s: invalid header sections.",
2638
0
     function );
2639
2640
0
    return( -1 );
2641
0
  }
2642
0
  if( ( header_sections->xheader == NULL )
2643
0
   || ( header_sections->xheader_size == 0 ) )
2644
0
  {
2645
0
    libcerror_error_set(
2646
0
     error,
2647
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2648
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2649
0
     "%s: invalid header sections - missing xheader.",
2650
0
     function );
2651
2652
0
    return( -1 );
2653
0
  }
2654
0
  if( libewf_section_descriptor_initialize(
2655
0
       &section_descriptor,
2656
0
       error ) != 1 )
2657
0
  {
2658
0
    libcerror_error_set(
2659
0
     error,
2660
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2661
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2662
0
     "%s: unable to create section descriptor.",
2663
0
     function );
2664
2665
0
    goto on_error;
2666
0
  }
2667
  /* Do not include the end of string character in the compressed data
2668
   */
2669
0
  write_count = libewf_section_write_compressed_string(
2670
0
                 section_descriptor,
2671
0
                 segment_file->io_handle,
2672
0
                 file_io_pool,
2673
0
                 file_io_pool_entry,
2674
0
                 1,
2675
0
                 0,
2676
0
                 (uint8_t *) "xheader",
2677
0
                 7,
2678
0
                 segment_file->current_offset,
2679
0
                 segment_file->io_handle->compression_method,
2680
0
                 LIBEWF_COMPRESSION_LEVEL_DEFAULT,
2681
0
                 header_sections->xheader,
2682
0
                 header_sections->xheader_size - 1,
2683
0
                 0,
2684
0
                 error );
2685
2686
0
  if( write_count == -1 )
2687
0
  {
2688
0
    libcerror_error_set(
2689
0
     error,
2690
0
     LIBCERROR_ERROR_DOMAIN_IO,
2691
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
2692
0
     "%s: unable to write xheader section.",
2693
0
     function );
2694
2695
0
    goto on_error;
2696
0
  }
2697
0
  if( libfdata_list_append_element(
2698
0
       segment_file->sections_list,
2699
0
       &element_index,
2700
0
       file_io_pool_entry,
2701
0
       segment_file->current_offset,
2702
0
       sizeof( ewf_section_descriptor_v1_t ),
2703
0
       0,
2704
0
       error ) != 1 )
2705
0
  {
2706
0
    libcerror_error_set(
2707
0
     error,
2708
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2709
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2710
0
     "%s: unable to append element to sections list.",
2711
0
     function );
2712
2713
0
    goto on_error;
2714
0
  }
2715
0
  segment_file->current_offset += write_count;
2716
2717
0
  if( libewf_section_descriptor_free(
2718
0
       &section_descriptor,
2719
0
       error ) != 1 )
2720
0
  {
2721
0
    libcerror_error_set(
2722
0
     error,
2723
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2724
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2725
0
     "%s: unable to free section.",
2726
0
     function );
2727
2728
0
    goto on_error;
2729
0
  }
2730
0
  header_sections->number_of_header_sections += 1;
2731
2732
#if defined( HAVE_DEBUG_OUTPUT )
2733
  if( libcnotify_verbose != 0 )
2734
  {
2735
    if( libewf_debug_utf8_stream_print(
2736
         "XHeader",
2737
         header_sections->xheader,
2738
         header_sections->xheader_size,
2739
         error ) != 1 )
2740
    {
2741
      libcerror_error_set(
2742
       error,
2743
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2744
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
2745
       "%s: unable to print xheader.",
2746
       function );
2747
2748
      goto on_error;
2749
    }
2750
  }
2751
#endif
2752
0
  return( write_count );
2753
2754
0
on_error:
2755
0
  if( section_descriptor != NULL )
2756
0
  {
2757
0
    libewf_section_descriptor_free(
2758
0
     &section_descriptor,
2759
0
     NULL );
2760
0
  }
2761
0
  return( -1 );
2762
0
}
2763
2764
/* Writes the header sections to file
2765
 * Returns the number of bytes written or -1 on error
2766
 */
2767
ssize_t libewf_segment_file_write_header_sections(
2768
         libewf_segment_file_t *segment_file,
2769
         libbfio_pool_t *file_io_pool,
2770
         int file_io_pool_entry,
2771
         libfvalue_table_t *header_values,
2772
         time_t timestamp,
2773
         libcerror_error_t **error )
2774
0
{
2775
0
  libewf_header_sections_t *header_sections = NULL;
2776
0
  static char *function                     = "libewf_segment_file_write_header_sections";
2777
0
  ssize_t write_count                       = 0;
2778
0
  ssize_t total_write_count                 = 0;
2779
2780
0
  if( segment_file == NULL )
2781
0
  {
2782
0
    libcerror_error_set(
2783
0
     error,
2784
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2785
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2786
0
     "%s: invalid segment file.",
2787
0
     function );
2788
2789
0
    return( -1 );
2790
0
  }
2791
0
  if( segment_file->io_handle == NULL )
2792
0
  {
2793
0
    libcerror_error_set(
2794
0
     error,
2795
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2796
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2797
0
     "%s: invalid segment file - missing IO handle.",
2798
0
     function );
2799
2800
0
    return( -1 );
2801
0
  }
2802
0
  if( libewf_header_sections_initialize(
2803
0
       &header_sections,
2804
0
       error ) != 1 )
2805
0
  {
2806
0
    libcerror_error_set(
2807
0
     error,
2808
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2809
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2810
0
     "%s: unable to create header sections.",
2811
0
     function );
2812
2813
0
    goto on_error;
2814
0
  }
2815
0
  if( libewf_header_sections_generate(
2816
0
       header_sections,
2817
0
       header_values,
2818
0
       timestamp,
2819
0
       segment_file->io_handle->compression_level,
2820
0
       segment_file->io_handle->format,
2821
0
       segment_file->io_handle->header_codepage,
2822
0
       error ) == -1 )
2823
0
  {
2824
0
    libcerror_error_set(
2825
0
     error,
2826
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2827
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2828
0
     "%s: unable to set header sections.",
2829
0
     function );
2830
2831
0
    goto on_error;
2832
0
  }
2833
0
  if( ( segment_file->io_handle->format == LIBEWF_FORMAT_EWF )
2834
0
   || ( segment_file->io_handle->format == LIBEWF_FORMAT_SMART )
2835
0
   || ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE1 ) )
2836
0
  {
2837
    /* The header should be written only once
2838
     * and using the compression used in the file
2839
     */
2840
0
    write_count = libewf_segment_file_write_header_section(
2841
0
                   segment_file,
2842
0
                   file_io_pool,
2843
0
                   file_io_pool_entry,
2844
0
                   header_sections,
2845
0
                   segment_file->io_handle->compression_level,
2846
0
                   error );
2847
2848
0
    if( write_count == -1 )
2849
0
    {
2850
0
      libcerror_error_set(
2851
0
       error,
2852
0
       LIBCERROR_ERROR_DOMAIN_IO,
2853
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
2854
0
       "%s: unable to write single header section.",
2855
0
       function );
2856
2857
0
      goto on_error;
2858
0
    }
2859
0
    total_write_count += write_count;
2860
0
  }
2861
0
  else if( ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE2 )
2862
0
        || ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE3 )
2863
0
        || ( segment_file->io_handle->format == LIBEWF_FORMAT_FTK_IMAGER )
2864
0
        || ( segment_file->io_handle->format == LIBEWF_FORMAT_LINEN5 )
2865
0
        || ( segment_file->io_handle->format == LIBEWF_FORMAT_LINEN6 )
2866
0
        || ( segment_file->io_handle->format == LIBEWF_FORMAT_LINEN7 ) )
2867
0
  {
2868
    /* The header should be written twice
2869
     * the default compression is used
2870
     */
2871
0
    write_count = libewf_segment_file_write_header_section(
2872
0
                   segment_file,
2873
0
                   file_io_pool,
2874
0
                   file_io_pool_entry,
2875
0
                   header_sections,
2876
0
                   LIBEWF_COMPRESSION_LEVEL_DEFAULT,
2877
0
                   error );
2878
2879
0
    if( write_count == -1 )
2880
0
    {
2881
0
      libcerror_error_set(
2882
0
       error,
2883
0
       LIBCERROR_ERROR_DOMAIN_IO,
2884
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
2885
0
       "%s: unable to write first header section.",
2886
0
       function );
2887
2888
0
      goto on_error;
2889
0
    }
2890
0
    total_write_count += write_count;
2891
2892
0
    write_count = libewf_segment_file_write_header_section(
2893
0
                   segment_file,
2894
0
                   file_io_pool,
2895
0
                   file_io_pool_entry,
2896
0
                   header_sections,
2897
0
                   LIBEWF_COMPRESSION_LEVEL_DEFAULT,
2898
0
                   error );
2899
2900
0
    if( write_count == -1 )
2901
0
    {
2902
0
      libcerror_error_set(
2903
0
       error,
2904
0
       LIBCERROR_ERROR_DOMAIN_IO,
2905
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
2906
0
       "%s: unable to write second header section.",
2907
0
       function );
2908
2909
0
      goto on_error;
2910
0
    }
2911
0
    total_write_count += write_count;
2912
0
  }
2913
0
  else if( ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE4 )
2914
0
        || ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE5 )
2915
0
        || ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE6 )
2916
0
        || ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE7 ) )
2917
0
  {
2918
    /* The header2 should be written twice
2919
     * the default compression is used
2920
     */
2921
0
    write_count = libewf_segment_file_write_header2_section(
2922
0
                   segment_file,
2923
0
                   file_io_pool,
2924
0
                   file_io_pool_entry,
2925
0
                   header_sections,
2926
0
                   error );
2927
2928
0
    if( write_count == -1 )
2929
0
    {
2930
0
      libcerror_error_set(
2931
0
       error,
2932
0
       LIBCERROR_ERROR_DOMAIN_IO,
2933
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
2934
0
       "%s: unable to write first header2 section.",
2935
0
       function );
2936
2937
0
      goto on_error;
2938
0
    }
2939
0
    total_write_count += write_count;
2940
2941
0
    write_count = libewf_segment_file_write_header2_section(
2942
0
                   segment_file,
2943
0
                   file_io_pool,
2944
0
                   file_io_pool_entry,
2945
0
                   header_sections,
2946
0
                   error );
2947
2948
0
    if( write_count == -1 )
2949
0
    {
2950
0
      libcerror_error_set(
2951
0
       error,
2952
0
       LIBCERROR_ERROR_DOMAIN_IO,
2953
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
2954
0
       "%s: unable to write second header2 section.",
2955
0
       function );
2956
2957
0
      goto on_error;
2958
0
    }
2959
0
    total_write_count += write_count;
2960
2961
    /* The header should be written once
2962
     * the default compression is used
2963
     */
2964
0
    write_count = libewf_segment_file_write_header_section(
2965
0
                   segment_file,
2966
0
                   file_io_pool,
2967
0
                   file_io_pool_entry,
2968
0
                   header_sections,
2969
0
                   LIBEWF_COMPRESSION_LEVEL_DEFAULT,
2970
0
                   error );
2971
2972
0
    if( write_count == -1 )
2973
0
    {
2974
0
      libcerror_error_set(
2975
0
       error,
2976
0
       LIBCERROR_ERROR_DOMAIN_IO,
2977
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
2978
0
       "%s: unable to write third header section.",
2979
0
       function );
2980
2981
0
      goto on_error;
2982
0
    }
2983
0
    total_write_count += write_count;
2984
0
  }
2985
  /* EWFX uses the header and header2 for backwards compatibility
2986
   */
2987
0
  else if( segment_file->io_handle->format == LIBEWF_FORMAT_EWFX )
2988
0
  {
2989
    /* The xheader should be written once
2990
     * the default compression is used
2991
     */
2992
0
    write_count = libewf_segment_file_write_xheader_section(
2993
0
                   segment_file,
2994
0
                   file_io_pool,
2995
0
                   file_io_pool_entry,
2996
0
                   header_sections,
2997
0
                   error );
2998
2999
0
    if( write_count == -1 )
3000
0
    {
3001
0
      libcerror_error_set(
3002
0
       error,
3003
0
       LIBCERROR_ERROR_DOMAIN_IO,
3004
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
3005
0
       "%s: unable to write xheader section.",
3006
0
       function );
3007
3008
0
      goto on_error;
3009
0
    }
3010
0
    total_write_count += write_count;
3011
3012
    /* The header2 should be written once
3013
     * the default compression is used
3014
     */
3015
0
    write_count = libewf_segment_file_write_header2_section(
3016
0
                   segment_file,
3017
0
                   file_io_pool,
3018
0
                   file_io_pool_entry,
3019
0
                   header_sections,
3020
0
                   error );
3021
3022
0
    if( write_count == -1 )
3023
0
    {
3024
0
      libcerror_error_set(
3025
0
       error,
3026
0
       LIBCERROR_ERROR_DOMAIN_IO,
3027
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
3028
0
       "%s: unable to write second header2 section.",
3029
0
       function );
3030
3031
0
      goto on_error;
3032
0
    }
3033
0
    total_write_count += write_count;
3034
3035
    /* The header should be written once
3036
     * the default compression is used
3037
     */
3038
0
    write_count = libewf_segment_file_write_header_section(
3039
0
                   segment_file,
3040
0
                   file_io_pool,
3041
0
                   file_io_pool_entry,
3042
0
                   header_sections,
3043
0
                   LIBEWF_COMPRESSION_LEVEL_DEFAULT,
3044
0
                   error );
3045
3046
0
    if( write_count == -1 )
3047
0
    {
3048
0
      libcerror_error_set(
3049
0
       error,
3050
0
       LIBCERROR_ERROR_DOMAIN_IO,
3051
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
3052
0
       "%s: unable to write third header section.",
3053
0
       function );
3054
3055
0
      goto on_error;
3056
0
    }
3057
0
    total_write_count += write_count;
3058
0
  }
3059
0
  if( libewf_header_sections_free(
3060
0
       &header_sections,
3061
0
       error ) != 1 )
3062
0
  {
3063
0
    libcerror_error_set(
3064
0
     error,
3065
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3066
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3067
0
     "%s: unable to free header sections.",
3068
0
     function );
3069
3070
0
    goto on_error;
3071
0
  }
3072
0
  return( total_write_count );
3073
3074
0
on_error:
3075
0
  if( header_sections != NULL )
3076
0
  {
3077
0
    libewf_header_sections_free(
3078
0
     &header_sections,
3079
0
     NULL );
3080
0
  }
3081
0
  return( -1 );
3082
0
}
3083
3084
/* Write the last section at the end of the segment file
3085
 * Returns the number of bytes written or -1 on error
3086
 */
3087
ssize_t libewf_segment_file_write_last_section(
3088
         libewf_segment_file_t *segment_file,
3089
         libbfio_pool_t *file_io_pool,
3090
         int file_io_pool_entry,
3091
         int last_segment_file,
3092
         libcerror_error_t **error )
3093
0
{
3094
0
  libewf_section_descriptor_t *section_descriptor = NULL;
3095
0
  uint8_t *section_type_string                    = NULL;
3096
0
  static char *function                           = "libewf_segment_file_write_last_section";
3097
0
  size_t section_descriptor_data_size             = 0;
3098
0
  size_t section_size                             = 0;
3099
0
  size_t section_type_string_length               = 0;
3100
0
  ssize_t write_count                             = 0;
3101
0
  uint32_t section_type                           = 0;
3102
0
  int element_index                               = 0;
3103
3104
0
  if( segment_file == NULL )
3105
0
  {
3106
0
    libcerror_error_set(
3107
0
     error,
3108
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3109
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3110
0
     "%s: invalid segment file.",
3111
0
     function );
3112
3113
0
    return( -1 );
3114
0
  }
3115
0
  if( ( segment_file->type != LIBEWF_SEGMENT_FILE_TYPE_EWF2 )
3116
0
   && ( segment_file->type != LIBEWF_SEGMENT_FILE_TYPE_EWF2_LOGICAL ) )
3117
0
  {
3118
0
    section_descriptor_data_size = sizeof( ewf_section_descriptor_v1_t );
3119
0
  }
3120
0
  else
3121
0
  {
3122
0
    section_descriptor_data_size = sizeof( ewf_section_descriptor_v2_t );
3123
0
  }
3124
0
  if( last_segment_file == 0 )
3125
0
  {
3126
0
    section_type               = LIBEWF_SECTION_TYPE_NEXT;
3127
0
    section_type_string        = (uint8_t *) "next";
3128
0
    section_type_string_length = 4;
3129
0
  }
3130
0
  else
3131
0
  {
3132
0
    section_type               = LIBEWF_SECTION_TYPE_DONE;
3133
0
    section_type_string        = (uint8_t *) "done";
3134
0
    section_type_string_length = 4;
3135
0
  }
3136
  /* The version 1 EWF-E01 and EWF-L01 formats leave the size of this section empty
3137
   */
3138
0
  if( ( segment_file->type != LIBEWF_SEGMENT_FILE_TYPE_EWF1 )
3139
0
   && ( segment_file->type != LIBEWF_SEGMENT_FILE_TYPE_EWF1_LOGICAL ) )
3140
0
  {
3141
0
    section_size = section_descriptor_data_size;
3142
0
  }
3143
  /* Write next or done section
3144
   */
3145
0
  if( libewf_section_descriptor_initialize(
3146
0
       &section_descriptor,
3147
0
       error ) != 1 )
3148
0
  {
3149
0
    libcerror_error_set(
3150
0
     error,
3151
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3152
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3153
0
     "%s: unable to create section descriptor.",
3154
0
     function );
3155
3156
0
    goto on_error;
3157
0
  }
3158
0
  if( libewf_section_descriptor_set(
3159
0
       section_descriptor,
3160
0
       section_type,
3161
0
       section_type_string,
3162
0
       section_type_string_length,
3163
0
       segment_file->current_offset,
3164
0
       section_size,
3165
0
       0,
3166
0
       0,
3167
0
       error ) != 1 )
3168
0
  {
3169
0
    libcerror_error_set(
3170
0
     error,
3171
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3172
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3173
0
     "%s: unable to set section descriptor.",
3174
0
     function );
3175
3176
0
    goto on_error;
3177
0
  }
3178
0
  write_count = libewf_section_descriptor_write_file_io_pool(
3179
0
                 section_descriptor,
3180
0
                 file_io_pool,
3181
0
                 file_io_pool_entry,
3182
0
                 segment_file->major_version,
3183
0
                 error );
3184
3185
0
  if( write_count != (ssize_t) section_descriptor_data_size )
3186
0
  {
3187
0
    libcerror_error_set(
3188
0
     error,
3189
0
     LIBCERROR_ERROR_DOMAIN_IO,
3190
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
3191
0
     "%s: unable to write section descriptor data.",
3192
0
     function );
3193
3194
0
    goto on_error;
3195
0
  }
3196
0
  if( libfdata_list_append_element(
3197
0
       segment_file->sections_list,
3198
0
       &element_index,
3199
0
       file_io_pool_entry,
3200
0
       segment_file->current_offset,
3201
0
       (size64_t) write_count,
3202
0
       0,
3203
0
       error ) != 1 )
3204
0
  {
3205
0
    libcerror_error_set(
3206
0
     error,
3207
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3208
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
3209
0
     "%s: unable to append element to sections list.",
3210
0
     function );
3211
3212
0
    goto on_error;
3213
0
  }
3214
0
  segment_file->current_offset += write_count;
3215
3216
0
  if( libewf_section_descriptor_free(
3217
0
       &section_descriptor,
3218
0
       error ) != 1 )
3219
0
  {
3220
0
    libcerror_error_set(
3221
0
     error,
3222
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3223
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3224
0
     "%s: unable to free section.",
3225
0
     function );
3226
3227
0
    goto on_error;
3228
0
  }
3229
0
  return( write_count );
3230
3231
0
on_error:
3232
0
  if( section_descriptor != NULL )
3233
0
  {
3234
0
    libewf_section_descriptor_free(
3235
0
     &section_descriptor,
3236
0
     NULL );
3237
0
  }
3238
0
  return( -1 );
3239
0
}
3240
3241
/* Write the necessary sections at the start of the segment file
3242
 * Returns the number of bytes written or -1 on error
3243
 */
3244
ssize_t libewf_segment_file_write_start(
3245
         libewf_segment_file_t *segment_file,
3246
         libbfio_pool_t *file_io_pool,
3247
         int file_io_pool_entry,
3248
         uint8_t **case_data,
3249
         size_t *case_data_size,
3250
         uint8_t **device_information,
3251
         size_t *device_information_size,
3252
         ewf_data_t **data_section_descriptor,
3253
         libewf_media_values_t *media_values,
3254
         libfvalue_table_t *header_values,
3255
         time_t timestamp,
3256
         libcerror_error_t **error )
3257
0
{
3258
0
  libewf_section_descriptor_t *section_descriptor = NULL;
3259
0
  static char *function                           = "libewf_segment_file_write_start";
3260
0
  ssize_t total_write_count                       = 0;
3261
0
  ssize_t write_count                             = 0;
3262
0
  int element_index                               = 0;
3263
3264
0
  if( segment_file == NULL )
3265
0
  {
3266
0
    libcerror_error_set(
3267
0
     error,
3268
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3269
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3270
0
     "%s: invalid segment file.",
3271
0
     function );
3272
3273
0
    return( -1 );
3274
0
  }
3275
0
  write_count = libewf_segment_file_write_file_header(
3276
0
                 segment_file,
3277
0
                 file_io_pool,
3278
0
                 file_io_pool_entry,
3279
0
                 error );
3280
3281
0
  if( write_count == -1 )
3282
0
  {
3283
0
    libcerror_error_set(
3284
0
     error,
3285
0
     LIBCERROR_ERROR_DOMAIN_IO,
3286
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
3287
0
     "%s: unable to write file header.",
3288
0
     function );
3289
3290
0
    goto on_error;
3291
0
  }
3292
0
  total_write_count += write_count;
3293
3294
0
  if( ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1 )
3295
0
   || ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART ) )
3296
0
  {
3297
0
    if( segment_file->segment_number == 1 )
3298
0
    {
3299
0
      write_count = libewf_segment_file_write_header_sections(
3300
0
               segment_file,
3301
0
               file_io_pool,
3302
0
               file_io_pool_entry,
3303
0
               header_values,
3304
0
               timestamp,
3305
0
                     error );
3306
3307
0
      if( write_count == -1 )
3308
0
      {
3309
0
        libcerror_error_set(
3310
0
         error,
3311
0
         LIBCERROR_ERROR_DOMAIN_IO,
3312
0
         LIBCERROR_IO_ERROR_WRITE_FAILED,
3313
0
         "%s: unable to write header sections.",
3314
0
         function );
3315
3316
0
        goto on_error;
3317
0
      }
3318
0
      total_write_count += write_count;
3319
0
    }
3320
0
    if( libewf_section_descriptor_initialize(
3321
0
         &section_descriptor,
3322
0
         error ) != 1 )
3323
0
    {
3324
0
      libcerror_error_set(
3325
0
       error,
3326
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3327
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3328
0
       "%s: unable to create section descriptor.",
3329
0
       function );
3330
3331
0
      goto on_error;
3332
0
    }
3333
0
    if( segment_file->segment_number == 1 )
3334
0
    {
3335
0
      write_count = -1;
3336
3337
0
      if( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1 )
3338
0
      {
3339
0
        write_count = libewf_volume_section_e01_write_file_io_pool(
3340
0
                 section_descriptor,
3341
0
                 segment_file->io_handle,
3342
0
                 file_io_pool,
3343
0
                 file_io_pool_entry,
3344
0
                 segment_file->current_offset,
3345
0
                 media_values,
3346
0
                       error );
3347
0
      }
3348
0
      else if( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
3349
0
      {
3350
0
        write_count = libewf_volume_section_s01_write_file_io_pool(
3351
0
                 section_descriptor,
3352
0
                 segment_file->io_handle,
3353
0
                 file_io_pool,
3354
0
                 file_io_pool_entry,
3355
0
                 segment_file->current_offset,
3356
0
                 media_values,
3357
0
                       error );
3358
0
      }
3359
0
      if( write_count == -1 )
3360
0
      {
3361
0
        libcerror_error_set(
3362
0
         error,
3363
0
         LIBCERROR_ERROR_DOMAIN_IO,
3364
0
         LIBCERROR_IO_ERROR_WRITE_FAILED,
3365
0
         "%s: unable to write volume section.",
3366
0
         function );
3367
3368
0
        goto on_error;
3369
0
      }
3370
0
    }
3371
0
    else if( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1 )
3372
0
    {
3373
0
      write_count = libewf_section_data_write(
3374
0
               section_descriptor,
3375
0
               segment_file->io_handle,
3376
0
               file_io_pool,
3377
0
               file_io_pool_entry,
3378
0
               segment_file->current_offset,
3379
0
               media_values,
3380
0
               data_section_descriptor,
3381
0
                     error );
3382
3383
0
      if( write_count == -1 )
3384
0
      {
3385
0
        libcerror_error_set(
3386
0
         error,
3387
0
         LIBCERROR_ERROR_DOMAIN_IO,
3388
0
         LIBCERROR_IO_ERROR_WRITE_FAILED,
3389
0
         "%s: unable to write data section.",
3390
0
         function );
3391
3392
0
        goto on_error;
3393
0
      }
3394
0
    }
3395
0
    else
3396
0
    {
3397
0
      write_count = 0;
3398
0
    }
3399
0
    if( write_count > 0 )
3400
0
    {
3401
0
      if( libfdata_list_append_element(
3402
0
           segment_file->sections_list,
3403
0
           &element_index,
3404
0
           file_io_pool_entry,
3405
0
           segment_file->current_offset,
3406
0
           sizeof( ewf_section_descriptor_v1_t ),
3407
0
           0,
3408
0
           error ) != 1 )
3409
0
      {
3410
0
        libcerror_error_set(
3411
0
         error,
3412
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3413
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
3414
0
         "%s: unable to append element to sections list.",
3415
0
         function );
3416
3417
0
        goto on_error;
3418
0
      }
3419
0
      segment_file->current_offset += write_count;
3420
0
      total_write_count            += write_count;
3421
0
    }
3422
0
    if( libewf_section_descriptor_free(
3423
0
         &section_descriptor,
3424
0
         error ) != 1 )
3425
0
    {
3426
0
      libcerror_error_set(
3427
0
       error,
3428
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3429
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3430
0
       "%s: unable to free section.",
3431
0
       function );
3432
3433
0
      goto on_error;
3434
0
    }
3435
0
  }
3436
0
  else if( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF2 )
3437
0
  {
3438
0
    write_count = libewf_segment_file_write_device_information_section(
3439
0
             segment_file,
3440
0
             file_io_pool,
3441
0
             file_io_pool_entry,
3442
0
             device_information,
3443
0
             device_information_size,
3444
0
             media_values,
3445
0
             header_values,
3446
0
             error );
3447
3448
0
    if( write_count == -1 )
3449
0
    {
3450
0
      libcerror_error_set(
3451
0
       error,
3452
0
       LIBCERROR_ERROR_DOMAIN_IO,
3453
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
3454
0
       "%s: unable to write device information section.",
3455
0
       function );
3456
3457
0
      goto on_error;
3458
0
    }
3459
0
    total_write_count += write_count;
3460
3461
0
    write_count = libewf_segment_file_write_case_data_section(
3462
0
             segment_file,
3463
0
             file_io_pool,
3464
0
             file_io_pool_entry,
3465
0
             case_data,
3466
0
             case_data_size,
3467
0
             media_values,
3468
0
             header_values,
3469
0
             timestamp,
3470
0
             error );
3471
3472
0
    if( write_count == -1 )
3473
0
    {
3474
0
      libcerror_error_set(
3475
0
       error,
3476
0
       LIBCERROR_ERROR_DOMAIN_IO,
3477
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
3478
0
       "%s: unable to write case data section.",
3479
0
       function );
3480
3481
0
      goto on_error;
3482
0
    }
3483
0
    total_write_count += write_count;
3484
0
  }
3485
0
  return( total_write_count );
3486
3487
0
on_error:
3488
0
  if( section_descriptor != NULL )
3489
0
  {
3490
0
    libewf_section_descriptor_free(
3491
0
     &section_descriptor,
3492
0
     NULL );
3493
0
  }
3494
0
  return( -1 );
3495
0
}
3496
3497
/* Write the necessary sections before the actual data chunks to file
3498
 * Returns the number of bytes written or -1 on error
3499
 */
3500
ssize_t libewf_segment_file_write_chunks_section_start(
3501
         libewf_segment_file_t *segment_file,
3502
         libbfio_pool_t *file_io_pool,
3503
         int file_io_pool_entry,
3504
         uint8_t *table_section_data,
3505
         size_t table_section_data_size,
3506
         uint8_t *table_entries_data,
3507
         size_t table_entries_data_size,
3508
         uint32_t number_of_table_entries,
3509
         uint64_t number_of_chunks_written,
3510
         libcerror_error_t **error )
3511
0
{
3512
0
  libewf_section_descriptor_t *section_descriptor = NULL;
3513
0
  libewf_table_section_t *table_section           = NULL;
3514
0
  static char *function                           = "libewf_segment_file_write_chunks_section_start";
3515
0
  ssize_t write_count                             = 0;
3516
3517
0
  if( segment_file == NULL )
3518
0
  {
3519
0
    libcerror_error_set(
3520
0
     error,
3521
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3522
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3523
0
     "%s: invalid segment file.",
3524
0
     function );
3525
3526
0
    return( -1 );
3527
0
  }
3528
0
  if( segment_file->io_handle == NULL )
3529
0
  {
3530
0
    libcerror_error_set(
3531
0
     error,
3532
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3533
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3534
0
     "%s: invalid segment file - missing IO handle.",
3535
0
     function );
3536
3537
0
    return( -1 );
3538
0
  }
3539
0
  if( ( segment_file->type != LIBEWF_SEGMENT_FILE_TYPE_EWF1 )
3540
0
   && ( segment_file->type != LIBEWF_SEGMENT_FILE_TYPE_EWF1_LOGICAL )
3541
0
   && ( segment_file->type != LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART ) )
3542
0
  {
3543
0
    libcerror_error_set(
3544
0
     error,
3545
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3546
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3547
0
     "%s: invalid segment file - unsupported type.",
3548
0
     function );
3549
3550
0
    return( -1 );
3551
0
  }
3552
0
  if( ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
3553
0
   || ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE1 ) )
3554
0
  {
3555
0
    if( libewf_table_section_initialize(
3556
0
         &table_section,
3557
0
         error ) != 1 )
3558
0
    {
3559
0
      libcerror_error_set(
3560
0
       error,
3561
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3562
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3563
0
       "%s: unable to create table section.",
3564
0
       function );
3565
3566
0
      goto on_error;
3567
0
    }
3568
0
    table_section->first_chunk_index = number_of_chunks_written;
3569
0
    table_section->base_offset       = 0;
3570
0
    table_section->number_of_entries = number_of_table_entries;
3571
0
    table_section->section_data      = table_section_data;
3572
0
    table_section->section_data_size = table_section_data_size;
3573
3574
    /* Write table section descriptor
3575
     */
3576
0
    write_count = libewf_table_section_write_file_io_pool(
3577
0
                   table_section,
3578
0
                   segment_file->io_handle,
3579
0
                   file_io_pool,
3580
0
                   file_io_pool_entry,
3581
0
                   1,
3582
0
                   segment_file->type,
3583
0
                   (uint8_t *) "table",
3584
0
                   5,
3585
0
                   segment_file->current_offset,
3586
0
                   table_entries_data,
3587
0
                   table_entries_data_size,
3588
0
                   0,
3589
0
                   error );
3590
3591
0
    table_section->section_data      = NULL;
3592
0
    table_section->section_data_size = 0;
3593
3594
0
    if( write_count == -1 )
3595
0
    {
3596
0
      libcerror_error_set(
3597
0
       error,
3598
0
       LIBCERROR_ERROR_DOMAIN_IO,
3599
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
3600
0
       "%s: unable to write table section.",
3601
0
       function );
3602
3603
0
      goto on_error;
3604
0
    }
3605
0
    if( libewf_table_section_free(
3606
0
         &table_section,
3607
0
         error ) != 1 )
3608
0
    {
3609
0
      libcerror_error_set(
3610
0
       error,
3611
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3612
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3613
0
       "%s: unable to free table section.",
3614
0
       function );
3615
3616
0
      goto on_error;
3617
0
    }
3618
0
  }
3619
0
  else if( ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1 )
3620
0
        || ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_LOGICAL ) )
3621
0
  {
3622
0
    if( libewf_section_descriptor_initialize(
3623
0
         &section_descriptor,
3624
0
         error ) != 1 )
3625
0
    {
3626
0
      libcerror_error_set(
3627
0
       error,
3628
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3629
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3630
0
       "%s: unable to create section descriptor.",
3631
0
       function );
3632
3633
0
      goto on_error;
3634
0
    }
3635
0
    write_count = libewf_section_sectors_write(
3636
0
                   section_descriptor,
3637
0
                   file_io_pool,
3638
0
                   file_io_pool_entry,
3639
0
                   1,
3640
0
                   segment_file->current_offset,
3641
0
                   0,
3642
0
                   0,
3643
0
                   error );
3644
3645
0
    if( write_count == -1 )
3646
0
    {
3647
0
      libcerror_error_set(
3648
0
       error,
3649
0
       LIBCERROR_ERROR_DOMAIN_IO,
3650
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
3651
0
       "%s: unable to write sectors section.",
3652
0
       function );
3653
3654
0
      goto on_error;
3655
0
    }
3656
0
    if( libewf_section_descriptor_free(
3657
0
         &section_descriptor,
3658
0
         error ) != 1 )
3659
0
    {
3660
0
      libcerror_error_set(
3661
0
       error,
3662
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3663
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3664
0
       "%s: unable to free section.",
3665
0
       function );
3666
3667
0
      goto on_error;
3668
0
    }
3669
0
  }
3670
0
  segment_file->current_offset += write_count;
3671
3672
0
  return( write_count );
3673
3674
0
on_error:
3675
0
  if( section_descriptor != NULL )
3676
0
  {
3677
0
    libewf_section_descriptor_free(
3678
0
     &section_descriptor,
3679
0
     NULL );
3680
0
  }
3681
0
  if( table_section != NULL )
3682
0
  {
3683
0
    libewf_table_section_free(
3684
0
     &table_section,
3685
0
     NULL );
3686
0
  }
3687
0
  return( -1 );
3688
0
}
3689
3690
/* Write the necessary sections after the actual data chunks to file
3691
 * If necessary the sections before the actual data chunks are corrected
3692
 * Returns the number of bytes written or -1 on error
3693
 */
3694
ssize_t libewf_segment_file_write_chunks_section_end(
3695
         libewf_segment_file_t *segment_file,
3696
         libbfio_pool_t *file_io_pool,
3697
         int file_io_pool_entry,
3698
         uint8_t *table_section_data,
3699
         size_t table_section_data_size,
3700
         uint8_t *table_entries_data,
3701
         size_t table_entries_data_size,
3702
         uint32_t number_of_table_entries,
3703
         off64_t chunks_section_offset,
3704
         size64_t chunks_section_size,
3705
         uint32_t chunks_section_padding_size,
3706
         uint64_t first_chunk_index,
3707
         uint64_t base_offset,
3708
         libcerror_error_t **error )
3709
0
{
3710
0
  libewf_section_descriptor_t *section_descriptor = NULL;
3711
0
  libewf_table_section_t *table_section           = NULL;
3712
0
  static char *function                           = "libewf_segment_file_write_chunks_section_end";
3713
0
  size64_t maximum_chunks_section_size            = 0;
3714
0
  ssize_t total_write_count                       = 0;
3715
0
  ssize_t write_count                             = 0;
3716
0
  int element_index                               = 0;
3717
0
  int result                                      = 0;
3718
3719
0
  if( segment_file == NULL )
3720
0
  {
3721
0
    libcerror_error_set(
3722
0
     error,
3723
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3724
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3725
0
     "%s: invalid segment file.",
3726
0
     function );
3727
3728
0
    return( -1 );
3729
0
  }
3730
0
  if( segment_file->io_handle == NULL )
3731
0
  {
3732
0
    libcerror_error_set(
3733
0
     error,
3734
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3735
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3736
0
     "%s: invalid segment file - missing IO handle.",
3737
0
     function );
3738
3739
0
    return( -1 );
3740
0
  }
3741
/* TODO what about linen 7 */
3742
0
  if( ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE6 )
3743
0
   || ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE7 )
3744
0
   || ( segment_file->io_handle->format == LIBEWF_FORMAT_V2_ENCASE7 ) )
3745
0
  {
3746
0
    maximum_chunks_section_size = (size64_t) INT64_MAX;
3747
0
  }
3748
0
  else
3749
0
  {
3750
0
    maximum_chunks_section_size = (size64_t) INT32_MAX;
3751
0
  }
3752
0
  if( chunks_section_size >= maximum_chunks_section_size )
3753
0
  {
3754
0
    libcerror_error_set(
3755
0
     error,
3756
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3757
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
3758
0
     "%s: invalid chunk section size value exceeds maximum.",
3759
0
     function );
3760
3761
0
    return( -1 );
3762
0
  }
3763
0
  if( libewf_section_descriptor_initialize(
3764
0
       &section_descriptor,
3765
0
       error ) != 1 )
3766
0
  {
3767
0
    libcerror_error_set(
3768
0
     error,
3769
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3770
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3771
0
     "%s: unable to create section descriptor.",
3772
0
     function );
3773
3774
0
    goto on_error;
3775
0
  }
3776
  /* The EWF version 1 format requires the chunks section descriptor to
3777
   * be corrected in EWF version 2 the section descriptor is added to
3778
   * the end of the section
3779
   */
3780
0
  if( ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1 )
3781
0
   || ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_LOGICAL )
3782
0
   || ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART ) )
3783
0
  {
3784
#if defined( HAVE_DEBUG_OUTPUT )
3785
    if( libcnotify_verbose != 0 )
3786
    {
3787
      libcnotify_printf(
3788
       "%s: setting file descriptor to start of chunks section offset: %" PRIi64 ".\n",
3789
       function,
3790
       chunks_section_offset );
3791
    }
3792
#endif
3793
    /* Seek the start of the chunks section
3794
     */
3795
0
    if( libbfio_pool_seek_offset(
3796
0
         file_io_pool,
3797
0
         file_io_pool_entry,
3798
0
         chunks_section_offset,
3799
0
         SEEK_SET,
3800
0
         error ) == -1 )
3801
0
    {
3802
0
      libcerror_error_set(
3803
0
       error,
3804
0
       LIBCERROR_ERROR_DOMAIN_IO,
3805
0
       LIBCERROR_IO_ERROR_SEEK_FAILED,
3806
0
       "%s: unable to find offset to correct sectors size.",
3807
0
       function );
3808
3809
0
      goto on_error;
3810
0
    }
3811
0
    if( ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
3812
0
     || ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE1 ) )
3813
0
    {
3814
#if defined( HAVE_DEBUG_OUTPUT )
3815
      if( libcnotify_verbose != 0 )
3816
      {
3817
        libcnotify_printf(
3818
         "%s: correcting table section offset: %" PRIi64 " size: %" PRIu64 ".\n",
3819
         function,
3820
         chunks_section_offset,
3821
         chunks_section_size );
3822
      }
3823
#endif
3824
0
      if( libewf_table_section_initialize(
3825
0
           &table_section,
3826
0
           error ) != 1 )
3827
0
      {
3828
0
        libcerror_error_set(
3829
0
         error,
3830
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3831
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3832
0
         "%s: unable to create table section.",
3833
0
         function );
3834
3835
0
        goto on_error;
3836
0
      }
3837
0
      table_section->first_chunk_index = first_chunk_index;
3838
0
      table_section->base_offset       = 0;
3839
0
      table_section->number_of_entries = number_of_table_entries;
3840
0
      table_section->section_data      = table_section_data;
3841
0
      table_section->section_data_size = table_section_data_size;
3842
3843
      /* Rewrite table section descriptor
3844
       */
3845
0
      write_count = libewf_table_section_write_file_io_pool(
3846
0
               table_section,
3847
0
               segment_file->io_handle,
3848
0
               file_io_pool,
3849
0
               file_io_pool_entry,
3850
0
               1,
3851
0
               segment_file->type,
3852
0
               (uint8_t *) "table",
3853
0
               5,
3854
0
               chunks_section_offset,
3855
0
               table_entries_data,
3856
0
               table_entries_data_size,
3857
0
               chunks_section_size,
3858
0
               error );
3859
3860
0
      table_section->section_data      = NULL;
3861
0
      table_section->section_data_size = 0;
3862
3863
0
      if( write_count == -1 )
3864
0
      {
3865
0
        libcerror_error_set(
3866
0
         error,
3867
0
         LIBCERROR_ERROR_DOMAIN_IO,
3868
0
         LIBCERROR_IO_ERROR_WRITE_FAILED,
3869
0
         "%s: unable to write table section.",
3870
0
         function );
3871
3872
0
        goto on_error;
3873
0
      }
3874
0
      if( libewf_table_section_free(
3875
0
           &table_section,
3876
0
           error ) != 1 )
3877
0
      {
3878
0
        libcerror_error_set(
3879
0
         error,
3880
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3881
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3882
0
         "%s: unable to free table section.",
3883
0
         function );
3884
3885
0
        goto on_error;
3886
0
      }
3887
0
    }
3888
0
    else if( ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1 )
3889
0
          || ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_LOGICAL ) )
3890
0
    {
3891
#if defined( HAVE_DEBUG_OUTPUT )
3892
      if( libcnotify_verbose != 0 )
3893
      {
3894
        libcnotify_printf(
3895
        "%s: correcting sectors section offset: %" PRIi64 " size: %" PRIu64 ".\n",
3896
         function,
3897
         chunks_section_offset,
3898
         chunks_section_size );
3899
      }
3900
#endif
3901
0
      write_count = libewf_section_sectors_write(
3902
0
               section_descriptor,
3903
0
               file_io_pool,
3904
0
               file_io_pool_entry,
3905
0
               1,
3906
0
               chunks_section_offset,
3907
0
               chunks_section_size,
3908
0
               0,
3909
0
               error );
3910
3911
0
      if( write_count == -1 )
3912
0
      {
3913
0
        libcerror_error_set(
3914
0
         error,
3915
0
         LIBCERROR_ERROR_DOMAIN_IO,
3916
0
         LIBCERROR_IO_ERROR_WRITE_FAILED,
3917
0
         "%s: unable to write sectors section.",
3918
0
         function );
3919
3920
0
        goto on_error;
3921
0
      }
3922
0
    }
3923
0
    if( libfdata_list_append_element(
3924
0
         segment_file->sections_list,
3925
0
         &element_index,
3926
0
         file_io_pool_entry,
3927
0
         chunks_section_offset,
3928
0
         sizeof( ewf_section_descriptor_v1_t ),
3929
0
         0,
3930
0
         error ) != 1 )
3931
0
    {
3932
0
      libcerror_error_set(
3933
0
       error,
3934
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3935
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
3936
0
       "%s: unable to append element to sections list.",
3937
0
       function );
3938
3939
0
      goto on_error;
3940
0
    }
3941
#if defined( HAVE_DEBUG_OUTPUT )
3942
    if( libcnotify_verbose != 0 )
3943
    {
3944
      libcnotify_printf(
3945
       "%s: setting file descriptor back to end of data at offset: 0x%08" PRIx64 ".\n",
3946
       function,
3947
       segment_file->current_offset );
3948
    }
3949
#endif
3950
0
    if( libbfio_pool_seek_offset(
3951
0
         file_io_pool,
3952
0
         file_io_pool_entry,
3953
0
         segment_file->current_offset,
3954
0
         SEEK_SET,
3955
0
         error ) == -1 )
3956
0
    {
3957
0
      libcerror_error_set(
3958
0
       error,
3959
0
       LIBCERROR_ERROR_DOMAIN_IO,
3960
0
       LIBCERROR_IO_ERROR_SEEK_FAILED,
3961
0
       "%s: unable to find offset to continue.",
3962
0
       function );
3963
3964
0
      goto on_error;
3965
0
    }
3966
0
  }
3967
0
  else
3968
0
  {
3969
0
    write_count = libewf_section_sectors_write(
3970
0
                   section_descriptor,
3971
0
                   file_io_pool,
3972
0
                   file_io_pool_entry,
3973
0
                   2,
3974
0
                   chunks_section_offset,
3975
0
                   chunks_section_size,
3976
0
                   chunks_section_padding_size,
3977
0
                   error );
3978
3979
0
    if( write_count == -1 )
3980
0
    {
3981
0
      libcerror_error_set(
3982
0
       error,
3983
0
       LIBCERROR_ERROR_DOMAIN_IO,
3984
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
3985
0
       "%s: unable to write sectors data section.",
3986
0
       function );
3987
3988
0
      goto on_error;
3989
0
    }
3990
0
    segment_file->current_offset += write_count;
3991
0
    total_write_count            += write_count;
3992
3993
0
    if( libfdata_list_append_element(
3994
0
         segment_file->sections_list,
3995
0
         &element_index,
3996
0
         file_io_pool_entry,
3997
0
         segment_file->current_offset - sizeof( ewf_section_descriptor_v2_t ),
3998
0
         sizeof( ewf_section_descriptor_v2_t ),
3999
0
         0,
4000
0
         error ) != 1 )
4001
0
    {
4002
0
      libcerror_error_set(
4003
0
       error,
4004
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4005
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
4006
0
       "%s: unable to append element to sections list.",
4007
0
       function );
4008
4009
0
      goto on_error;
4010
0
    }
4011
0
  }
4012
0
  if( libewf_section_descriptor_free(
4013
0
       &section_descriptor,
4014
0
       error ) != 1 )
4015
0
  {
4016
0
    libcerror_error_set(
4017
0
     error,
4018
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4019
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4020
0
     "%s: unable to free section.",
4021
0
     function );
4022
4023
0
    goto on_error;
4024
0
  }
4025
0
  if( ( segment_file->type != LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
4026
0
   && ( segment_file->io_handle->format != LIBEWF_FORMAT_ENCASE1 ) )
4027
0
  {
4028
0
    if( libewf_table_section_initialize(
4029
0
         &table_section,
4030
0
         error ) != 1 )
4031
0
    {
4032
0
      libcerror_error_set(
4033
0
       error,
4034
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4035
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4036
0
       "%s: unable to create table section.",
4037
0
       function );
4038
4039
0
      goto on_error;
4040
0
    }
4041
0
    table_section->first_chunk_index = first_chunk_index;
4042
0
    table_section->base_offset       = base_offset;
4043
0
    table_section->number_of_entries = number_of_table_entries;
4044
0
    table_section->section_data      = table_section_data;
4045
0
    table_section->section_data_size = table_section_data_size;
4046
4047
0
    write_count = libewf_table_section_write_file_io_pool(
4048
0
                   table_section,
4049
0
                   segment_file->io_handle,
4050
0
                   file_io_pool,
4051
0
                   file_io_pool_entry,
4052
0
                   segment_file->major_version,
4053
0
                   segment_file->type,
4054
0
                   (uint8_t *) "table",
4055
0
                   5,
4056
0
                   segment_file->current_offset,
4057
0
                   table_entries_data,
4058
0
                   table_entries_data_size,
4059
0
                   0,
4060
0
                   error );
4061
4062
0
    table_section->section_data      = NULL;
4063
0
    table_section->section_data_size = 0;
4064
4065
0
    if( write_count == -1 )
4066
0
    {
4067
0
      libcerror_error_set(
4068
0
       error,
4069
0
       LIBCERROR_ERROR_DOMAIN_IO,
4070
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
4071
0
       "%s: unable to write sector table section.",
4072
0
       function );
4073
4074
0
      goto on_error;
4075
0
    }
4076
0
    if( libewf_table_section_free(
4077
0
         &table_section,
4078
0
         error ) != 1 )
4079
0
    {
4080
0
      libcerror_error_set(
4081
0
       error,
4082
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4083
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4084
0
       "%s: unable to free table section.",
4085
0
       function );
4086
4087
0
      goto on_error;
4088
0
    }
4089
0
    if( segment_file->major_version == 1 )
4090
0
    {
4091
0
      result = libfdata_list_append_element(
4092
0
                segment_file->sections_list,
4093
0
                &element_index,
4094
0
                file_io_pool_entry,
4095
0
                segment_file->current_offset,
4096
0
                sizeof( ewf_section_descriptor_v1_t ),
4097
0
                0,
4098
0
                error );
4099
0
    }
4100
0
    segment_file->current_offset += write_count;
4101
0
    total_write_count            += write_count;
4102
4103
0
    if( segment_file->major_version == 2 )
4104
0
    {
4105
0
      result = libfdata_list_append_element(
4106
0
                segment_file->sections_list,
4107
0
                &element_index,
4108
0
                file_io_pool_entry,
4109
0
                segment_file->current_offset - sizeof( ewf_section_descriptor_v2_t ),
4110
0
                sizeof( ewf_section_descriptor_v2_t ),
4111
0
                0,
4112
0
                error );
4113
0
    }
4114
0
    if( result != 1 )
4115
0
    {
4116
0
      libcerror_error_set(
4117
0
       error,
4118
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4119
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
4120
0
       "%s: unable to append element to sections list.",
4121
0
       function );
4122
4123
0
      goto on_error;
4124
0
    }
4125
0
  }
4126
0
  if( ( ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1 )
4127
0
    ||  ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_LOGICAL ) )
4128
0
   && ( segment_file->io_handle->format != LIBEWF_FORMAT_ENCASE1 ) )
4129
0
  {
4130
0
    if( libewf_table_section_initialize(
4131
0
         &table_section,
4132
0
         error ) != 1 )
4133
0
    {
4134
0
      libcerror_error_set(
4135
0
       error,
4136
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4137
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4138
0
       "%s: unable to create table section.",
4139
0
       function );
4140
4141
0
      goto on_error;
4142
0
    }
4143
0
    table_section->first_chunk_index = first_chunk_index;
4144
0
    table_section->base_offset       = base_offset;
4145
0
    table_section->number_of_entries = number_of_table_entries;
4146
0
    table_section->section_data      = table_section_data;
4147
0
    table_section->section_data_size = table_section_data_size;
4148
4149
0
    write_count = libewf_table_section_write_file_io_pool(
4150
0
                   table_section,
4151
0
                   segment_file->io_handle,
4152
0
                   file_io_pool,
4153
0
                   file_io_pool_entry,
4154
0
                   1,
4155
0
                   segment_file->type,
4156
0
                   (uint8_t *) "table2",
4157
0
                   6,
4158
0
                   segment_file->current_offset,
4159
0
                   table_entries_data,
4160
0
                   table_entries_data_size,
4161
0
                   0,
4162
0
                   error );
4163
4164
0
    table_section->section_data      = NULL;
4165
0
    table_section->section_data_size = 0;
4166
4167
0
    if( write_count == -1 )
4168
0
    {
4169
0
      libcerror_error_set(
4170
0
       error,
4171
0
       LIBCERROR_ERROR_DOMAIN_IO,
4172
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
4173
0
       "%s: unable to write table2 section.",
4174
0
       function );
4175
4176
0
      goto on_error;
4177
0
    }
4178
0
    if( libewf_table_section_free(
4179
0
         &table_section,
4180
0
         error ) != 1 )
4181
0
    {
4182
0
      libcerror_error_set(
4183
0
       error,
4184
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4185
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4186
0
       "%s: unable to free table section.",
4187
0
       function );
4188
4189
0
      goto on_error;
4190
0
    }
4191
0
    if( libfdata_list_append_element(
4192
0
         segment_file->sections_list,
4193
0
         &element_index,
4194
0
         file_io_pool_entry,
4195
0
         segment_file->current_offset,
4196
0
         sizeof( ewf_section_descriptor_v1_t ),
4197
0
         0,
4198
0
         error ) != 1 )
4199
0
    {
4200
0
      libcerror_error_set(
4201
0
       error,
4202
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4203
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
4204
0
       "%s: unable to append element to sections list.",
4205
0
       function );
4206
4207
0
      goto on_error;
4208
0
    }
4209
0
    segment_file->current_offset += write_count;
4210
0
    total_write_count            += write_count;
4211
0
  }
4212
0
  return( total_write_count );
4213
4214
0
on_error:
4215
0
  if( table_section != NULL )
4216
0
  {
4217
0
    libewf_table_section_free(
4218
0
     &table_section,
4219
0
     NULL );
4220
0
  }
4221
0
  if( section_descriptor != NULL )
4222
0
  {
4223
0
    libewf_section_descriptor_free(
4224
0
     &section_descriptor,
4225
0
     NULL );
4226
0
  }
4227
0
  return( -1 );
4228
0
}
4229
4230
/* Write a chunk of data to a segment file and update the chunk table
4231
 * Returns the number of bytes written or -1 on error
4232
 */
4233
ssize_t libewf_segment_file_write_chunk_data(
4234
         libewf_segment_file_t *segment_file,
4235
         libbfio_pool_t *file_io_pool,
4236
         int file_io_pool_entry,
4237
         uint64_t chunk_index LIBEWF_ATTRIBUTE_UNUSED,
4238
         libewf_chunk_data_t *chunk_data,
4239
         libcerror_error_t **error )
4240
0
{
4241
0
  static char *function     = "libewf_segment_file_write_chunk_data";
4242
0
  ssize_t write_count       = 0;
4243
0
  uint32_t chunk_write_size = 0;
4244
4245
#if defined( HAVE_DEBUG_OUTPUT )
4246
  uint32_t chunk_checksum   = 0;
4247
  int result                = 0;
4248
#endif
4249
4250
0
  LIBEWF_UNREFERENCED_PARAMETER( chunk_index )
4251
4252
0
  if( segment_file == NULL )
4253
0
  {
4254
0
    libcerror_error_set(
4255
0
     error,
4256
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4257
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4258
0
     "%s: invalid segment file.",
4259
0
     function );
4260
4261
0
    return( -1 );
4262
0
  }
4263
0
  if( segment_file->io_handle == NULL )
4264
0
  {
4265
0
    libcerror_error_set(
4266
0
     error,
4267
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4268
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4269
0
     "%s: invalid segment file - missing IO handle.",
4270
0
     function );
4271
4272
0
    return( -1 );
4273
0
  }
4274
0
  if( chunk_data == NULL )
4275
0
  {
4276
0
    libcerror_error_set(
4277
0
     error,
4278
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4279
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4280
0
     "%s: invalid chunk data.",
4281
0
     function );
4282
4283
0
    return( -1 );
4284
0
  }
4285
/* TODO chunk data rewrite */
4286
0
  if( segment_file->io_handle->format != LIBEWF_FORMAT_SMART )
4287
0
  {
4288
0
    if( chunk_data->data_size > chunk_data->allocated_data_size )
4289
0
    {
4290
0
      libcerror_error_set(
4291
0
       error,
4292
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4293
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4294
0
       "%s: invalid chunk data size value out of bounds.",
4295
0
       function );
4296
4297
0
      return( -1 );
4298
0
    }
4299
0
  }
4300
0
  if( libewf_chunk_data_get_write_size(
4301
0
       chunk_data,
4302
0
       &chunk_write_size,
4303
0
       error ) != 1 )
4304
0
  {
4305
0
    libcerror_error_set(
4306
0
     error,
4307
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4308
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4309
0
     "%s: unable to retrieve chunk write size.",
4310
0
     function );
4311
4312
0
    return( -1 );
4313
0
  }
4314
#if defined( HAVE_DEBUG_OUTPUT )
4315
  if( libcnotify_verbose != 0 )
4316
  {
4317
    libcnotify_printf(
4318
     "%s: chunk: %05" PRIu64 " file IO pool entry\t: %d\n",
4319
     function,
4320
     chunk_index,
4321
     file_io_pool_entry );
4322
4323
    libcnotify_printf(
4324
     "%s: chunk: %05" PRIu64 " offset\t\t: %" PRIi64 " (0x%08" PRIx64 ")\n",
4325
     function,
4326
     chunk_index,
4327
     segment_file->current_offset,
4328
     segment_file->current_offset );
4329
4330
    libcnotify_printf(
4331
     "%s: chunk: %05" PRIu64 " write size\t\t: %" PRIzd "\n",
4332
     function,
4333
     chunk_index,
4334
     chunk_write_size );
4335
4336
    libcnotify_printf(
4337
     "%s: chunk: %05" PRIu64 " data size\t\t: %" PRIzd "\n",
4338
     function,
4339
     chunk_index,
4340
     chunk_data->data_size );
4341
4342
    libcnotify_printf(
4343
     "%s: chunk: %05" PRIu64 " padding size\t\t: %" PRIzd "\n",
4344
     function,
4345
     chunk_index,
4346
     chunk_data->padding_size );
4347
4348
    result = libewf_chunk_data_get_checksum(
4349
              chunk_data,
4350
              segment_file->io_handle->compression_method,
4351
              &chunk_checksum,
4352
              error );
4353
4354
    if( result == -1 )
4355
    {
4356
      libcerror_error_set(
4357
       error,
4358
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4359
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4360
       "%s: unable to retrieve chunk checksum.",
4361
       function );
4362
4363
      return( -1 );
4364
    }
4365
    libcnotify_printf(
4366
     "%s: chunk: %05" PRIu64 " checksum\t\t: ",
4367
     function,
4368
     chunk_index );
4369
4370
    if( result != 0 )
4371
    {
4372
      libcnotify_printf(
4373
       "0x%08" PRIx32 "",
4374
       chunk_checksum );
4375
    }
4376
    else
4377
    {
4378
      libcnotify_printf(
4379
       "N/A" );
4380
    }
4381
    libcnotify_printf(
4382
     "\n" );
4383
4384
    libcnotify_printf(
4385
     "%s: chunk: %05" PRIu64 " flags:\n",
4386
     function,
4387
     chunk_index );
4388
4389
    if( ( chunk_data->range_flags & LIBEWF_RANGE_FLAG_IS_COMPRESSED ) != 0 )
4390
    {
4391
      libcnotify_printf(
4392
       "\tIs compressed\n" );
4393
    }
4394
    if( ( chunk_data->range_flags & LIBEWF_RANGE_FLAG_HAS_CHECKSUM ) != 0 )
4395
    {
4396
      libcnotify_printf(
4397
       "\tHas checksum\n" );
4398
    }
4399
    if( ( chunk_data->range_flags & LIBEWF_RANGE_FLAG_USES_PATTERN_FILL ) != 0 )
4400
    {
4401
      libcnotify_printf(
4402
       "\tUses pattern fill\n" );
4403
    }
4404
    libcnotify_printf(
4405
     "\n" );
4406
  }
4407
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
4408
4409
0
  write_count = libewf_chunk_data_write(
4410
0
                 chunk_data,
4411
0
                 file_io_pool,
4412
0
                 file_io_pool_entry,
4413
0
                 error );
4414
4415
0
  if( write_count != (ssize_t) chunk_write_size )
4416
0
  {
4417
0
    libcerror_error_set(
4418
0
     error,
4419
0
     LIBCERROR_ERROR_DOMAIN_IO,
4420
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
4421
0
     "%s: unable to write chunk data.",
4422
0
     function );
4423
4424
0
    return( -1 );
4425
0
  }
4426
0
  segment_file->current_offset += write_count;
4427
4428
0
  return( write_count );
4429
0
}
4430
4431
/* Writes the hash sections to file
4432
 * Returns the number of bytes written or -1 on error
4433
 */
4434
ssize_t libewf_segment_file_write_hash_sections(
4435
         libewf_segment_file_t *segment_file,
4436
         libbfio_pool_t *file_io_pool,
4437
         int file_io_pool_entry,
4438
         libewf_hash_sections_t *hash_sections,
4439
         libfvalue_table_t *hash_values,
4440
         libcerror_error_t **error )
4441
0
{
4442
0
  libewf_section_descriptor_t *section_descriptor = NULL;
4443
0
  static char *function                           = "libewf_segment_file_write_hash_sections";
4444
0
  ssize_t total_write_count                       = 0;
4445
0
  ssize_t write_count                             = 0;
4446
0
  int element_index                               = 0;
4447
0
  int result                                      = 0;
4448
4449
0
  if( segment_file == NULL )
4450
0
  {
4451
0
    libcerror_error_set(
4452
0
     error,
4453
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4454
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4455
0
     "%s: invalid segment file.",
4456
0
     function );
4457
4458
0
    return( -1 );
4459
0
  }
4460
0
  if( segment_file->io_handle == NULL )
4461
0
  {
4462
0
    libcerror_error_set(
4463
0
     error,
4464
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4465
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4466
0
     "%s: invalid segment file - missing IO handle.",
4467
0
     function );
4468
4469
0
    return( -1 );
4470
0
  }
4471
0
  if( hash_sections == NULL )
4472
0
  {
4473
0
    libcerror_error_set(
4474
0
     error,
4475
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4476
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4477
0
     "%s: invalid hash sections.",
4478
0
     function );
4479
4480
0
    return( -1 );
4481
0
  }
4482
0
  if( ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE6 )
4483
0
   || ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE7 )
4484
0
   || ( segment_file->io_handle->format == LIBEWF_FORMAT_LINEN6 )
4485
0
   || ( segment_file->io_handle->format == LIBEWF_FORMAT_LINEN7 ) )
4486
0
  {
4487
    /* Write the digest section if required
4488
     */
4489
0
    if( hash_sections->sha1_digest_set != 0 )
4490
0
    {
4491
0
      if( libewf_section_descriptor_initialize(
4492
0
           &section_descriptor,
4493
0
           error ) != 1 )
4494
0
      {
4495
0
        libcerror_error_set(
4496
0
         error,
4497
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4498
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4499
0
         "%s: unable to create section descriptor.",
4500
0
         function );
4501
4502
0
        goto on_error;
4503
0
      }
4504
0
      write_count = libewf_digest_section_write_file_io_pool(
4505
0
               section_descriptor,
4506
0
               segment_file->io_handle,
4507
0
               file_io_pool,
4508
0
               file_io_pool_entry,
4509
0
               segment_file->current_offset,
4510
0
               hash_sections,
4511
0
               error );
4512
4513
0
      if( write_count == -1 )
4514
0
      {
4515
0
        libcerror_error_set(
4516
0
         error,
4517
0
         LIBCERROR_ERROR_DOMAIN_IO,
4518
0
         LIBCERROR_IO_ERROR_WRITE_FAILED,
4519
0
         "%s: unable to write digest section.",
4520
0
         function );
4521
4522
0
        goto on_error;
4523
0
      }
4524
0
      if( libfdata_list_append_element(
4525
0
           segment_file->sections_list,
4526
0
           &element_index,
4527
0
           file_io_pool_entry,
4528
0
           segment_file->current_offset,
4529
0
           sizeof( ewf_section_descriptor_v1_t ),
4530
0
           0,
4531
0
           error ) != 1 )
4532
0
      {
4533
0
        libcerror_error_set(
4534
0
         error,
4535
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4536
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
4537
0
         "%s: unable to append element to sections list.",
4538
0
         function );
4539
4540
0
        goto on_error;
4541
0
      }
4542
0
      segment_file->current_offset += write_count;
4543
0
      total_write_count            += write_count;
4544
4545
0
      if( libewf_section_descriptor_free(
4546
0
           &section_descriptor,
4547
0
           error ) != 1 )
4548
0
      {
4549
0
        libcerror_error_set(
4550
0
         error,
4551
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4552
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4553
0
         "%s: unable to free section.",
4554
0
         function );
4555
4556
0
        goto on_error;
4557
0
      }
4558
0
    }
4559
0
  }
4560
  /* Write the MD5 hash section if required
4561
   */
4562
0
  if( hash_sections->md5_hash_set != 0 )
4563
0
  {
4564
0
    if( libewf_section_descriptor_initialize(
4565
0
         &section_descriptor,
4566
0
         error ) != 1 )
4567
0
    {
4568
0
      libcerror_error_set(
4569
0
       error,
4570
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4571
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4572
0
       "%s: unable to create section descriptor.",
4573
0
       function );
4574
4575
0
      goto on_error;
4576
0
    }
4577
0
    write_count = libewf_md5_hash_section_write_file_io_pool(
4578
0
             section_descriptor,
4579
0
             segment_file->io_handle,
4580
0
             file_io_pool,
4581
0
             file_io_pool_entry,
4582
0
             segment_file->major_version,
4583
0
             segment_file->current_offset,
4584
0
             hash_sections,
4585
0
             error );
4586
4587
0
    if( write_count == -1 )
4588
0
    {
4589
0
      libcerror_error_set(
4590
0
       error,
4591
0
       LIBCERROR_ERROR_DOMAIN_IO,
4592
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
4593
0
       "%s: unable to write MD5 hash section.",
4594
0
       function );
4595
4596
0
      goto on_error;
4597
0
    }
4598
0
    if( segment_file->major_version == 1 )
4599
0
    {
4600
0
      result = libfdata_list_append_element(
4601
0
                segment_file->sections_list,
4602
0
                &element_index,
4603
0
                file_io_pool_entry,
4604
0
                segment_file->current_offset,
4605
0
                sizeof( ewf_section_descriptor_v1_t ),
4606
0
                0,
4607
0
                error );
4608
0
    }
4609
0
    segment_file->current_offset += write_count;
4610
0
    total_write_count            += write_count;
4611
4612
0
    if( segment_file->major_version == 2 )
4613
0
    {
4614
0
      result = libfdata_list_append_element(
4615
0
                segment_file->sections_list,
4616
0
                &element_index,
4617
0
                file_io_pool_entry,
4618
0
                segment_file->current_offset - sizeof( ewf_section_descriptor_v2_t ),
4619
0
                sizeof( ewf_section_descriptor_v2_t ),
4620
0
                0,
4621
0
                error );
4622
0
    }
4623
0
    if( result != 1 )
4624
0
    {
4625
0
      libcerror_error_set(
4626
0
       error,
4627
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4628
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
4629
0
       "%s: unable to append element to sections list.",
4630
0
       function );
4631
4632
0
      goto on_error;
4633
0
    }
4634
0
    if( libewf_section_descriptor_free(
4635
0
         &section_descriptor,
4636
0
         error ) != 1 )
4637
0
    {
4638
0
      libcerror_error_set(
4639
0
       error,
4640
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4641
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4642
0
       "%s: unable to free section.",
4643
0
       function );
4644
4645
0
      goto on_error;
4646
0
    }
4647
0
  }
4648
0
  if( segment_file->io_handle->format == LIBEWF_FORMAT_V2_ENCASE7 )
4649
0
  {
4650
    /* Write the SHA1 hash section if required
4651
     */
4652
0
    if( hash_sections->sha1_hash_set != 0 )
4653
0
    {
4654
0
      if( libewf_section_descriptor_initialize(
4655
0
           &section_descriptor,
4656
0
           error ) != 1 )
4657
0
      {
4658
0
        libcerror_error_set(
4659
0
         error,
4660
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4661
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4662
0
         "%s: unable to create section descriptor.",
4663
0
         function );
4664
4665
0
        goto on_error;
4666
0
      }
4667
0
      write_count = libewf_sha1_hash_section_write_file_io_pool(
4668
0
               section_descriptor,
4669
0
               segment_file->io_handle,
4670
0
               file_io_pool,
4671
0
               file_io_pool_entry,
4672
0
               segment_file->major_version,
4673
0
               segment_file->current_offset,
4674
0
               hash_sections,
4675
0
               error );
4676
4677
0
      if( write_count == -1 )
4678
0
      {
4679
0
        libcerror_error_set(
4680
0
         error,
4681
0
         LIBCERROR_ERROR_DOMAIN_IO,
4682
0
         LIBCERROR_IO_ERROR_WRITE_FAILED,
4683
0
         "%s: unable to write SHA1 hash section.",
4684
0
         function );
4685
4686
0
        goto on_error;
4687
0
      }
4688
0
      if( segment_file->major_version == 1 )
4689
0
      {
4690
0
        result = libfdata_list_append_element(
4691
0
            segment_file->sections_list,
4692
0
            &element_index,
4693
0
            file_io_pool_entry,
4694
0
            segment_file->current_offset,
4695
0
            sizeof( ewf_section_descriptor_v1_t ),
4696
0
            0,
4697
0
            error );
4698
0
      }
4699
0
      segment_file->current_offset += write_count;
4700
0
      total_write_count            += write_count;
4701
4702
0
      if( segment_file->major_version == 2 )
4703
0
      {
4704
0
        result = libfdata_list_append_element(
4705
0
            segment_file->sections_list,
4706
0
            &element_index,
4707
0
            file_io_pool_entry,
4708
0
            segment_file->current_offset - sizeof( ewf_section_descriptor_v2_t ),
4709
0
            sizeof( ewf_section_descriptor_v2_t ),
4710
0
            0,
4711
0
            error );
4712
0
      }
4713
0
      if( result != 1 )
4714
0
      {
4715
0
        libcerror_error_set(
4716
0
         error,
4717
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4718
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
4719
0
         "%s: unable to append element to sections list.",
4720
0
         function );
4721
4722
0
        goto on_error;
4723
0
      }
4724
0
      if( libewf_section_descriptor_free(
4725
0
           &section_descriptor,
4726
0
           error ) != 1 )
4727
0
      {
4728
0
        libcerror_error_set(
4729
0
         error,
4730
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4731
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4732
0
         "%s: unable to free section.",
4733
0
         function );
4734
4735
0
        goto on_error;
4736
0
      }
4737
0
    }
4738
0
  }
4739
0
  if( segment_file->io_handle->format == LIBEWF_FORMAT_EWFX )
4740
0
  {
4741
    /* Write the xhash section
4742
     */
4743
0
    if( hash_sections->xhash != NULL )
4744
0
    {
4745
#if defined( HAVE_DEBUG_OUTPUT )
4746
      if( libcnotify_verbose != 0 )
4747
      {
4748
        libcnotify_printf(
4749
        "%s: xhash already set - removing previous version.\n",
4750
         function );
4751
      }
4752
#endif
4753
0
      memory_free(
4754
0
       hash_sections->xhash );
4755
4756
0
      hash_sections->xhash = NULL;
4757
0
    }
4758
0
    if( libewf_hash_values_generate_xhash(
4759
0
         hash_values,
4760
0
         &( hash_sections->xhash ),
4761
0
         &( hash_sections->xhash_size ),
4762
0
         error ) != 1 )
4763
0
    {
4764
0
      libcerror_error_set(
4765
0
       error,
4766
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4767
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4768
0
       "%s: unable to generate xhash.",
4769
0
       function );
4770
4771
0
      goto on_error;
4772
0
    }
4773
#if defined( HAVE_DEBUG_OUTPUT )
4774
    if( libcnotify_verbose != 0 )
4775
    {
4776
      if( libewf_debug_utf8_stream_print(
4777
           "XHash",
4778
           hash_sections->xhash,
4779
           hash_sections->xhash_size,
4780
           error ) != 1 )
4781
      {
4782
        libcerror_error_set(
4783
         error,
4784
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4785
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
4786
         "%s: unable to print xhash.",
4787
         function );
4788
4789
        goto on_error;
4790
      }
4791
    }
4792
#endif
4793
0
    if( libewf_section_descriptor_initialize(
4794
0
         &section_descriptor,
4795
0
         error ) != 1 )
4796
0
    {
4797
0
      libcerror_error_set(
4798
0
       error,
4799
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4800
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4801
0
       "%s: unable to create section descriptor.",
4802
0
       function );
4803
4804
0
      goto on_error;
4805
0
    }
4806
    /* Do not include the end of string character in the compressed data
4807
     */
4808
0
    write_count = libewf_section_write_compressed_string(
4809
0
             section_descriptor,
4810
0
             segment_file->io_handle,
4811
0
             file_io_pool,
4812
0
             file_io_pool_entry,
4813
0
             1,
4814
0
             0,
4815
0
             (uint8_t *) "xhash",
4816
0
             5,
4817
0
             segment_file->current_offset,
4818
0
             segment_file->io_handle->compression_method,
4819
0
             LIBEWF_COMPRESSION_LEVEL_DEFAULT,
4820
0
             hash_sections->xhash,
4821
0
             hash_sections->xhash_size - 1,
4822
0
             0,
4823
0
             error );
4824
4825
0
    if( write_count == -1 )
4826
0
    {
4827
0
      libcerror_error_set(
4828
0
       error,
4829
0
       LIBCERROR_ERROR_DOMAIN_IO,
4830
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
4831
0
       "%s: unable to write xhash section.",
4832
0
       function );
4833
4834
0
      goto on_error;
4835
0
    }
4836
0
    if( libfdata_list_append_element(
4837
0
         segment_file->sections_list,
4838
0
         &element_index,
4839
0
         file_io_pool_entry,
4840
0
         segment_file->current_offset,
4841
0
         sizeof( ewf_section_descriptor_v1_t ),
4842
0
         0,
4843
0
         error ) != 1 )
4844
0
    {
4845
0
      libcerror_error_set(
4846
0
       error,
4847
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4848
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
4849
0
       "%s: unable to append element to sections list.",
4850
0
       function );
4851
4852
0
      goto on_error;
4853
0
    }
4854
0
    segment_file->current_offset += write_count;
4855
0
    total_write_count            += write_count;
4856
4857
0
    if( libewf_section_descriptor_free(
4858
0
         &section_descriptor,
4859
0
         error ) != 1 )
4860
0
    {
4861
0
      libcerror_error_set(
4862
0
       error,
4863
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4864
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4865
0
       "%s: unable to free section.",
4866
0
       function );
4867
4868
0
      goto on_error;
4869
0
    }
4870
0
  }
4871
0
  return( total_write_count );
4872
4873
0
on_error:
4874
0
  if( section_descriptor != NULL )
4875
0
  {
4876
0
    libewf_section_descriptor_free(
4877
0
     &section_descriptor,
4878
0
     NULL );
4879
0
  }
4880
0
  return( -1 );
4881
0
}
4882
4883
/* Closes the segment file, necessary sections at the end of the segment file will be written
4884
 * Returns the number of bytes written or -1 on error
4885
 */
4886
ssize_t libewf_segment_file_write_close(
4887
         libewf_segment_file_t *segment_file,
4888
         libbfio_pool_t *file_io_pool,
4889
         int file_io_pool_entry,
4890
         uint64_t number_of_chunks_written_to_segment_file,
4891
         int last_segment_file,
4892
         libewf_hash_sections_t *hash_sections,
4893
         libfvalue_table_t *hash_values,
4894
         libewf_media_values_t *media_values,
4895
         libcdata_array_t *sessions,
4896
         libcdata_array_t *tracks,
4897
         libcdata_range_list_t *acquiry_errors,
4898
         ewf_data_t **data_section_descriptor,
4899
   libcerror_error_t **error )
4900
0
{
4901
0
  libewf_section_descriptor_t *section_descriptor = NULL;
4902
0
  static char *function                           = "libewf_segment_file_write_close";
4903
0
  ssize_t total_write_count                       = 0;
4904
0
  ssize_t write_count                             = 0;
4905
0
  int element_index                               = 0;
4906
0
  int number_of_acquiry_errors                    = 0;
4907
0
  int number_of_sessions                          = 0;
4908
0
  int result                                      = 0;
4909
4910
0
  if( segment_file == NULL )
4911
0
  {
4912
0
    libcerror_error_set(
4913
0
     error,
4914
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4915
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4916
0
     "%s: invalid segment file.",
4917
0
     function );
4918
4919
0
    return( -1 );
4920
0
  }
4921
0
  if( segment_file->io_handle == NULL )
4922
0
  {
4923
0
    libcerror_error_set(
4924
0
     error,
4925
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4926
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4927
0
     "%s: invalid segment file - missing IO handle.",
4928
0
     function );
4929
4930
0
    return( -1 );
4931
0
  }
4932
0
  if( media_values == NULL )
4933
0
  {
4934
0
    libcerror_error_set(
4935
0
     error,
4936
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4937
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4938
0
     "%s: invalid media values.",
4939
0
     function );
4940
4941
0
    return( -1 );
4942
0
  }
4943
0
  if( sessions == NULL )
4944
0
  {
4945
0
    libcerror_error_set(
4946
0
     error,
4947
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4948
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4949
0
     "%s: invalid sessions.",
4950
0
     function );
4951
4952
0
    return( -1 );
4953
0
  }
4954
0
  if( acquiry_errors == NULL )
4955
0
  {
4956
0
    libcerror_error_set(
4957
0
     error,
4958
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4959
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4960
0
     "%s: invalid acquiry errors.",
4961
0
     function );
4962
4963
0
    return( -1 );
4964
0
  }
4965
0
  if( last_segment_file != 0 )
4966
0
  {
4967
    /* Write the da