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 data section for a single segment file only for EWF-E01
4968
     */
4969
0
    if( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1 )
4970
0
    {
4971
0
      if( segment_file->segment_number == 1 )
4972
0
      {
4973
0
        if( libewf_section_descriptor_initialize(
4974
0
             &section_descriptor,
4975
0
             error ) != 1 )
4976
0
        {
4977
0
          libcerror_error_set(
4978
0
           error,
4979
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
4980
0
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4981
0
           "%s: unable to create section descriptor.",
4982
0
           function );
4983
4984
0
          goto on_error;
4985
0
        }
4986
0
        write_count = libewf_section_data_write(
4987
0
                 section_descriptor,
4988
0
                 segment_file->io_handle,
4989
0
                 file_io_pool,
4990
0
                 file_io_pool_entry,
4991
0
                 segment_file->current_offset,
4992
0
                 media_values,
4993
0
                 data_section_descriptor,
4994
0
                 error );
4995
4996
0
        if( write_count == -1 )
4997
0
        {
4998
0
          libcerror_error_set(
4999
0
           error,
5000
0
           LIBCERROR_ERROR_DOMAIN_IO,
5001
0
           LIBCERROR_IO_ERROR_WRITE_FAILED,
5002
0
           "%s: unable to write data section.",
5003
0
           function );
5004
5005
0
          goto on_error;
5006
0
        }
5007
0
        if( libfdata_list_append_element(
5008
0
             segment_file->sections_list,
5009
0
             &element_index,
5010
0
             file_io_pool_entry,
5011
0
             segment_file->current_offset,
5012
0
             sizeof( ewf_section_descriptor_v1_t ),
5013
0
             0,
5014
0
             error ) != 1 )
5015
0
        {
5016
0
          libcerror_error_set(
5017
0
           error,
5018
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
5019
0
           LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
5020
0
           "%s: unable to append element to sections list.",
5021
0
           function );
5022
5023
0
          goto on_error;
5024
0
        }
5025
0
        segment_file->current_offset += write_count;
5026
0
        total_write_count            += write_count;
5027
5028
0
        if( libewf_section_descriptor_free(
5029
0
             &section_descriptor,
5030
0
             error ) != 1 )
5031
0
        {
5032
0
          libcerror_error_set(
5033
0
           error,
5034
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
5035
0
           LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
5036
0
           "%s: unable to free section.",
5037
0
           function );
5038
5039
0
          goto on_error;
5040
0
        }
5041
0
      }
5042
0
    }
5043
    /* Write the session section if required
5044
     */
5045
0
    if( ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE5 )
5046
0
     || ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE6 )
5047
0
     || ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE7 )
5048
0
     || ( segment_file->io_handle->format == LIBEWF_FORMAT_LINEN5 )
5049
0
     || ( segment_file->io_handle->format == LIBEWF_FORMAT_LINEN6 )
5050
0
     || ( segment_file->io_handle->format == LIBEWF_FORMAT_LINEN7 )
5051
0
     || ( segment_file->io_handle->format == LIBEWF_FORMAT_V2_ENCASE7 )
5052
0
     || ( segment_file->io_handle->format == LIBEWF_FORMAT_EWFX ) )
5053
0
    {
5054
0
      if( libcdata_array_get_number_of_entries(
5055
0
           sessions,
5056
0
           &number_of_sessions,
5057
0
           error ) != 1 )
5058
0
      {
5059
0
        libcerror_error_set(
5060
0
         error,
5061
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
5062
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5063
0
         "%s: unable to retrieve number of entries from sessions array.",
5064
0
         function );
5065
5066
0
        goto on_error;
5067
0
      }
5068
0
      if( number_of_sessions > 0 )
5069
0
      {
5070
0
        if( libewf_section_descriptor_initialize(
5071
0
             &section_descriptor,
5072
0
             error ) != 1 )
5073
0
        {
5074
0
          libcerror_error_set(
5075
0
           error,
5076
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
5077
0
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5078
0
           "%s: unable to create section descriptor.",
5079
0
           function );
5080
5081
0
          goto on_error;
5082
0
        }
5083
0
        write_count = libewf_session_section_write_file_io_pool(
5084
0
                 section_descriptor,
5085
0
                 segment_file->io_handle,
5086
0
                 file_io_pool,
5087
0
                 file_io_pool_entry,
5088
0
                 segment_file->major_version,
5089
0
                 segment_file->current_offset,
5090
0
                 sessions,
5091
0
                 tracks,
5092
0
                 error );
5093
5094
0
        if( write_count == -1 )
5095
0
        {
5096
0
          libcerror_error_set(
5097
0
           error,
5098
0
           LIBCERROR_ERROR_DOMAIN_IO,
5099
0
           LIBCERROR_IO_ERROR_WRITE_FAILED,
5100
0
           "%s: unable to write session section.",
5101
0
           function );
5102
5103
0
          goto on_error;
5104
0
        }
5105
0
        if( segment_file->major_version == 1 )
5106
0
        {
5107
0
          result = libfdata_list_append_element(
5108
0
                    segment_file->sections_list,
5109
0
                    &element_index,
5110
0
                    file_io_pool_entry,
5111
0
                    segment_file->current_offset,
5112
0
                    sizeof( ewf_section_descriptor_v1_t ),
5113
0
                    0,
5114
0
                    error );
5115
0
        }
5116
0
        segment_file->current_offset += write_count;
5117
0
        total_write_count            += write_count;
5118
5119
0
        if( segment_file->major_version == 2 )
5120
0
        {
5121
0
          result = libfdata_list_append_element(
5122
0
                    segment_file->sections_list,
5123
0
                    &element_index,
5124
0
                    file_io_pool_entry,
5125
0
                    segment_file->current_offset - sizeof( ewf_section_descriptor_v2_t ),
5126
0
                    sizeof( ewf_section_descriptor_v2_t ),
5127
0
                    0,
5128
0
                    error );
5129
0
        }
5130
0
        if( result != 1 )
5131
0
        {
5132
0
          libcerror_error_set(
5133
0
           error,
5134
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
5135
0
           LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
5136
0
           "%s: unable to append element to sections list.",
5137
0
           function );
5138
5139
0
          goto on_error;
5140
0
        }
5141
0
        if( libewf_section_descriptor_free(
5142
0
             &section_descriptor,
5143
0
             error ) != 1 )
5144
0
        {
5145
0
          libcerror_error_set(
5146
0
           error,
5147
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
5148
0
           LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
5149
0
           "%s: unable to free section.",
5150
0
           function );
5151
5152
0
          goto on_error;
5153
0
        }
5154
0
      }
5155
0
    }
5156
    /* Write the error section if required
5157
     */
5158
0
    if( ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE3 )
5159
0
     || ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE4 )
5160
0
     || ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE5 )
5161
0
     || ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE6 )
5162
0
     || ( segment_file->io_handle->format == LIBEWF_FORMAT_ENCASE7 )
5163
0
     || ( segment_file->io_handle->format == LIBEWF_FORMAT_LINEN5 )
5164
0
     || ( segment_file->io_handle->format == LIBEWF_FORMAT_LINEN6 )
5165
0
     || ( segment_file->io_handle->format == LIBEWF_FORMAT_LINEN7 )
5166
0
     || ( segment_file->io_handle->format == LIBEWF_FORMAT_V2_ENCASE7 )
5167
0
     || ( segment_file->io_handle->format == LIBEWF_FORMAT_EWFX ) )
5168
0
    {
5169
0
      if( libcdata_range_list_get_number_of_elements(
5170
0
           acquiry_errors,
5171
0
           &number_of_acquiry_errors,
5172
0
           error ) != 1 )
5173
0
      {
5174
0
        libcerror_error_set(
5175
0
         error,
5176
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
5177
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5178
0
         "%s: unable to retrieve number of elements from acquiry errors range list.",
5179
0
         function );
5180
5181
0
        goto on_error;
5182
0
      }
5183
0
      if( number_of_acquiry_errors > 0 )
5184
0
      {
5185
0
        if( libewf_section_descriptor_initialize(
5186
0
             &section_descriptor,
5187
0
             error ) != 1 )
5188
0
        {
5189
0
          libcerror_error_set(
5190
0
           error,
5191
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
5192
0
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5193
0
           "%s: unable to create section descriptor.",
5194
0
           function );
5195
5196
0
          goto on_error;
5197
0
        }
5198
0
        write_count = libewf_error2_section_write_file_io_pool(
5199
0
                 section_descriptor,
5200
0
                 segment_file->io_handle,
5201
0
                 file_io_pool,
5202
0
                 file_io_pool_entry,
5203
0
                 segment_file->major_version,
5204
0
                 segment_file->current_offset,
5205
0
                 acquiry_errors,
5206
0
                 error );
5207
5208
0
        if( write_count == -1 )
5209
0
        {
5210
0
          libcerror_error_set(
5211
0
           error,
5212
0
           LIBCERROR_ERROR_DOMAIN_IO,
5213
0
           LIBCERROR_IO_ERROR_WRITE_FAILED,
5214
0
           "%s: unable to write error2 section.",
5215
0
           function );
5216
5217
0
          goto on_error;
5218
0
        }
5219
0
        if( segment_file->major_version == 1 )
5220
0
        {
5221
0
          result = libfdata_list_append_element(
5222
0
                    segment_file->sections_list,
5223
0
                    &element_index,
5224
0
                    file_io_pool_entry,
5225
0
                    segment_file->current_offset,
5226
0
                    sizeof( ewf_section_descriptor_v1_t ),
5227
0
                    0,
5228
0
                    error );
5229
0
        }
5230
0
        segment_file->current_offset += write_count;
5231
0
        total_write_count            += write_count;
5232
5233
0
        if( segment_file->major_version == 2 )
5234
0
        {
5235
0
          result = libfdata_list_append_element(
5236
0
                    segment_file->sections_list,
5237
0
                    &element_index,
5238
0
                    file_io_pool_entry,
5239
0
                    segment_file->current_offset - sizeof( ewf_section_descriptor_v2_t ),
5240
0
                    sizeof( ewf_section_descriptor_v2_t ),
5241
0
                    0,
5242
0
                    error );
5243
0
        }
5244
0
        if( result != 1 )
5245
0
        {
5246
0
          libcerror_error_set(
5247
0
           error,
5248
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
5249
0
           LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
5250
0
           "%s: unable to append element to sections list.",
5251
0
           function );
5252
5253
0
          goto on_error;
5254
0
        }
5255
0
        if( libewf_section_descriptor_free(
5256
0
             &section_descriptor,
5257
0
             error ) != 1 )
5258
0
        {
5259
0
          libcerror_error_set(
5260
0
           error,
5261
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
5262
0
           LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
5263
0
           "%s: unable to free section.",
5264
0
           function );
5265
5266
0
          goto on_error;
5267
0
        }
5268
0
      }
5269
0
    }
5270
    /* Write the hash sections
5271
     */
5272
0
    write_count = libewf_segment_file_write_hash_sections(
5273
0
             segment_file,
5274
0
             file_io_pool,
5275
0
             file_io_pool_entry,
5276
0
             hash_sections,
5277
0
             hash_values,
5278
0
             error );
5279
5280
0
    if( write_count == -1 )
5281
0
    {
5282
0
      libcerror_error_set(
5283
0
       error,
5284
0
       LIBCERROR_ERROR_DOMAIN_IO,
5285
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
5286
0
       "%s: unable to write hash sections.",
5287
0
       function );
5288
5289
0
      goto on_error;
5290
0
    }
5291
0
    total_write_count += write_count;
5292
0
  }
5293
  /* Write the done or next section
5294
   * The segment file offset is updated by the function
5295
   */
5296
0
  write_count = libewf_segment_file_write_last_section(
5297
0
           segment_file,
5298
0
           file_io_pool,
5299
0
           file_io_pool_entry,
5300
0
                 last_segment_file,
5301
0
                 error );
5302
5303
0
  if( write_count == -1 )
5304
0
  {
5305
0
    libcerror_error_set(
5306
0
     error,
5307
0
     LIBCERROR_ERROR_DOMAIN_IO,
5308
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
5309
0
     "%s: unable to write end of segment file.",
5310
0
     function );
5311
5312
0
    goto on_error;
5313
0
  }
5314
0
  total_write_count += write_count;
5315
5316
0
  segment_file->number_of_chunks = number_of_chunks_written_to_segment_file;
5317
5318
0
  if( libbfio_pool_close(
5319
0
       file_io_pool,
5320
0
       file_io_pool_entry,
5321
0
       error ) != 0 )
5322
0
  {
5323
0
    libcerror_error_set(
5324
0
     error,
5325
0
     LIBCERROR_ERROR_DOMAIN_IO,
5326
0
     LIBCERROR_IO_ERROR_CLOSE_FAILED,
5327
0
     "%s: unable to close segment file: %" PRIu16 ".",
5328
0
     function,
5329
0
     segment_file->segment_number );
5330
5331
0
    goto on_error;
5332
0
  }
5333
0
  segment_file->flags &= ~( LIBEWF_SEGMENT_FILE_FLAG_WRITE_OPEN );
5334
5335
0
  return( total_write_count );
5336
5337
0
on_error:
5338
0
  if( section_descriptor != NULL )
5339
0
  {
5340
0
    libewf_section_descriptor_free(
5341
0
     &section_descriptor,
5342
0
     NULL );
5343
0
  }
5344
0
  return( -1 );
5345
0
}
5346
5347
/* Reopens the segment file for resume writing
5348
 * Returns 1 if successful or -1 on error
5349
 */
5350
int libewf_segment_file_reopen(
5351
     libewf_segment_file_t *segment_file,
5352
     int last_section_index,
5353
     libbfio_pool_t *file_io_pool,
5354
     int file_io_pool_entry,
5355
     libfcache_cache_t *sections_cache,
5356
     libcerror_error_t **error )
5357
0
{
5358
0
  libewf_section_descriptor_t *last_section = NULL;
5359
0
  static char *function                     = "libewf_segment_file_reopen";
5360
0
  size64_t storage_media_size               = 0;
5361
0
  uint64_t number_of_chunks                 = 0;
5362
5363
0
  if( segment_file == NULL )
5364
0
  {
5365
0
    libcerror_error_set(
5366
0
     error,
5367
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5368
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5369
0
     "%s: invalid segment file.",
5370
0
     function );
5371
5372
0
    return( -1 );
5373
0
  }
5374
0
  if( segment_file->io_handle == NULL )
5375
0
  {
5376
0
    libcerror_error_set(
5377
0
     error,
5378
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5379
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5380
0
     "%s: invalid segment file - missing IO handle.",
5381
0
     function );
5382
5383
0
    return( -1 );
5384
0
  }
5385
0
  if( segment_file->io_handle->chunk_size == 0 )
5386
0
  {
5387
0
    libcerror_error_set(
5388
0
     error,
5389
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5390
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5391
0
     "%s: invalid segment file - invalid IO handle - missing chunk size.",
5392
0
     function );
5393
5394
0
    return( -1 );
5395
0
  }
5396
0
  if( libfdata_list_get_element_value_by_index(
5397
0
       segment_file->sections_list,
5398
0
       (intptr_t *) file_io_pool,
5399
0
       (libfdata_cache_t *) sections_cache,
5400
0
       last_section_index,
5401
0
       (intptr_t **) &last_section,
5402
0
       0,
5403
0
       error ) != 1 )
5404
0
  {
5405
0
    libcerror_error_set(
5406
0
     error,
5407
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5408
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5409
0
     "%s: unable to retrieve section: %d from sections list.",
5410
0
     function,
5411
0
     last_section_index );
5412
5413
0
    return( -1 );
5414
0
  }
5415
0
  if( last_section == NULL )
5416
0
  {
5417
0
    libcerror_error_set(
5418
0
     error,
5419
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5420
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5421
0
     "%s: missing section: %d.",
5422
0
     function,
5423
0
     last_section_index );
5424
5425
0
    return( -1 );
5426
0
  }
5427
0
        segment_file->current_offset      = last_section->end_offset;
5428
0
  segment_file->last_section_offset = last_section->end_offset;
5429
5430
0
  if( libfdata_list_resize(
5431
0
       segment_file->sections_list,
5432
0
       last_section_index + 1,
5433
0
       error ) != 1 )
5434
0
  {
5435
0
    libcerror_error_set(
5436
0
     error,
5437
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5438
0
     LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
5439
0
     "%s: unable to resize sections list.",
5440
0
     function );
5441
5442
0
    return( -1 );
5443
0
  }
5444
0
  if( segment_file->number_of_chunks > 0 )
5445
0
  {
5446
0
    if( libfdata_list_get_mapped_size_by_index(
5447
0
         segment_file->chunk_groups_list,
5448
0
         segment_file->current_chunk_group_index,
5449
0
         &storage_media_size,
5450
0
         error ) != 1 )
5451
0
    {
5452
0
      libcerror_error_set(
5453
0
       error,
5454
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5455
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5456
0
       "%s: unable to retrieve chunk group: %d mapped size.",
5457
0
       function,
5458
0
       segment_file->current_chunk_group_index );
5459
5460
0
      return( -1 );
5461
0
    }
5462
0
    if( libfdata_list_resize(
5463
0
         segment_file->chunk_groups_list,
5464
0
         segment_file->current_chunk_group_index,
5465
0
         error ) != 1 )
5466
0
    {
5467
0
      libcerror_error_set(
5468
0
       error,
5469
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5470
0
       LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED,
5471
0
       "%s: unable to resize chunk groups list.",
5472
0
       function );
5473
5474
0
      return( -1 );
5475
0
    }
5476
0
    segment_file->current_chunk_group_index -= 1;
5477
5478
0
    if( storage_media_size > segment_file->storage_media_size )
5479
0
    {
5480
0
      libcerror_error_set(
5481
0
       error,
5482
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5483
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5484
0
       "%s: invalid storage media size value out of bounds.",
5485
0
       function );
5486
5487
0
      return( -1 );
5488
0
    }
5489
0
    segment_file->storage_media_size -= storage_media_size;
5490
5491
0
    number_of_chunks = storage_media_size;
5492
5493
0
    if( ( number_of_chunks % segment_file->io_handle->chunk_size ) != 0 )
5494
0
    {
5495
0
      number_of_chunks /= (uint64_t) segment_file->io_handle->chunk_size;
5496
0
      number_of_chunks += 1;
5497
0
    }
5498
0
    else
5499
0
    {
5500
0
      number_of_chunks /= (uint64_t) segment_file->io_handle->chunk_size;
5501
0
    }
5502
0
    if( number_of_chunks > segment_file->number_of_chunks )
5503
0
    {
5504
0
      libcerror_error_set(
5505
0
       error,
5506
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5507
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5508
0
       "%s: invalid number of chunks value out of bounds.",
5509
0
       function );
5510
5511
0
      return( -1 );
5512
0
    }
5513
0
    segment_file->number_of_chunks -= (uint64_t) number_of_chunks;
5514
0
  }
5515
0
  if( libbfio_pool_reopen(
5516
0
       file_io_pool,
5517
0
       file_io_pool_entry,
5518
0
       LIBBFIO_OPEN_READ_WRITE,
5519
0
       error ) != 1 )
5520
0
  {
5521
0
    libcerror_error_set(
5522
0
     error,
5523
0
     LIBCERROR_ERROR_DOMAIN_IO,
5524
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
5525
0
     "%s: unable to re-open file IO pool entry: %d.",
5526
0
     function,
5527
0
     file_io_pool_entry );
5528
5529
0
    return( -1 );
5530
0
  }
5531
0
  segment_file->flags |= LIBEWF_SEGMENT_FILE_FLAG_WRITE_OPEN;
5532
5533
0
  return( 1 );
5534
0
}
5535
5536
/* Corrects sections after streamed write
5537
 * Returns 1 if successful or -1 on error
5538
 */
5539
int libewf_segment_file_write_sections_correction(
5540
     libewf_segment_file_t *segment_file,
5541
     libbfio_pool_t *file_io_pool,
5542
     int file_io_pool_entry,
5543
     uint64_t number_of_chunks_written_to_segment_file,
5544
     int last_segment_file,
5545
     libewf_media_values_t *media_values,
5546
     libfvalue_table_t *header_values,
5547
     time_t timestamp,
5548
     libfvalue_table_t *hash_values,
5549
     libewf_hash_sections_t *hash_sections,
5550
     libcdata_array_t *sessions,
5551
     libcdata_array_t *tracks,
5552
     libcdata_range_list_t *acquiry_errors,
5553
     uint8_t **case_data,
5554
     size_t *case_data_size,
5555
     uint8_t **device_information,
5556
     size_t *device_information_size,
5557
     ewf_data_t **data_section_descriptor,
5558
     libcerror_error_t **error )
5559
0
{
5560
0
  libewf_section_descriptor_t *section_descriptor = NULL;
5561
0
  libfcache_cache_t *sections_cache               = NULL;
5562
0
  static char *function                           = "libewf_segment_file_write_sections_correction";
5563
0
  ssize_t write_count                             = 0;
5564
0
  off64_t next_section_start_offset               = 0;
5565
0
  int correct_last_next_section                   = 0;
5566
0
  int number_of_sections                          = 0;
5567
0
  int section_index                               = 0;
5568
5569
0
  if( segment_file == NULL )
5570
0
  {
5571
0
    libcerror_error_set(
5572
0
     error,
5573
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5574
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5575
0
     "%s: invalid segment file.",
5576
0
     function );
5577
5578
0
    return( -1 );
5579
0
  }
5580
0
  if( segment_file->io_handle == NULL )
5581
0
  {
5582
0
    libcerror_error_set(
5583
0
     error,
5584
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5585
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5586
0
     "%s: invalid segment file - missing IO handle.",
5587
0
     function );
5588
5589
0
    return( -1 );
5590
0
  }
5591
0
  if( segment_file->sections_list == NULL )
5592
0
  {
5593
0
    libcerror_error_set(
5594
0
     error,
5595
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5596
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5597
0
     "%s: invalid segment file - missing sections list.",
5598
0
     function );
5599
5600
0
    return( -1 );
5601
0
  }
5602
0
  if( device_information == NULL )
5603
0
  {
5604
0
    libcerror_error_set(
5605
0
     error,
5606
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5607
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5608
0
     "%s: invalid device information.",
5609
0
     function );
5610
5611
0
    return( -1 );
5612
0
  }
5613
0
  if( device_information_size == NULL )
5614
0
  {
5615
0
    libcerror_error_set(
5616
0
     error,
5617
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5618
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5619
0
     "%s: invalid device information size.",
5620
0
     function );
5621
5622
0
    return( -1 );
5623
0
  }
5624
0
  if( case_data == NULL )
5625
0
  {
5626
0
    libcerror_error_set(
5627
0
     error,
5628
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5629
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5630
0
     "%s: invalid case data.",
5631
0
     function );
5632
5633
0
    return( -1 );
5634
0
  }
5635
0
  if( case_data_size == NULL )
5636
0
  {
5637
0
    libcerror_error_set(
5638
0
     error,
5639
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5640
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5641
0
     "%s: invalid case data size.",
5642
0
     function );
5643
5644
0
    return( -1 );
5645
0
  }
5646
0
  if( libfcache_cache_initialize(
5647
0
       &sections_cache,
5648
0
       LIBEWF_MAXIMUM_CACHE_ENTRIES_SECTIONS,
5649
0
       error ) != 1 )
5650
0
  {
5651
0
    libcerror_error_set(
5652
0
     error,
5653
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5654
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5655
0
     "%s: unable to create section descriptor. cache.",
5656
0
     function );
5657
5658
0
    goto on_error;
5659
0
  }
5660
#if defined( HAVE_DEBUG_OUTPUT )
5661
  if( libcnotify_verbose != 0 )
5662
  {
5663
    libcnotify_printf(
5664
     "%s: correcting sections in segment file: %" PRIu16 ".\n",
5665
     function,
5666
     segment_file->segment_number );
5667
  }
5668
#endif
5669
0
  if( libfdata_list_get_number_of_elements(
5670
0
       segment_file->sections_list,
5671
0
       &number_of_sections,
5672
0
       error ) != 1 )
5673
0
  {
5674
0
    libcerror_error_set(
5675
0
     error,
5676
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5677
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5678
0
     "%s: unable to retrieve the number of sections in the sections list.",
5679
0
     function );
5680
5681
0
    goto on_error;
5682
0
  }
5683
0
  for( section_index = 0;
5684
0
       section_index < number_of_sections;
5685
0
       section_index++ )
5686
0
  {
5687
0
    if( libfdata_list_get_element_value_by_index(
5688
0
         segment_file->sections_list,
5689
0
         (intptr_t *) file_io_pool,
5690
0
         (libfdata_cache_t *) sections_cache,
5691
0
         section_index,
5692
0
         (intptr_t **) &section_descriptor,
5693
0
         0,
5694
0
         error ) != 1 )
5695
0
    {
5696
0
      libcerror_error_set(
5697
0
       error,
5698
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5699
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5700
0
       "%s: unable to retrieve section: %d from sections list.",
5701
0
       function,
5702
0
       section_index );
5703
5704
0
      goto on_error;
5705
0
    }
5706
0
    if( section_descriptor == NULL )
5707
0
    {
5708
0
      libcerror_error_set(
5709
0
       error,
5710
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5711
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5712
0
       "%s: missing section: %d.",
5713
0
       function,
5714
0
       section_index );
5715
5716
0
      goto on_error;
5717
0
    }
5718
0
    if( section_descriptor->type != 0 )
5719
0
    {
5720
0
      switch( section_descriptor->type )
5721
0
      {
5722
0
        case LIBEWF_SECTION_TYPE_DEVICE_INFORMATION:
5723
0
          if( *device_information == NULL )
5724
0
          {
5725
0
            if( libewf_device_information_generate(
5726
0
                 device_information,
5727
0
                 device_information_size,
5728
0
                 media_values,
5729
0
                 header_values,
5730
0
                 error ) != 1 )
5731
0
            {
5732
0
              libcerror_error_set(
5733
0
               error,
5734
0
               LIBCERROR_ERROR_DOMAIN_RUNTIME,
5735
0
               LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5736
0
               "%s: unable to generate device information.",
5737
0
               function );
5738
5739
0
              goto on_error;
5740
0
            }
5741
0
          }
5742
#if defined( HAVE_DEBUG_OUTPUT )
5743
          if( libcnotify_verbose != 0 )
5744
          {
5745
            libcnotify_printf(
5746
             "%s: correcting device information section.\n",
5747
             function );
5748
          }
5749
#endif
5750
0
          if( libbfio_pool_seek_offset(
5751
0
               file_io_pool,
5752
0
               file_io_pool_entry,
5753
0
               section_descriptor->start_offset,
5754
0
               SEEK_SET,
5755
0
               error ) == -1 )
5756
0
          {
5757
0
            libcerror_error_set(
5758
0
             error,
5759
0
             LIBCERROR_ERROR_DOMAIN_IO,
5760
0
             LIBCERROR_IO_ERROR_SEEK_FAILED,
5761
0
             "%s: unable to find offset to correct device information section.",
5762
0
             function );
5763
5764
0
            goto on_error;
5765
0
          }
5766
0
          segment_file->current_offset = section_descriptor->start_offset;
5767
5768
          /* Do not include the end of string character in the compressed data
5769
           */
5770
0
          write_count = libewf_section_write_compressed_string(
5771
0
                   section_descriptor,
5772
0
                   segment_file->io_handle,
5773
0
                   file_io_pool,
5774
0
                   file_io_pool_entry,
5775
0
                   2,
5776
0
                   LIBEWF_SECTION_TYPE_DEVICE_INFORMATION,
5777
0
                   NULL,
5778
0
                   0,
5779
0
                   section_descriptor->start_offset,
5780
0
                   segment_file->io_handle->compression_method,
5781
0
                   LIBEWF_COMPRESSION_LEVEL_DEFAULT,
5782
0
                   *device_information,
5783
0
                   *device_information_size - 2,
5784
0
                   (size_t) section_descriptor->data_size,
5785
0
                   error );
5786
5787
0
          if( write_count == -1 )
5788
0
          {
5789
0
            libcerror_error_set(
5790
0
             error,
5791
0
             LIBCERROR_ERROR_DOMAIN_IO,
5792
0
             LIBCERROR_IO_ERROR_WRITE_FAILED,
5793
0
             "%s: unable to write device information section.",
5794
0
             function );
5795
5796
0
            goto on_error;
5797
0
          }
5798
0
          segment_file->current_offset += write_count;
5799
5800
0
          break;
5801
5802
0
        case LIBEWF_SECTION_TYPE_CASE_DATA:
5803
0
          if( *case_data == NULL )
5804
0
          {
5805
0
            if( libewf_case_data_generate(
5806
0
                 case_data,
5807
0
                 case_data_size,
5808
0
                 media_values,
5809
0
                 header_values,
5810
0
                 timestamp,
5811
0
                 segment_file->io_handle->format,
5812
0
                 error ) != 1 )
5813
0
            {
5814
0
              libcerror_error_set(
5815
0
               error,
5816
0
               LIBCERROR_ERROR_DOMAIN_RUNTIME,
5817
0
               LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5818
0
               "%s: unable to generate case data.",
5819
0
               function );
5820
5821
0
              goto on_error;
5822
0
            }
5823
0
          }
5824
#if defined( HAVE_DEBUG_OUTPUT )
5825
          if( libcnotify_verbose != 0 )
5826
          {
5827
            libcnotify_printf(
5828
             "%s: correcting case data section.\n",
5829
             function );
5830
          }
5831
#endif
5832
0
          if( libbfio_pool_seek_offset(
5833
0
               file_io_pool,
5834
0
               file_io_pool_entry,
5835
0
               section_descriptor->start_offset,
5836
0
               SEEK_SET,
5837
0
               error ) == -1 )
5838
0
          {
5839
0
            libcerror_error_set(
5840
0
             error,
5841
0
             LIBCERROR_ERROR_DOMAIN_IO,
5842
0
             LIBCERROR_IO_ERROR_SEEK_FAILED,
5843
0
             "%s: unable to find offset to correct case data section.",
5844
0
             function );
5845
5846
0
            goto on_error;
5847
0
          }
5848
0
          segment_file->current_offset = section_descriptor->start_offset;
5849
5850
          /* Do not include the end of string character in the compressed data
5851
           */
5852
0
          write_count = libewf_section_write_compressed_string(
5853
0
                   section_descriptor,
5854
0
                   segment_file->io_handle,
5855
0
                   file_io_pool,
5856
0
                   file_io_pool_entry,
5857
0
                   2,
5858
0
                   LIBEWF_SECTION_TYPE_CASE_DATA,
5859
0
                   NULL,
5860
0
                   0,
5861
0
                   section_descriptor->start_offset,
5862
0
                   segment_file->io_handle->compression_method,
5863
0
                   LIBEWF_COMPRESSION_LEVEL_DEFAULT,
5864
0
                   *case_data,
5865
0
                   *case_data_size - 2,
5866
0
                   (size_t) section_descriptor->data_size,
5867
0
                   error );
5868
5869
0
          if( write_count == -1 )
5870
0
          {
5871
0
            libcerror_error_set(
5872
0
             error,
5873
0
             LIBCERROR_ERROR_DOMAIN_IO,
5874
0
             LIBCERROR_IO_ERROR_WRITE_FAILED,
5875
0
             "%s: unable to write case data section.",
5876
0
             function );
5877
5878
0
            goto on_error;
5879
0
          }
5880
0
          segment_file->current_offset += write_count;
5881
5882
0
          break;
5883
5884
0
        case LIBEWF_SECTION_TYPE_NEXT:
5885
          /* The last segment file should be terminated with a done section and not with a next section
5886
           */
5887
0
          if( last_segment_file != 0 )
5888
0
          {
5889
0
            correct_last_next_section = 1;
5890
0
            next_section_start_offset = section_descriptor->start_offset;
5891
0
          }
5892
0
          break;
5893
0
      }
5894
0
    }
5895
0
    else if( section_descriptor->type_string_length == 6 )
5896
0
    {
5897
0
      if( memory_compare(
5898
0
           section_descriptor->type_string,
5899
0
           "volume",
5900
0
           6 ) == 0 )
5901
0
      {
5902
#if defined( HAVE_DEBUG_OUTPUT )
5903
        if( libcnotify_verbose != 0 )
5904
        {
5905
          libcnotify_printf(
5906
           "%s: correcting volume section.\n",
5907
           function );
5908
        }
5909
#endif
5910
0
        if( libbfio_pool_seek_offset(
5911
0
             file_io_pool,
5912
0
             file_io_pool_entry,
5913
0
             section_descriptor->start_offset,
5914
0
             SEEK_SET,
5915
0
             error ) == -1 )
5916
0
        {
5917
0
          libcerror_error_set(
5918
0
           error,
5919
0
           LIBCERROR_ERROR_DOMAIN_IO,
5920
0
           LIBCERROR_IO_ERROR_SEEK_FAILED,
5921
0
           "%s: unable to find offset to correct volume section.",
5922
0
           function );
5923
5924
0
          goto on_error;
5925
0
        }
5926
0
        segment_file->current_offset = section_descriptor->start_offset;
5927
5928
0
        if( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1 )
5929
0
        {
5930
0
          write_count = libewf_volume_section_e01_write_file_io_pool(
5931
0
                   section_descriptor,
5932
0
                   segment_file->io_handle,
5933
0
                   file_io_pool,
5934
0
                   file_io_pool_entry,
5935
0
                   section_descriptor->start_offset,
5936
0
                   media_values,
5937
0
                   error );
5938
0
        }
5939
0
        else if( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
5940
0
        {
5941
0
          write_count = libewf_volume_section_s01_write_file_io_pool(
5942
0
                   section_descriptor,
5943
0
                   segment_file->io_handle,
5944
0
                   file_io_pool,
5945
0
                   file_io_pool_entry,
5946
0
                   section_descriptor->start_offset,
5947
0
                   media_values,
5948
0
                   error );
5949
0
        }
5950
0
        else
5951
0
        {
5952
0
          write_count = -1;
5953
0
        }
5954
0
        if( write_count == -1 )
5955
0
        {
5956
0
          libcerror_error_set(
5957
0
           error,
5958
0
           LIBCERROR_ERROR_DOMAIN_IO,
5959
0
           LIBCERROR_IO_ERROR_WRITE_FAILED,
5960
0
           "%s: unable to correct volume section.",
5961
0
           function );
5962
5963
0
          goto on_error;
5964
0
        }
5965
0
        segment_file->current_offset += write_count;
5966
0
      }
5967
0
    }
5968
0
    else if( section_descriptor->type_string_length == 4 )
5969
0
    {
5970
0
      if( memory_compare(
5971
0
           section_descriptor->type_string,
5972
0
           "data",
5973
0
           4 ) == 0 )
5974
0
      {
5975
#if defined( HAVE_DEBUG_OUTPUT )
5976
        if( libcnotify_verbose != 0 )
5977
        {
5978
          libcnotify_printf(
5979
           "%s: correcting data section.\n",
5980
           function );
5981
        }
5982
#endif
5983
0
        if( libbfio_pool_seek_offset(
5984
0
             file_io_pool,
5985
0
             file_io_pool_entry,
5986
0
             section_descriptor->start_offset,
5987
0
             SEEK_SET,
5988
0
             error ) == -1 )
5989
0
        {
5990
0
          libcerror_error_set(
5991
0
           error,
5992
0
           LIBCERROR_ERROR_DOMAIN_IO,
5993
0
           LIBCERROR_IO_ERROR_SEEK_FAILED,
5994
0
           "%s: unable to seek offset of data section.",
5995
0
           function );
5996
5997
0
          goto on_error;
5998
0
        }
5999
0
        segment_file->current_offset = section_descriptor->start_offset;
6000
6001
0
        write_count = libewf_section_data_write(
6002
0
                 section_descriptor,
6003
0
                 segment_file->io_handle,
6004
0
                 file_io_pool,
6005
0
                 file_io_pool_entry,
6006
0
                 section_descriptor->start_offset,
6007
0
                 media_values,
6008
0
                 data_section_descriptor,
6009
0
                 error );
6010
6011
0
        if( write_count == -1 )
6012
0
        {
6013
0
          libcerror_error_set(
6014
0
           error,
6015
0
           LIBCERROR_ERROR_DOMAIN_IO,
6016
0
           LIBCERROR_IO_ERROR_WRITE_FAILED,
6017
0
           "%s: unable to correct data section.",
6018
0
           function );
6019
6020
0
          goto on_error;
6021
0
        }
6022
0
        segment_file->current_offset += write_count;
6023
0
      }
6024
0
    }
6025
0
  }
6026
0
  if( correct_last_next_section == 0 )
6027
0
  {
6028
0
    if( libbfio_pool_close(
6029
0
         file_io_pool,
6030
0
         file_io_pool_entry,
6031
0
         error ) != 0 )
6032
0
    {
6033
0
      libcerror_error_set(
6034
0
       error,
6035
0
       LIBCERROR_ERROR_DOMAIN_IO,
6036
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
6037
0
       "%s: unable to close file IO pool entry: %d.",
6038
0
       function,
6039
0
       file_io_pool_entry );
6040
6041
0
      goto on_error;
6042
0
    }
6043
0
  }
6044
0
  else
6045
0
  {
6046
#if defined( HAVE_DEBUG_OUTPUT )
6047
    if( libcnotify_verbose != 0 )
6048
    {
6049
      libcnotify_printf(
6050
       "%s: correcting last next section.\n",
6051
       function );
6052
    }
6053
#endif
6054
0
    if( libbfio_pool_seek_offset(
6055
0
         file_io_pool,
6056
0
         file_io_pool_entry,
6057
0
         next_section_start_offset,
6058
0
         SEEK_SET,
6059
0
         error ) == -1 )
6060
0
    {
6061
0
      libcerror_error_set(
6062
0
       error,
6063
0
       LIBCERROR_ERROR_DOMAIN_IO,
6064
0
       LIBCERROR_IO_ERROR_SEEK_FAILED,
6065
0
       "%s: unable to find offset to last next section.",
6066
0
       function );
6067
6068
0
      goto on_error;
6069
0
    }
6070
0
    segment_file->current_offset = next_section_start_offset;
6071
6072
0
    write_count = libewf_segment_file_write_close(
6073
0
             segment_file,
6074
0
             file_io_pool,
6075
0
             file_io_pool_entry,
6076
0
             number_of_chunks_written_to_segment_file,
6077
0
             1,
6078
0
             hash_sections,
6079
0
             hash_values,
6080
0
             media_values,
6081
0
             sessions,
6082
0
             tracks,
6083
0
             acquiry_errors,
6084
0
             data_section_descriptor,
6085
0
             error );
6086
6087
0
    if( write_count == -1 )
6088
0
    {
6089
0
      libcerror_error_set(
6090
0
       error,
6091
0
       LIBCERROR_ERROR_DOMAIN_IO,
6092
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
6093
0
       "%s: unable to close segment file.",
6094
0
       function );
6095
6096
0
      goto on_error;
6097
0
    }
6098
0
  }
6099
0
  if( libfcache_cache_free(
6100
0
       &sections_cache,
6101
0
       error ) != 1 )
6102
0
  {
6103
0
    libcerror_error_set(
6104
0
     error,
6105
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6106
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
6107
0
     "%s: unable to free sections cache.",
6108
0
     function );
6109
6110
0
    goto on_error;
6111
0
  }
6112
0
  return( 1 );
6113
6114
0
on_error:
6115
0
  if( sections_cache != NULL )
6116
0
  {
6117
0
    libfcache_cache_free(
6118
0
     &sections_cache,
6119
0
     NULL );
6120
0
  }
6121
0
  return( -1 );
6122
0
}
6123
6124
/* Reads a segment file
6125
 * Callback function for the segment files list
6126
 * Returns 1 if successful or -1 on error
6127
 */
6128
int libewf_segment_file_read_element_data(
6129
     libewf_io_handle_t *io_handle,
6130
     libbfio_pool_t *file_io_pool,
6131
     libfdata_list_element_t *element,
6132
     libfdata_cache_t *segment_file_cache,
6133
     int file_io_pool_entry,
6134
     off64_t segment_file_offset,
6135
     size64_t segment_file_size,
6136
     uint32_t element_flags LIBEWF_ATTRIBUTE_UNUSED,
6137
     uint8_t read_flags LIBEWF_ATTRIBUTE_UNUSED,
6138
     libcerror_error_t **error )
6139
2.88k
{
6140
2.88k
  libewf_section_descriptor_t *section_descriptor = NULL;
6141
2.88k
  libewf_segment_file_t *segment_file             = NULL;
6142
2.88k
  libfcache_cache_t *sections_cache               = NULL;
6143
2.88k
  static char *function                           = "libewf_segment_file_read_element_data";
6144
2.88k
  ssize_t read_count                              = 0;
6145
2.88k
  off64_t section_data_offset                     = 0;
6146
2.88k
  int element_index                               = 0;
6147
2.88k
  int last_section                                = 0;
6148
2.88k
  int number_of_sections                          = 0;
6149
2.88k
  int result                                      = 0;
6150
2.88k
  int section_index                               = 0;
6151
6152
2.88k
  LIBEWF_UNREFERENCED_PARAMETER( element_flags )
6153
2.88k
  LIBEWF_UNREFERENCED_PARAMETER( read_flags )
6154
6155
2.88k
  if( io_handle == NULL )
6156
0
  {
6157
0
    libcerror_error_set(
6158
0
     error,
6159
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6160
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6161
0
     "%s: invalid IO handle.",
6162
0
     function );
6163
6164
0
    return( -1 );
6165
0
  }
6166
2.88k
  if( libewf_segment_file_initialize(
6167
2.88k
       &segment_file,
6168
2.88k
       io_handle,
6169
2.88k
       error ) != 1 )
6170
0
  {
6171
0
    libcerror_error_set(
6172
0
     error,
6173
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6174
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6175
0
     "%s: unable to create segment file.",
6176
0
     function );
6177
6178
0
    goto on_error;
6179
0
  }
6180
2.88k
  if( segment_file_size == 0 )
6181
0
  {
6182
    /* segment_file_size is 0 on write correction
6183
     */
6184
0
    if( libbfio_pool_get_size(
6185
0
         file_io_pool,
6186
0
         file_io_pool_entry,
6187
0
         &segment_file_size,
6188
0
         error ) != 1 )
6189
0
    {
6190
0
      libcerror_error_set(
6191
0
       error,
6192
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6193
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6194
0
       "%s: unable to retrieve segment file size.",
6195
0
       function );
6196
6197
0
      goto on_error;
6198
0
    }
6199
0
  }
6200
2.88k
  read_count = libewf_segment_file_read_file_header_file_io_pool(
6201
2.88k
          segment_file,
6202
2.88k
          file_io_pool,
6203
2.88k
          file_io_pool_entry,
6204
2.88k
          error );
6205
6206
/* TODO deal with corrupted header ? */
6207
2.88k
  if( read_count == -1 )
6208
0
  {
6209
0
    libcerror_error_set(
6210
0
     error,
6211
0
     LIBCERROR_ERROR_DOMAIN_IO,
6212
0
     LIBCERROR_IO_ERROR_READ_FAILED,
6213
0
     "%s: unable to read segment file header.",
6214
0
     function );
6215
6216
0
    goto on_error;
6217
0
  }
6218
2.88k
  if( ( segment_file->type != LIBEWF_SEGMENT_FILE_TYPE_EWF1 )
6219
2.88k
   && ( segment_file->type != LIBEWF_SEGMENT_FILE_TYPE_EWF1_LOGICAL )
6220
2.88k
   && ( segment_file->type != LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
6221
2.88k
   && ( segment_file->type != LIBEWF_SEGMENT_FILE_TYPE_EWF2 )
6222
2.88k
   && ( segment_file->type != LIBEWF_SEGMENT_FILE_TYPE_EWF2_LOGICAL ) )
6223
0
  {
6224
0
    libcerror_error_set(
6225
0
     error,
6226
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6227
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6228
0
     "%s: unsupported segment file type.",
6229
0
     function );
6230
6231
0
    goto on_error;
6232
0
  }
6233
2.88k
  if( ( io_handle->segment_file_type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
6234
2.88k
   && ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1 ) )
6235
0
  {
6236
0
    segment_file->type = LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART;
6237
0
  }
6238
2.88k
  else if( ( io_handle->segment_file_type != LIBEWF_SEGMENT_FILE_TYPE_UNDEFINED )
6239
2.88k
        && ( io_handle->segment_file_type != segment_file->type ) )
6240
0
  {
6241
0
    libcerror_error_set(
6242
0
     error,
6243
0
     LIBCERROR_ERROR_DOMAIN_INPUT,
6244
0
     LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
6245
0
     "%s: segment file type value mismatch.",
6246
0
     function );
6247
6248
0
    goto on_error;
6249
0
  }
6250
2.88k
  if( segment_file->major_version == 2 )
6251
194
  {
6252
194
    if( ( segment_file->compression_method != LIBEWF_COMPRESSION_METHOD_DEFLATE )
6253
194
     && ( segment_file->compression_method != LIBEWF_COMPRESSION_METHOD_BZIP2 ) )
6254
17
    {
6255
17
      libcerror_error_set(
6256
17
       error,
6257
17
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6258
17
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
6259
17
       "%s: unsupported compression method.",
6260
17
       function );
6261
6262
17
      goto on_error;
6263
17
    }
6264
194
  }
6265
  /* Read the section descriptors:
6266
   * EWF version 1 read from front to back
6267
   * EWF version 2 read from back to front
6268
   */
6269
2.87k
  if( segment_file->major_version == 1 )
6270
2.68k
  {
6271
2.68k
    segment_file_offset = (off64_t) read_count;
6272
2.68k
  }
6273
184
  else if( segment_file->major_version == 2 )
6274
177
  {
6275
177
    segment_file_offset = (off64_t) segment_file_size - sizeof( ewf_section_descriptor_v2_t );
6276
177
  }
6277
2.87k
  last_section = 0;
6278
6279
2.87k
  if( libewf_section_descriptor_initialize(
6280
2.87k
       &section_descriptor,
6281
2.87k
       error ) != 1 )
6282
0
  {
6283
0
    libcerror_error_set(
6284
0
     error,
6285
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6286
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6287
0
     "%s: unable to create section descriptor.",
6288
0
     function );
6289
6290
0
    goto on_error;
6291
0
  }
6292
11.5k
  while( ( segment_file_offset > 0 )
6293
11.5k
      && ( (size64_t) segment_file_offset < segment_file_size ) )
6294
9.78k
  {
6295
9.78k
    read_count = libewf_section_descriptor_read_file_io_pool(
6296
9.78k
            section_descriptor,
6297
9.78k
            file_io_pool,
6298
9.78k
            file_io_pool_entry,
6299
9.78k
            segment_file_offset,
6300
9.78k
            segment_file->major_version,
6301
9.78k
            error );
6302
6303
9.78k
    if( read_count == -1 )
6304
1.09k
    {
6305
1.09k
      libcerror_error_set(
6306
1.09k
       error,
6307
1.09k
       LIBCERROR_ERROR_DOMAIN_IO,
6308
1.09k
       LIBCERROR_IO_ERROR_READ_FAILED,
6309
1.09k
       "%s: unable to read section descriptor.",
6310
1.09k
       function );
6311
6312
#if defined( HAVE_DEBUG_OUTPUT )
6313
      if( libcnotify_verbose != 0 )
6314
      {
6315
        if( ( error != NULL )
6316
         && ( *error != NULL ) )
6317
        {
6318
          libcnotify_print_error_backtrace(
6319
           *error );
6320
        }
6321
      }
6322
#endif
6323
1.09k
      libcerror_error_free(
6324
1.09k
       error );
6325
6326
1.09k
      segment_file->flags |= LIBEWF_SEGMENT_FILE_FLAG_IS_CORRUPTED;
6327
6328
1.09k
      break;
6329
1.09k
    }
6330
8.68k
    segment_file->current_offset = segment_file_offset + read_count;
6331
6332
8.68k
    if( segment_file->major_version == 1 )
6333
8.68k
    {
6334
8.68k
      if( section_descriptor->type == LIBEWF_SECTION_TYPE_NEXT )
6335
0
      {
6336
0
        last_section = 1;
6337
0
      }
6338
8.68k
      else if( section_descriptor->type == LIBEWF_SECTION_TYPE_DONE )
6339
15
      {
6340
15
        last_section = 1;
6341
6342
15
        segment_file->flags |= LIBEWF_SEGMENT_FILE_FLAG_IS_LAST;
6343
15
      }
6344
8.68k
      segment_file->last_section_offset = segment_file_offset;
6345
6346
8.68k
      if( libfdata_list_append_element(
6347
8.68k
           segment_file->sections_list,
6348
8.68k
           &element_index,
6349
8.68k
           file_io_pool_entry,
6350
8.68k
           segment_file_offset,
6351
8.68k
           sizeof( ewf_section_descriptor_v1_t ),
6352
8.68k
           0,
6353
8.68k
           error ) != 1 )
6354
0
      {
6355
0
        libcerror_error_set(
6356
0
         error,
6357
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6358
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
6359
0
         "%s: unable to append element to sections list.",
6360
0
         function );
6361
6362
0
        goto on_error;
6363
0
      }
6364
8.68k
      segment_file_offset += section_descriptor->size;
6365
6366
/* TODO move into section descriptor read ? */
6367
8.68k
      if( ( last_section != 0 )
6368
8.68k
       && ( section_descriptor->size == 0 ) )
6369
0
      {
6370
0
        segment_file_offset += sizeof( ewf_section_descriptor_v1_t );
6371
0
      }
6372
8.68k
    }
6373
0
    else if( segment_file->major_version == 2 )
6374
0
    {
6375
0
      if( section_descriptor->type == LIBEWF_SECTION_TYPE_DEVICE_INFORMATION )
6376
0
      {
6377
0
        segment_file->device_information_section_index = section_index;
6378
0
      }
6379
0
      if( section_descriptor->type == LIBEWF_SECTION_TYPE_ENCRYPTION_KEYS )
6380
0
      {
6381
0
        segment_file->flags |= LIBEWF_SEGMENT_FILE_FLAG_IS_ENCRYPTED;
6382
/* TODO get key info ? */
6383
0
      }
6384
0
      if( segment_file->last_section_offset == 0 )
6385
0
      {
6386
0
        if( section_descriptor->type == LIBEWF_SECTION_TYPE_NEXT )
6387
0
        {
6388
0
          last_section = 1;
6389
0
        }
6390
0
        else if( section_descriptor->type == LIBEWF_SECTION_TYPE_DONE )
6391
0
        {
6392
0
          last_section = 1;
6393
6394
0
          segment_file->flags |= LIBEWF_SEGMENT_FILE_FLAG_IS_LAST;
6395
0
        }
6396
0
        segment_file->last_section_offset = segment_file_offset;
6397
0
      }
6398
0
      if( libfdata_list_append_element(
6399
0
           segment_file->sections_list,
6400
0
           &element_index,
6401
0
           file_io_pool_entry,
6402
0
           segment_file_offset,
6403
0
           sizeof( ewf_section_descriptor_v2_t ),
6404
0
           0,
6405
0
           error ) != 1 )
6406
0
      {
6407
0
        libcerror_error_set(
6408
0
         error,
6409
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6410
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
6411
0
         "%s: unable to append element to sections list.",
6412
0
         function );
6413
6414
0
        goto on_error;
6415
0
      }
6416
0
      segment_file_offset -= section_descriptor->size;
6417
0
    }
6418
8.68k
    section_index++;
6419
6420
8.68k
    if( ( segment_file->major_version == 1 )
6421
8.68k
     && ( last_section != 0 ) )
6422
15
    {
6423
15
      break;
6424
15
    }
6425
8.68k
  }
6426
2.87k
  number_of_sections = section_index;
6427
6428
2.87k
  if( libewf_section_descriptor_free(
6429
2.87k
       &section_descriptor,
6430
2.87k
       error ) != 1 )
6431
0
  {
6432
0
    libcerror_error_set(
6433
0
     error,
6434
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6435
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
6436
0
     "%s: unable to free section.",
6437
0
     function );
6438
6439
0
    goto on_error;
6440
0
  }
6441
2.87k
  if( ( segment_file->flags & LIBEWF_SEGMENT_FILE_FLAG_IS_CORRUPTED ) == 0 )
6442
1.77k
  {
6443
1.77k
    if( last_section == 0 )
6444
1.75k
    {
6445
1.75k
      libcerror_error_set(
6446
1.75k
       error,
6447
1.75k
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6448
1.75k
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6449
1.75k
       "%s: missing next or done section.",
6450
1.75k
       function );
6451
6452
#if defined( HAVE_DEBUG_OUTPUT )
6453
      if( libcnotify_verbose != 0 )
6454
      {
6455
        if( ( error != NULL )
6456
         && ( *error != NULL ) )
6457
        {
6458
          libcnotify_print_error_backtrace(
6459
           *error );
6460
        }
6461
      }
6462
#endif
6463
1.75k
      libcerror_error_free(
6464
1.75k
       error );
6465
6466
1.75k
      segment_file->flags |= LIBEWF_SEGMENT_FILE_FLAG_IS_CORRUPTED;
6467
1.75k
    }
6468
#if defined( HAVE_DEBUG_OUTPUT )
6469
    else if( libcnotify_verbose != 0 )
6470
    {
6471
      if( (size64_t) segment_file_offset < segment_file_size )
6472
      {
6473
        libcnotify_printf(
6474
         "%s: trailing data in segment file: %" PRIu16 "\n",
6475
         function,
6476
         segment_file->segment_number );
6477
      }
6478
    }
6479
#endif
6480
1.77k
  }
6481
2.87k
  if( segment_file->major_version == 2 )
6482
177
  {
6483
    /* Reversing the list after the last append is more efficient than using prepend
6484
     */
6485
177
    if( libfdata_list_reverse(
6486
177
         segment_file->sections_list,
6487
177
         error ) != 1 )
6488
0
    {
6489
0
      libcerror_error_set(
6490
0
       error,
6491
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6492
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6493
0
       "%s: unable to reverse sections list.",
6494
0
       function );
6495
6496
0
      goto on_error;
6497
0
    }
6498
177
    if( segment_file->device_information_section_index != -1 )
6499
0
    {
6500
0
      segment_file->device_information_section_index = ( section_index - 1 )
6501
0
                                                     - segment_file->device_information_section_index;
6502
0
    }
6503
177
  }
6504
2.87k
  if( io_handle->chunk_size != 0 )
6505
0
  {
6506
0
    if( libfcache_cache_initialize(
6507
0
         &sections_cache,
6508
0
         LIBEWF_MAXIMUM_CACHE_ENTRIES_SECTIONS,
6509
0
         error ) != 1 )
6510
0
    {
6511
0
      libcerror_error_set(
6512
0
       error,
6513
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6514
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6515
0
       "%s: unable to create section descriptor cache.",
6516
0
       function );
6517
6518
0
      goto on_error;
6519
0
    }
6520
0
    for( section_index = 0;
6521
0
         section_index < number_of_sections;
6522
0
         section_index++ )
6523
0
    {
6524
0
      if( libfdata_list_get_element_value_by_index(
6525
0
           segment_file->sections_list,
6526
0
           (intptr_t *) file_io_pool,
6527
0
           (libfdata_cache_t *) sections_cache,
6528
0
           section_index,
6529
0
           (intptr_t **) &section_descriptor,
6530
0
           0,
6531
0
           error ) != 1 )
6532
0
      {
6533
0
        libcerror_error_set(
6534
0
         error,
6535
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6536
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6537
0
         "%s: unable to retrieve section: %d from sections list.",
6538
0
         function,
6539
0
         section_index );
6540
6541
0
        goto on_error;
6542
0
      }
6543
0
      result = libewf_section_descriptor_get_data_offset(
6544
0
                section_descriptor,
6545
0
                segment_file->major_version,
6546
0
                &section_data_offset,
6547
0
                error );
6548
6549
0
      if( result == -1 )
6550
0
      {
6551
0
        libcerror_error_set(
6552
0
         error,
6553
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6554
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6555
0
         "%s: unable to retrieve section: %d data offset.",
6556
0
         function,
6557
0
         section_index );
6558
6559
0
        goto on_error;
6560
0
      }
6561
0
      if( section_descriptor->type == LIBEWF_SECTION_TYPE_SECTOR_TABLE )
6562
0
      {
6563
0
        if( result == 0 )
6564
0
        {
6565
0
          libcerror_error_set(
6566
0
           error,
6567
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
6568
0
           LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6569
0
           "%s: missing section: %d data offset.",
6570
0
           function,
6571
0
           section_index );
6572
6573
0
          goto on_error;
6574
0
        }
6575
0
        if( libewf_segment_file_seek_offset(
6576
0
             segment_file,
6577
0
             file_io_pool,
6578
0
             file_io_pool_entry,
6579
0
             section_data_offset,
6580
0
             error ) == -1 )
6581
0
        {
6582
0
          libcerror_error_set(
6583
0
           error,
6584
0
           LIBCERROR_ERROR_DOMAIN_IO,
6585
0
           LIBCERROR_IO_ERROR_OPEN_FAILED,
6586
0
           "%s: unable to seek section: %d data offset: %" PRIu64 ".",
6587
0
           function,
6588
0
           section_index,
6589
0
           section_data_offset );
6590
6591
0
          goto on_error;
6592
0
        }
6593
0
        read_count = libewf_segment_file_read_table_section(
6594
0
                segment_file,
6595
0
                section_descriptor,
6596
0
                file_io_pool,
6597
0
                file_io_pool_entry,
6598
0
                io_handle->chunk_size,
6599
0
                error );
6600
6601
0
        if( read_count == -1 )
6602
0
        {
6603
0
          libcerror_error_set(
6604
0
           error,
6605
0
           LIBCERROR_ERROR_DOMAIN_IO,
6606
0
           LIBCERROR_IO_ERROR_READ_FAILED,
6607
0
           "%s: unable to read section: 0x%08" PRIx32 ".",
6608
0
           function,
6609
0
           section_descriptor->type );
6610
6611
0
          section_descriptor = NULL;
6612
6613
0
          goto on_error;
6614
0
        }
6615
0
      }
6616
0
      else if( ( segment_file->major_version == 1 )
6617
0
            && ( ( section_descriptor->type_string_length == 6 )
6618
0
            && ( memory_compare(
6619
0
                  (void *) section_descriptor->type_string,
6620
0
                  (void *) "table2",
6621
0
                  6 ) == 0 ) ) )
6622
0
      {
6623
0
        if( result == 0 )
6624
0
        {
6625
0
          libcerror_error_set(
6626
0
           error,
6627
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
6628
0
           LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6629
0
           "%s: missing section: %d data offset.",
6630
0
           function,
6631
0
           section_index );
6632
6633
0
          goto on_error;
6634
0
        }
6635
0
        if( libewf_segment_file_seek_offset(
6636
0
             segment_file,
6637
0
             file_io_pool,
6638
0
             file_io_pool_entry,
6639
0
             section_data_offset,
6640
0
             error ) == -1 )
6641
0
        {
6642
0
          libcerror_error_set(
6643
0
           error,
6644
0
           LIBCERROR_ERROR_DOMAIN_IO,
6645
0
           LIBCERROR_IO_ERROR_OPEN_FAILED,
6646
0
           "%s: unable to seek section: %d data offset: %" PRIu64 ".",
6647
0
           function,
6648
0
           section_index,
6649
0
           section_data_offset );
6650
6651
0
          goto on_error;
6652
0
        }
6653
0
        read_count = libewf_segment_file_read_table2_section(
6654
0
                segment_file,
6655
0
                section_descriptor,
6656
0
                file_io_pool,
6657
0
                file_io_pool_entry,
6658
0
                error );
6659
6660
0
        if( read_count == -1 )
6661
0
        {
6662
0
          libcerror_error_set(
6663
0
           error,
6664
0
           LIBCERROR_ERROR_DOMAIN_IO,
6665
0
           LIBCERROR_IO_ERROR_READ_FAILED,
6666
0
           "%s: unable to read section: %s.",
6667
0
           function,
6668
0
           section_descriptor->type_string );
6669
6670
0
          section_descriptor = NULL;
6671
6672
0
          goto on_error;
6673
0
        }
6674
0
      }
6675
0
      section_descriptor = NULL;
6676
0
    }
6677
0
    if( libfcache_cache_free(
6678
0
         &sections_cache,
6679
0
         error ) != 1 )
6680
0
    {
6681
0
      libcerror_error_set(
6682
0
       error,
6683
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6684
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
6685
0
       "%s: unable to free sections cache.",
6686
0
       function );
6687
6688
0
      goto on_error;
6689
0
    }
6690
0
  }
6691
2.87k
  if( libfdata_list_element_set_element_value(
6692
2.87k
       element,
6693
2.87k
       (intptr_t *) file_io_pool,
6694
2.87k
       (libfdata_cache_t *) segment_file_cache,
6695
2.87k
       (intptr_t *) segment_file,
6696
2.87k
       (int (*)(intptr_t **, libcerror_error_t **)) &libewf_segment_file_free,
6697
2.87k
       LIBFDATA_LIST_ELEMENT_VALUE_FLAG_MANAGED,
6698
2.87k
       error ) != 1 )
6699
0
  {
6700
0
    libcerror_error_set(
6701
0
     error,
6702
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6703
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6704
0
     "%s: unable to set segment file as element value.",
6705
0
     function );
6706
6707
0
    goto on_error;
6708
0
  }
6709
2.87k
  return( 1 );
6710
6711
17
on_error:
6712
17
  if( sections_cache != NULL )
6713
0
  {
6714
0
    libfcache_cache_free(
6715
0
     &sections_cache,
6716
0
     NULL );
6717
0
  }
6718
17
  if( section_descriptor != NULL )
6719
0
  {
6720
0
    libewf_section_descriptor_free(
6721
0
     &section_descriptor,
6722
0
     NULL );
6723
0
  }
6724
17
  if( segment_file != NULL )
6725
17
  {
6726
17
    libewf_segment_file_free(
6727
17
     &segment_file,
6728
17
     NULL );
6729
17
  }
6730
17
  return( -1 );
6731
2.87k
}
6732
6733
/* Reads a section
6734
 * Callback function for the sections list
6735
 * Returns 1 if successful or -1 on error
6736
 */
6737
int libewf_segment_file_read_section_element_data(
6738
     libewf_segment_file_t *segment_file,
6739
     libbfio_pool_t *file_io_pool,
6740
     libfdata_list_element_t *element,
6741
     libfdata_cache_t *cache,
6742
     int file_io_pool_entry,
6743
     off64_t section_data_offset,
6744
     size64_t section_data_size LIBEWF_ATTRIBUTE_UNUSED,
6745
     uint32_t element_flags LIBEWF_ATTRIBUTE_UNUSED,
6746
     uint8_t read_flags LIBEWF_ATTRIBUTE_UNUSED,
6747
     libcerror_error_t **error )
6748
8.62k
{
6749
8.62k
  libewf_section_descriptor_t *section_descriptor = NULL;
6750
8.62k
  static char *function                           = "libewf_segment_file_read_section_element_data";
6751
8.62k
  ssize_t read_count                              = 0;
6752
6753
8.62k
  LIBEWF_UNREFERENCED_PARAMETER( section_data_size )
6754
8.62k
  LIBEWF_UNREFERENCED_PARAMETER( element_flags )
6755
8.62k
  LIBEWF_UNREFERENCED_PARAMETER( read_flags )
6756
6757
8.62k
  if( segment_file == NULL )
6758
0
  {
6759
0
    libcerror_error_set(
6760
0
     error,
6761
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6762
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6763
0
     "%s: invalid segment file.",
6764
0
     function );
6765
6766
0
    return( -1 );
6767
0
  }
6768
/* TODO validate section_data_size ? */
6769
8.62k
  if( libewf_section_descriptor_initialize(
6770
8.62k
       &section_descriptor,
6771
8.62k
       error ) != 1 )
6772
0
  {
6773
0
    libcerror_error_set(
6774
0
     error,
6775
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6776
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6777
0
     "%s: unable to create section descriptor.",
6778
0
     function );
6779
6780
0
    goto on_error;
6781
0
  }
6782
8.62k
  read_count = libewf_section_descriptor_read_file_io_pool(
6783
8.62k
          section_descriptor,
6784
8.62k
          file_io_pool,
6785
8.62k
          file_io_pool_entry,
6786
8.62k
          section_data_offset,
6787
8.62k
          segment_file->major_version,
6788
8.62k
          error );
6789
6790
8.62k
  if( read_count == -1 )
6791
0
  {
6792
0
    libcerror_error_set(
6793
0
     error,
6794
0
     LIBCERROR_ERROR_DOMAIN_IO,
6795
0
     LIBCERROR_IO_ERROR_READ_FAILED,
6796
0
     "%s: unable to read section descriptor.",
6797
0
     function );
6798
6799
0
    goto on_error;
6800
0
  }
6801
8.62k
  segment_file->current_offset = section_data_offset + read_count;
6802
6803
8.62k
  if( libfdata_list_element_set_element_value(
6804
8.62k
       element,
6805
8.62k
       (intptr_t *) file_io_pool,
6806
8.62k
       cache,
6807
8.62k
       (intptr_t *) section_descriptor,
6808
8.62k
       (int (*)(intptr_t **, libcerror_error_t **)) &libewf_section_descriptor_free,
6809
8.62k
       LIBFDATA_LIST_ELEMENT_VALUE_FLAG_MANAGED,
6810
8.62k
       error ) != 1 )
6811
0
  {
6812
0
    libcerror_error_set(
6813
0
     error,
6814
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6815
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6816
0
     "%s: unable to set section as element value.",
6817
0
     function );
6818
6819
0
    goto on_error;
6820
0
  }
6821
8.62k
  return( 1 );
6822
6823
0
on_error:
6824
0
  if( section_descriptor != NULL )
6825
0
  {
6826
0
    libewf_section_descriptor_free(
6827
0
     &section_descriptor,
6828
0
     NULL );
6829
0
  }
6830
0
  return( -1 );
6831
8.62k
}
6832
6833
/* Reads a chunk group
6834
 * Callback function for the chunk groups list
6835
 * Returns 1 if successful or -1 on error
6836
 */
6837
int libewf_segment_file_read_chunk_group_element_data(
6838
     libewf_segment_file_t *segment_file,
6839
     libbfio_pool_t *file_io_pool,
6840
     libfdata_list_element_t *element,
6841
     libfdata_cache_t *cache,
6842
     int file_io_pool_entry,
6843
     off64_t chunk_group_data_offset,
6844
     size64_t chunk_group_data_size,
6845
     uint32_t element_flags LIBEWF_ATTRIBUTE_UNUSED,
6846
     uint8_t read_flags LIBEWF_ATTRIBUTE_UNUSED,
6847
     libcerror_error_t **error )
6848
0
{
6849
0
  libewf_chunk_group_t *chunk_group               = NULL;
6850
0
  libewf_section_descriptor_t *section_descriptor = NULL;
6851
0
  libewf_table_section_t *table_section           = NULL;
6852
0
  static char *function                           = "libewf_segment_file_read_chunk_group_element_data";
6853
0
  ssize_t read_count                              = 0;
6854
0
  uint64_t chunk_index                            = 0;
6855
0
  int result                                      = 0;
6856
6857
#if defined( HAVE_DEBUG_OUTPUT )
6858
  size64_t chunk_group_range_size                 = 0;
6859
  off64_t chunk_group_range_offset                = 0;
6860
  int element_index                               = 0;
6861
#endif
6862
6863
0
  LIBEWF_UNREFERENCED_PARAMETER( element_flags )
6864
0
  LIBEWF_UNREFERENCED_PARAMETER( read_flags )
6865
6866
0
  if( segment_file == NULL )
6867
0
  {
6868
0
    libcerror_error_set(
6869
0
     error,
6870
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6871
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6872
0
     "%s: invalid segment file.",
6873
0
     function );
6874
6875
0
    return( -1 );
6876
0
  }
6877
0
  if( segment_file->chunk_groups_list == NULL )
6878
0
  {
6879
0
    libcerror_error_set(
6880
0
     error,
6881
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6882
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6883
0
     "%s: invalid segment file - missing chunk groups list.",
6884
0
     function );
6885
6886
0
    return( -1 );
6887
0
  }
6888
0
  if( segment_file->io_handle == NULL )
6889
0
  {
6890
0
    libcerror_error_set(
6891
0
     error,
6892
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6893
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6894
0
     "%s: invalid segment file - missing IO handle.",
6895
0
     function );
6896
6897
0
    return( -1 );
6898
0
  }
6899
0
  if( segment_file->io_handle->chunk_size == 0 )
6900
0
  {
6901
0
    libcerror_error_set(
6902
0
     error,
6903
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6904
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6905
0
     "%s: invalid segment file - invalid IO handle - missing chunk size.",
6906
0
     function );
6907
6908
0
    return( -1 );
6909
0
  }
6910
0
  if( libewf_section_descriptor_initialize(
6911
0
       &section_descriptor,
6912
0
       error ) != 1 )
6913
0
  {
6914
0
    libcerror_error_set(
6915
0
     error,
6916
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6917
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6918
0
     "%s: unable to create section descriptor.",
6919
0
     function );
6920
6921
0
    goto on_error;
6922
0
  }
6923
0
  if( segment_file->major_version == 1 )
6924
0
  {
6925
0
    read_count = libewf_section_descriptor_read_file_io_pool(
6926
0
            section_descriptor,
6927
0
            file_io_pool,
6928
0
            file_io_pool_entry,
6929
0
            chunk_group_data_offset,
6930
0
            segment_file->major_version,
6931
0
            error );
6932
6933
0
    if( read_count == -1 )
6934
0
    {
6935
0
      libcerror_error_set(
6936
0
       error,
6937
0
       LIBCERROR_ERROR_DOMAIN_IO,
6938
0
       LIBCERROR_IO_ERROR_READ_FAILED,
6939
0
       "%s: unable to read section descriptor.",
6940
0
       function );
6941
6942
0
      goto on_error;
6943
0
    }
6944
0
    segment_file->current_offset = chunk_group_data_offset + read_count;
6945
6946
0
    if( chunk_group_data_size != section_descriptor->size )
6947
0
    {
6948
0
      libcerror_error_set(
6949
0
       error,
6950
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6951
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
6952
0
       "%s: invalid chunk group data size value out of bounds.",
6953
0
       function );
6954
6955
0
      goto on_error;
6956
0
    }
6957
0
    chunk_group_data_size -= read_count;
6958
0
  }
6959
0
  else if( segment_file->major_version == 2 )
6960
0
  {
6961
0
    if( chunk_group_data_size > (size64_t) UINT32_MAX )
6962
0
    {
6963
0
      libcerror_error_set(
6964
0
       error,
6965
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6966
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
6967
0
       "%s: invalid chunk group data size value out of bounds.",
6968
0
       function );
6969
6970
0
      goto on_error;
6971
0
    }
6972
0
    if( libbfio_pool_seek_offset(
6973
0
         file_io_pool,
6974
0
         file_io_pool_entry,
6975
0
         chunk_group_data_offset,
6976
0
         SEEK_SET,
6977
0
         error ) == -1 )
6978
0
    {
6979
0
      libcerror_error_set(
6980
0
       error,
6981
0
       LIBCERROR_ERROR_DOMAIN_IO,
6982
0
       LIBCERROR_IO_ERROR_SEEK_FAILED,
6983
0
       "%s: unable to seek chunk table offset: %" PRIi64 " in file IO pool entry: %d.",
6984
0
       function,
6985
0
       chunk_group_data_offset,
6986
0
       file_io_pool_entry );
6987
6988
0
      goto on_error;
6989
0
    }
6990
0
    segment_file->current_offset     = chunk_group_data_offset;
6991
0
    section_descriptor->start_offset = chunk_group_data_offset;
6992
0
    section_descriptor->data_size    = (uint32_t) chunk_group_data_size;
6993
0
  }
6994
0
  if( libewf_table_section_initialize(
6995
0
       &table_section,
6996
0
       error ) != 1 )
6997
0
  {
6998
0
    libcerror_error_set(
6999
0
     error,
7000
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7001
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
7002
0
     "%s: unable to create table section.",
7003
0
     function );
7004
7005
0
    goto on_error;
7006
0
  }
7007
0
  read_count = libewf_table_section_read_file_io_pool(
7008
0
                table_section,
7009
0
                segment_file->io_handle,
7010
0
                file_io_pool,
7011
0
                file_io_pool_entry,
7012
0
                segment_file->major_version,
7013
0
                segment_file->type,
7014
0
                section_descriptor->data_size,
7015
0
                section_descriptor->data_flags,
7016
0
                error );
7017
7018
0
  if( read_count < 0 )
7019
0
  {
7020
0
    libcerror_error_set(
7021
0
     error,
7022
0
     LIBCERROR_ERROR_DOMAIN_IO,
7023
0
     LIBCERROR_IO_ERROR_READ_FAILED,
7024
0
     "%s: unable to read table section.",
7025
0
     function );
7026
7027
0
    goto on_error;
7028
0
  }
7029
0
  segment_file->current_offset += read_count;
7030
0
  chunk_group_data_size        -= read_count;
7031
7032
0
  if( table_section->number_of_entries == 0 )
7033
0
  {
7034
0
    libcerror_error_set(
7035
0
     error,
7036
0
     LIBCERROR_ERROR_DOMAIN_INPUT,
7037
0
     LIBCERROR_INPUT_ERROR_INVALID_DATA,
7038
0
     "%s: invalid number of entries.",
7039
0
     function );
7040
7041
0
    goto on_error;
7042
0
  }
7043
0
  if( libewf_chunk_group_initialize(
7044
0
       &chunk_group,
7045
0
       segment_file->io_handle,
7046
0
       error ) != 1 )
7047
0
  {
7048
0
    libcerror_error_set(
7049
0
     error,
7050
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7051
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
7052
0
     "%s: unable to create chunk group.",
7053
0
     function );
7054
7055
0
    goto on_error;
7056
0
  }
7057
#if defined( HAVE_DEBUG_OUTPUT )
7058
  if( libfdata_list_element_get_element_index(
7059
       element,
7060
       &element_index,
7061
       error ) != 1 )
7062
  {
7063
    libcerror_error_set(
7064
     error,
7065
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7066
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7067
     "%s: unable to retrieve chunk group list element index.",
7068
     function );
7069
7070
    goto on_error;
7071
  }
7072
  if( libfdata_list_get_element_mapped_range(
7073
       segment_file->chunk_groups_list,
7074
       element_index,
7075
       &chunk_group_range_offset,
7076
       &chunk_group_range_size,
7077
       error ) != 1 )
7078
  {
7079
    libcerror_error_set(
7080
     error,
7081
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7082
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7083
     "%s: unable to retrieve chunk group list element: %d mapped range.",
7084
     function,
7085
     element_index );
7086
7087
    goto on_error;
7088
  }
7089
  chunk_index = ( segment_file->range_start_offset + chunk_group_range_offset ) / segment_file->io_handle->chunk_size;
7090
7091
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
7092
7093
0
  if( segment_file->major_version == 1 )
7094
0
  {
7095
0
    result = libewf_chunk_group_fill_v1(
7096
0
        chunk_group,
7097
0
        chunk_index,
7098
0
        segment_file->io_handle->chunk_size,
7099
0
        file_io_pool_entry,
7100
0
        section_descriptor,
7101
0
        (off64_t) table_section->base_offset,
7102
0
        table_section->number_of_entries,
7103
0
        &( table_section->section_data[ table_section->entries_offset ] ),
7104
0
        table_section->entries_size,
7105
0
        table_section->entries_corrupted,
7106
0
        error );
7107
0
  }
7108
0
  else if( segment_file->major_version == 2 )
7109
0
  {
7110
0
    result = libewf_chunk_group_fill_v2(
7111
0
        chunk_group,
7112
0
        chunk_index,
7113
0
        segment_file->io_handle->chunk_size,
7114
0
        file_io_pool_entry,
7115
0
        section_descriptor,
7116
0
        table_section->number_of_entries,
7117
0
        &( table_section->section_data[ table_section->entries_offset ] ),
7118
0
        table_section->entries_size,
7119
0
        table_section->entries_corrupted,
7120
0
        error );
7121
0
  }
7122
0
  if( result != 1 )
7123
0
  {
7124
0
    libcerror_error_set(
7125
0
     error,
7126
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7127
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7128
0
     "%s: unable to fill chunks list.",
7129
0
     function );
7130
7131
0
    goto on_error;
7132
0
  }
7133
0
  if( libewf_table_section_free(
7134
0
       &table_section,
7135
0
       error ) != 1 )
7136
0
  {
7137
0
    libcerror_error_set(
7138
0
     error,
7139
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7140
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
7141
0
     "%s: unable to free table section.",
7142
0
     function );
7143
7144
0
    goto on_error;
7145
0
  }
7146
0
  if( libewf_section_descriptor_free(
7147
0
       &section_descriptor,
7148
0
       error ) != 1 )
7149
0
  {
7150
0
    libcerror_error_set(
7151
0
     error,
7152
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7153
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
7154
0
     "%s: unable to free section.",
7155
0
     function );
7156
7157
0
    goto on_error;
7158
0
  }
7159
/* TODO read and process backup range if available and neccessary
7160
  if( table_section->entries_corrupted != 0 )
7161
  {
7162
    if( segment_file->major_version == 1 )
7163
    {
7164
      result = libewf_chunk_group_correct_v1(
7165
          chunk_group,
7166
                chunk_index,
7167
                segment_file->io_handle->chunk_size,
7168
          file_io_pool_entry,
7169
          section_descriptor,
7170
          (off64_t) table_section->base_offset,
7171
          table_section->number_of_entries,
7172
          &( table_section->section_data[ table_section->entries_offset ] ),
7173
          table_section->entries_size,
7174
          table_section->entries_corrupted,
7175
          error );
7176
    }
7177
    if( result != 1 )
7178
    {
7179
      libcerror_error_set(
7180
       error,
7181
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7182
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7183
       "%s: unable to correct chunks list.",
7184
       function );
7185
7186
      goto on_error;
7187
    }
7188
  }
7189
*/
7190
0
  if( libfdata_list_element_set_element_value(
7191
0
       element,
7192
0
       (intptr_t *) file_io_pool,
7193
0
       cache,
7194
0
       (intptr_t *) chunk_group,
7195
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libewf_chunk_group_free,
7196
0
       LIBFDATA_LIST_ELEMENT_VALUE_FLAG_MANAGED,
7197
0
       error ) != 1 )
7198
0
  {
7199
0
    libcerror_error_set(
7200
0
     error,
7201
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7202
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7203
0
     "%s: unable to set section as element value.",
7204
0
     function );
7205
7206
0
    goto on_error;
7207
0
  }
7208
0
  return( 1 );
7209
7210
0
on_error:
7211
0
  if( chunk_group != NULL )
7212
0
  {
7213
0
    libewf_chunk_group_free(
7214
0
     &chunk_group,
7215
0
     NULL );
7216
0
  }
7217
0
  if( table_section != NULL )
7218
0
  {
7219
0
    libewf_table_section_free(
7220
0
     &table_section,
7221
0
     NULL );
7222
0
  }
7223
0
  if( section_descriptor != NULL )
7224
0
  {
7225
0
    libewf_section_descriptor_free(
7226
0
     &section_descriptor,
7227
0
     NULL );
7228
0
  }
7229
0
  return( -1 );
7230
0
}
7231
7232
/* Retrieves the chunk group at a specific offset
7233
 * Returns 1 if successful, 0 if not or -1 on error
7234
 */
7235
int libewf_segment_file_get_chunk_group_by_offset(
7236
     libewf_segment_file_t *segment_file,
7237
     libbfio_pool_t *file_io_pool,
7238
     off64_t offset,
7239
     int *chunk_group_index,
7240
     off64_t *chunk_group_data_offset,
7241
     libewf_chunk_group_t **chunk_group,
7242
     libcerror_error_t **error )
7243
0
{
7244
0
  libewf_chunk_group_t *safe_chunk_group = NULL;
7245
0
  static char *function                  = "libewf_segment_file_get_chunk_group_by_offset";
7246
0
  off64_t safe_chunk_group_data_offset   = 0;
7247
0
  int result                             = 0;
7248
0
  int safe_chunk_group_index             = 0;
7249
7250
0
  if( segment_file == NULL )
7251
0
  {
7252
0
    libcerror_error_set(
7253
0
     error,
7254
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7255
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7256
0
     "%s: invalid segment file.",
7257
0
     function );
7258
7259
0
    return( -1 );
7260
0
  }
7261
0
  if( chunk_group_index == NULL )
7262
0
  {
7263
0
    libcerror_error_set(
7264
0
     error,
7265
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7266
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7267
0
     "%s: invalid chunk group index.",
7268
0
     function );
7269
7270
0
    return( -1 );
7271
0
  }
7272
0
  if( chunk_group_data_offset == NULL )
7273
0
  {
7274
0
    libcerror_error_set(
7275
0
     error,
7276
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7277
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7278
0
     "%s: invalid chunk group data offset.",
7279
0
     function );
7280
7281
0
    return( -1 );
7282
0
  }
7283
0
  if( chunk_group == NULL )
7284
0
  {
7285
0
    libcerror_error_set(
7286
0
     error,
7287
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7288
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7289
0
     "%s: invalid chunk group.",
7290
0
     function );
7291
7292
0
    return( -1 );
7293
0
  }
7294
0
  result = libfdata_list_get_element_value_at_offset(
7295
0
      segment_file->chunk_groups_list,
7296
0
      (intptr_t *) file_io_pool,
7297
0
      (libfdata_cache_t *) segment_file->chunk_groups_cache,
7298
0
      offset,
7299
0
      &safe_chunk_group_index,
7300
0
      &safe_chunk_group_data_offset,
7301
0
      (intptr_t **) &safe_chunk_group,
7302
0
      0,
7303
0
      error );
7304
7305
0
  if( result == -1 )
7306
0
  {
7307
0
    libcerror_error_set(
7308
0
     error,
7309
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7310
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7311
0
     "%s: unable to retrieve chunks list at offset: 0x%08" PRIx64 ".",
7312
0
     function,
7313
0
     offset );
7314
7315
0
    return( -1 );
7316
0
  }
7317
0
  else if( result != 0 )
7318
0
  {
7319
0
    if( safe_chunk_group == NULL )
7320
0
    {
7321
0
      libcerror_error_set(
7322
0
       error,
7323
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7324
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7325
0
       "%s: missing chunk group.",
7326
0
       function );
7327
7328
0
      return( -1 );
7329
0
    }
7330
0
    segment_file->current_chunk_group_index = safe_chunk_group_index;
7331
7332
0
    if( libfdata_list_get_element_mapped_range(
7333
0
         segment_file->chunk_groups_list,
7334
0
         safe_chunk_group_index,
7335
0
         &( safe_chunk_group->range_start_offset ),
7336
0
         (size64_t *) &( safe_chunk_group->range_end_offset ),
7337
0
         error ) != 1 )
7338
0
    {
7339
0
      libcerror_error_set(
7340
0
       error,
7341
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7342
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7343
0
       "%s: unable to retrieve chunks list element: %d mapped range.",
7344
0
       function,
7345
0
       safe_chunk_group_index );
7346
7347
0
      return( -1 );
7348
0
    }
7349
0
    safe_chunk_group->range_start_offset += segment_file->range_start_offset;
7350
0
    safe_chunk_group->range_end_offset   += safe_chunk_group->range_start_offset;
7351
7352
0
    *chunk_group_index       = safe_chunk_group_index;
7353
0
    *chunk_group_data_offset = safe_chunk_group_data_offset;
7354
0
    *chunk_group             = safe_chunk_group;
7355
0
  }
7356
0
  return( result );
7357
0
}
7358