Coverage Report

Created: 2026-07-25 07:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libewf/libewf/libewf_handle.c
Line
Count
Source
1
/*
2
 * Handle functions
3
 *
4
 * Copyright (C) 2006-2026, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <narrow_string.h>
25
#include <types.h>
26
#include <wide_string.h>
27
28
#include "libewf_analytical_data.h"
29
#include "libewf_case_data.h"
30
#include "libewf_case_data_section.h"
31
#include "libewf_chunk_data.h"
32
#include "libewf_chunk_table.h"
33
#include "libewf_codepage.h"
34
#include "libewf_compression.h"
35
#include "libewf_data_chunk.h"
36
#include "libewf_data_stream.h"
37
#include "libewf_debug.h"
38
#include "libewf_definitions.h"
39
#include "libewf_device_information.h"
40
#include "libewf_device_information_section.h"
41
#include "libewf_digest_section.h"
42
#include "libewf_error2_section.h"
43
#include "libewf_file_entry.h"
44
#include "libewf_handle.h"
45
#include "libewf_hash_sections.h"
46
#include "libewf_hash_values.h"
47
#include "libewf_header_sections.h"
48
#include "libewf_header_values.h"
49
#include "libewf_io_handle.h"
50
#include "libewf_lef_file_entry.h"
51
#include "libewf_libbfio.h"
52
#include "libewf_libcdata.h"
53
#include "libewf_libcerror.h"
54
#include "libewf_libcnotify.h"
55
#include "libewf_libcthreads.h"
56
#include "libewf_libfcache.h"
57
#include "libewf_libfdata.h"
58
#include "libewf_libfvalue.h"
59
#include "libewf_libuna.h"
60
#include "libewf_ltree_section.h"
61
#include "libewf_md5_hash_section.h"
62
#include "libewf_restart_data.h"
63
#include "libewf_section.h"
64
#include "libewf_section_descriptor.h"
65
#include "libewf_sector_range.h"
66
#include "libewf_sector_range_list.h"
67
#include "libewf_segment_file.h"
68
#include "libewf_session_section.h"
69
#include "libewf_sha1_hash_section.h"
70
#include "libewf_single_file_tree.h"
71
#include "libewf_single_files.h"
72
#include "libewf_types.h"
73
#include "libewf_unused.h"
74
#include "libewf_value_table.h"
75
#include "libewf_write_io_handle.h"
76
77
#include "ewf_data.h"
78
#include "ewf_file_header.h"
79
80
/* Creates a handle
81
 * Make sure the value handle is referencing, is set to NULL
82
 * Returns 1 if successful or -1 on error
83
 */
84
int libewf_handle_initialize(
85
     libewf_handle_t **handle,
86
     libcerror_error_t **error )
87
3.31k
{
88
3.31k
  libewf_internal_handle_t *internal_handle = NULL;
89
3.31k
  static char *function                     = "libewf_handle_initialize";
90
91
3.31k
  if( handle == NULL )
92
0
  {
93
0
    libcerror_error_set(
94
0
     error,
95
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
96
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
97
0
     "%s: invalid handle.",
98
0
     function );
99
100
0
    return( -1 );
101
0
  }
102
3.31k
  if( *handle != NULL )
103
0
  {
104
0
    libcerror_error_set(
105
0
     error,
106
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
107
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
108
0
     "%s: invalid handle value already set.",
109
0
     function );
110
111
0
    return( -1 );
112
0
  }
113
3.31k
  internal_handle = memory_allocate_structure(
114
3.31k
                     libewf_internal_handle_t );
115
116
3.31k
  if( internal_handle == NULL )
117
0
  {
118
0
    libcerror_error_set(
119
0
     error,
120
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
121
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
122
0
     "%s: unable to create handle.",
123
0
     function );
124
125
0
    goto on_error;
126
0
  }
127
3.31k
  if( memory_set(
128
3.31k
       internal_handle,
129
3.31k
       0,
130
3.31k
       sizeof( libewf_internal_handle_t ) ) == NULL )
131
0
  {
132
0
    libcerror_error_set(
133
0
     error,
134
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
135
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
136
0
     "%s: unable to clear handle.",
137
0
     function );
138
139
0
    memory_free(
140
0
     internal_handle );
141
142
0
    return( -1 );
143
0
  }
144
3.31k
  if( libewf_io_handle_initialize(
145
3.31k
       &( internal_handle->io_handle ),
146
3.31k
       error ) != 1 )
147
0
  {
148
0
    libcerror_error_set(
149
0
     error,
150
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
151
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
152
0
     "%s: unable to create IO handle.",
153
0
     function );
154
155
0
    goto on_error;
156
0
  }
157
3.31k
  if( libewf_media_values_initialize(
158
3.31k
       &( internal_handle->media_values ),
159
3.31k
       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 media values.",
166
0
     function );
167
168
0
    goto on_error;
169
0
  }
170
3.31k
  if( libcdata_array_initialize(
171
3.31k
       &( internal_handle->sessions ),
172
3.31k
       0,
173
3.31k
       error ) != 1 )
174
0
  {
175
0
    libcerror_error_set(
176
0
     error,
177
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
178
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
179
0
     "%s: unable to create sessions array.",
180
0
     function );
181
182
0
    goto on_error;
183
0
  }
184
3.31k
  if( libcdata_array_initialize(
185
3.31k
       &( internal_handle->tracks ),
186
3.31k
       0,
187
3.31k
       error ) != 1 )
188
0
  {
189
0
    libcerror_error_set(
190
0
     error,
191
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
192
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
193
0
     "%s: unable to create tracks array.",
194
0
     function );
195
196
0
    goto on_error;
197
0
  }
198
3.31k
  if( libcdata_range_list_initialize(
199
3.31k
       &( internal_handle->acquiry_errors ),
200
3.31k
       error ) != 1 )
201
0
  {
202
0
    libcerror_error_set(
203
0
     error,
204
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
205
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
206
0
     "%s: unable to create acquiry errors range list.",
207
0
     function );
208
209
0
    goto on_error;
210
0
  }
211
3.31k
  if( libewf_segment_table_initialize(
212
3.31k
       &( internal_handle->segment_table ),
213
3.31k
       internal_handle->io_handle,
214
3.31k
       LIBEWF_DEFAULT_SEGMENT_FILE_SIZE,
215
3.31k
       error ) != 1 )
216
0
  {
217
0
    libcerror_error_set(
218
0
     error,
219
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
220
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
221
0
     "%s: unable to create segment table.",
222
0
     function );
223
224
0
    goto on_error;
225
0
  }
226
3.31k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
227
3.31k
  if( libcthreads_read_write_lock_initialize(
228
3.31k
       &( internal_handle->read_write_lock ),
229
3.31k
       error ) != 1 )
230
0
  {
231
0
    libcerror_error_set(
232
0
     error,
233
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
234
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
235
0
     "%s: unable to initialize read/write lock.",
236
0
     function );
237
238
0
    goto on_error;
239
0
  }
240
3.31k
#endif
241
3.31k
  internal_handle->date_format                    = LIBEWF_DATE_FORMAT_CTIME;
242
3.31k
  internal_handle->maximum_number_of_open_handles = LIBBFIO_POOL_UNLIMITED_NUMBER_OF_OPEN_HANDLES;
243
244
3.31k
  *handle = (libewf_handle_t *) internal_handle;
245
246
3.31k
  return( 1 );
247
248
0
on_error:
249
0
  if( internal_handle != NULL )
250
0
  {
251
0
    if( internal_handle->acquiry_errors != NULL )
252
0
    {
253
0
      libcdata_range_list_free(
254
0
       &( internal_handle->acquiry_errors ),
255
0
       NULL,
256
0
       NULL );
257
0
    }
258
0
    if( internal_handle->tracks != NULL )
259
0
    {
260
0
      libcdata_array_free(
261
0
       &( internal_handle->tracks ),
262
0
       NULL,
263
0
       NULL );
264
0
    }
265
0
    if( internal_handle->sessions != NULL )
266
0
    {
267
0
      libcdata_array_free(
268
0
       &( internal_handle->sessions ),
269
0
       NULL,
270
0
       NULL );
271
0
    }
272
0
    if( internal_handle->media_values != NULL )
273
0
    {
274
0
      libewf_media_values_free(
275
0
       &( internal_handle->media_values ),
276
0
       NULL );
277
0
    }
278
0
    if( internal_handle->io_handle != NULL )
279
0
    {
280
0
      libewf_io_handle_free(
281
0
       &( internal_handle->io_handle ),
282
0
       NULL );
283
0
    }
284
0
    memory_free(
285
0
     internal_handle );
286
0
  }
287
0
  return( -1 );
288
3.31k
}
289
290
/* Frees a handle
291
 * Returns 1 if successful or -1 on error
292
 */
293
int libewf_handle_free(
294
     libewf_handle_t **handle,
295
     libcerror_error_t **error )
296
3.31k
{
297
3.31k
  libewf_internal_handle_t *internal_handle = NULL;
298
3.31k
  static char *function                     = "libewf_internal_handle_free";
299
3.31k
  int result                                = 1;
300
301
3.31k
  if( handle == NULL )
302
0
  {
303
0
    libcerror_error_set(
304
0
     error,
305
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
306
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
307
0
     "%s: invalid handle.",
308
0
     function );
309
310
0
    return( -1 );
311
0
  }
312
3.31k
  if( *handle != NULL )
313
3.31k
  {
314
3.31k
    internal_handle = (libewf_internal_handle_t *) *handle;
315
316
3.31k
    if( internal_handle->file_io_pool != NULL )
317
1.16k
    {
318
1.16k
      if( libewf_handle_close(
319
1.16k
           *handle,
320
1.16k
           error ) != 0 )
321
0
      {
322
0
        libcerror_error_set(
323
0
         error,
324
0
         LIBCERROR_ERROR_DOMAIN_IO,
325
0
         LIBCERROR_IO_ERROR_CLOSE_FAILED,
326
0
         "%s: unable to close handle.",
327
0
         function );
328
329
0
        result = -1;
330
0
      }
331
1.16k
    }
332
3.31k
    *handle = NULL;
333
334
3.31k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
335
3.31k
    if( libcthreads_read_write_lock_free(
336
3.31k
         &( internal_handle->read_write_lock ),
337
3.31k
         error ) != 1 )
338
0
    {
339
0
      libcerror_error_set(
340
0
       error,
341
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
342
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
343
0
       "%s: unable to free read/write lock.",
344
0
       function );
345
346
0
      result = -1;
347
0
    }
348
3.31k
#endif
349
3.31k
    if( libewf_segment_table_free(
350
3.31k
         &( internal_handle->segment_table ),
351
3.31k
         error ) != 1 )
352
0
    {
353
0
      libcerror_error_set(
354
0
       error,
355
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
356
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
357
0
       "%s: unable to free segment table.",
358
0
       function );
359
360
0
      result = -1;
361
0
    }
362
3.31k
    if( libcdata_range_list_free(
363
3.31k
         &( internal_handle->acquiry_errors ),
364
3.31k
         NULL,
365
3.31k
         error ) != 1 )
366
0
    {
367
0
      libcerror_error_set(
368
0
       error,
369
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
370
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
371
0
       "%s: unable to free acquiry errors range list.",
372
0
       function );
373
374
0
      result = -1;
375
0
    }
376
3.31k
    if( libcdata_array_free(
377
3.31k
         &( internal_handle->tracks ),
378
3.31k
         (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
379
3.31k
         error ) != 1 )
380
0
    {
381
0
      libcerror_error_set(
382
0
       error,
383
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
384
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
385
0
       "%s: unable to free tracks array.",
386
0
       function );
387
388
0
      result = -1;
389
0
    }
390
3.31k
    if( libcdata_array_free(
391
3.31k
         &( internal_handle->sessions ),
392
3.31k
         (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
393
3.31k
         error ) != 1 )
394
0
    {
395
0
      libcerror_error_set(
396
0
       error,
397
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
398
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
399
0
       "%s: unable to free sessions array.",
400
0
       function );
401
402
0
      result = -1;
403
0
    }
404
3.31k
    if( libewf_media_values_free(
405
3.31k
         &( internal_handle->media_values ),
406
3.31k
         error ) != 1 )
407
0
    {
408
0
      libcerror_error_set(
409
0
       error,
410
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
411
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
412
0
       "%s: unable to free media values.",
413
0
       function );
414
415
0
      result = -1;
416
0
    }
417
3.31k
    if( libewf_io_handle_free(
418
3.31k
         &( internal_handle->io_handle ),
419
3.31k
         error ) != 1 )
420
0
    {
421
0
      libcerror_error_set(
422
0
       error,
423
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
424
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
425
0
       "%s: unable to free IO handle.",
426
0
       function );
427
428
0
      result = -1;
429
0
    }
430
3.31k
    memory_free(
431
3.31k
     internal_handle );
432
3.31k
  }
433
3.31k
  return( result );
434
3.31k
}
435
436
/* Clones the handle including elements
437
 * Returns 1 if successful or -1 on error
438
 */
439
int libewf_handle_clone(
440
     libewf_handle_t **destination_handle,
441
     libewf_handle_t *source_handle,
442
     libcerror_error_t **error )
443
0
{
444
0
  libewf_internal_handle_t *internal_destination_handle = NULL;
445
0
  libewf_internal_handle_t *internal_source_handle      = NULL;
446
0
  static char *function                                 = "libewf_handle_clone";
447
448
0
  if( destination_handle == NULL )
449
0
  {
450
0
    libcerror_error_set(
451
0
     error,
452
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
453
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
454
0
     "%s: invalid destination handle.",
455
0
     function );
456
457
0
    return( -1 );
458
0
  }
459
0
  if( *destination_handle != NULL )
460
0
  {
461
0
    libcerror_error_set(
462
0
     error,
463
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
464
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
465
0
     "%s: invalid destination handle value already set.",
466
0
     function );
467
468
0
    return( -1 );
469
0
  }
470
0
  if( source_handle == NULL )
471
0
  {
472
0
    *destination_handle = NULL;
473
474
0
    return( 1 );
475
0
  }
476
0
  internal_source_handle = (libewf_internal_handle_t *) source_handle;
477
478
0
  if( internal_source_handle->io_handle == NULL )
479
0
  {
480
0
    libcerror_error_set(
481
0
     error,
482
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
483
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
484
0
     "%s: invalid source handle - missing IO handle.",
485
0
     function );
486
487
0
    return( -1 );
488
0
  }
489
0
  if( ( internal_source_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
490
0
  {
491
0
    libcerror_error_set(
492
0
     error,
493
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
494
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
495
0
     "%s: write access currently not supported.",
496
0
     function );
497
498
0
    return( -1 );
499
0
  }
500
0
  internal_destination_handle = memory_allocate_structure(
501
0
                     libewf_internal_handle_t );
502
503
0
  if( internal_destination_handle == NULL )
504
0
  {
505
0
    libcerror_error_set(
506
0
     error,
507
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
508
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
509
0
     "%s: unable to create destination handle.",
510
0
     function );
511
512
0
    goto on_error;
513
0
  }
514
0
  if( memory_set(
515
0
       internal_destination_handle,
516
0
       0,
517
0
       sizeof( libewf_internal_handle_t ) ) == NULL )
518
0
  {
519
0
    libcerror_error_set(
520
0
     error,
521
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
522
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
523
0
     "%s: unable to clear destination handle.",
524
0
     function );
525
526
0
    goto on_error;
527
0
  }
528
0
  if( libewf_io_handle_clone(
529
0
       &( internal_destination_handle->io_handle ),
530
0
       internal_source_handle->io_handle,
531
0
       error ) != 1 )
532
0
  {
533
0
    libcerror_error_set(
534
0
     error,
535
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
536
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
537
0
     "%s: unable to create destination IO handle.",
538
0
     function );
539
540
0
    goto on_error;
541
0
  }
542
0
  if( libewf_media_values_clone(
543
0
       &( internal_destination_handle->media_values ),
544
0
       internal_source_handle->media_values,
545
0
       error ) != 1 )
546
0
  {
547
0
    libcerror_error_set(
548
0
     error,
549
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
550
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
551
0
     "%s: unable to create destination media values.",
552
0
     function );
553
554
0
    goto on_error;
555
0
  }
556
0
  if( libcdata_array_clone(
557
0
       &( internal_destination_handle->sessions ),
558
0
       internal_source_handle->sessions,
559
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
560
0
       (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libewf_sector_range_clone,
561
0
       error ) != 1 )
562
0
  {
563
0
    libcerror_error_set(
564
0
     error,
565
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
566
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
567
0
     "%s: unable to create destination sessions array.",
568
0
     function );
569
570
0
    goto on_error;
571
0
  }
572
0
  if( libcdata_array_clone(
573
0
       &( internal_destination_handle->tracks ),
574
0
       internal_source_handle->tracks,
575
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
576
0
       (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libewf_sector_range_clone,
577
0
       error ) != 1 )
578
0
  {
579
0
    libcerror_error_set(
580
0
     error,
581
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
582
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
583
0
     "%s: unable to create destination tracks array.",
584
0
     function );
585
586
0
    goto on_error;
587
0
  }
588
0
  if( libcdata_range_list_clone(
589
0
       &( internal_destination_handle->acquiry_errors ),
590
0
       internal_source_handle->acquiry_errors,
591
0
       NULL,
592
0
       NULL,
593
0
       error ) != 1 )
594
0
  {
595
0
    libcerror_error_set(
596
0
     error,
597
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
598
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
599
0
     "%s: unable to create destination acquiry errors range list.",
600
0
     function );
601
602
0
    goto on_error;
603
0
  }
604
0
  if( internal_source_handle->file_io_pool != NULL )
605
0
  {
606
0
    if( libbfio_pool_clone(
607
0
         &( internal_destination_handle->file_io_pool ),
608
0
         internal_source_handle->file_io_pool,
609
0
         error ) != 1 )
610
0
    {
611
0
      libcerror_error_set(
612
0
       error,
613
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
614
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
615
0
       "%s: unable to create destination file IO pool.",
616
0
       function );
617
618
0
      goto on_error;
619
0
    }
620
0
    internal_destination_handle->file_io_pool_created_in_library = 1;
621
0
  }
622
0
  if( internal_source_handle->read_io_handle != NULL )
623
0
  {
624
0
    if( libewf_read_io_handle_clone(
625
0
         &( internal_destination_handle->read_io_handle ),
626
0
         internal_source_handle->read_io_handle,
627
0
         error ) != 1 )
628
0
    {
629
0
      libcerror_error_set(
630
0
       error,
631
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
632
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
633
0
       "%s: unable to create destination read IO handle.",
634
0
       function );
635
636
0
      goto on_error;
637
0
    }
638
0
  }
639
0
  if( internal_source_handle->write_io_handle != NULL )
640
0
  {
641
0
    if( libewf_write_io_handle_clone(
642
0
         &( internal_destination_handle->write_io_handle ),
643
0
         internal_source_handle->write_io_handle,
644
0
         error ) != 1 )
645
0
    {
646
0
      libcerror_error_set(
647
0
       error,
648
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
649
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
650
0
       "%s: unable to create destination write IO handle.",
651
0
       function );
652
653
0
      goto on_error;
654
0
    }
655
0
  }
656
0
  if( libewf_segment_table_clone(
657
0
       &( internal_destination_handle->segment_table ),
658
0
       internal_source_handle->segment_table,
659
0
       error ) != 1 )
660
0
  {
661
0
    libcerror_error_set(
662
0
     error,
663
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
664
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
665
0
     "%s: unable to create destination segment table.",
666
0
     function );
667
668
0
    goto on_error;
669
0
  }
670
0
  if( internal_source_handle->chunk_table != NULL )
671
0
  {
672
0
    if( libewf_chunk_table_clone(
673
0
         &( internal_destination_handle->chunk_table ),
674
0
         internal_source_handle->chunk_table,
675
0
         error ) != 1 )
676
0
    {
677
0
      libcerror_error_set(
678
0
       error,
679
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
680
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
681
0
       "%s: unable to create destination chunk table.",
682
0
       function );
683
684
0
      goto on_error;
685
0
    }
686
0
  }
687
0
  if( internal_source_handle->hash_sections != NULL )
688
0
  {
689
0
    if( libewf_hash_sections_clone(
690
0
         &( internal_destination_handle->hash_sections ),
691
0
         internal_source_handle->hash_sections,
692
0
         error ) != 1 )
693
0
    {
694
0
      libcerror_error_set(
695
0
       error,
696
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
697
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
698
0
       "%s: unable to create destination hash sections.",
699
0
       function );
700
701
0
      goto on_error;
702
0
    }
703
0
  }
704
0
  if( internal_source_handle->header_values != NULL )
705
0
  {
706
0
    if( libfvalue_table_clone(
707
0
         &( internal_destination_handle->header_values ),
708
0
         internal_source_handle->header_values,
709
0
         error ) != 1 )
710
0
    {
711
0
      libcerror_error_set(
712
0
       error,
713
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
714
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
715
0
       "%s: unable to create destination header values.",
716
0
       function );
717
718
0
      goto on_error;
719
0
    }
720
0
    internal_destination_handle->header_values_parsed = internal_source_handle->header_values_parsed;
721
0
  }
722
0
  if( internal_source_handle->hash_values != NULL )
723
0
  {
724
0
    if( libfvalue_table_clone(
725
0
         &( internal_destination_handle->hash_values ),
726
0
         internal_source_handle->hash_values,
727
0
         error ) != 1 )
728
0
    {
729
0
      libcerror_error_set(
730
0
       error,
731
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
732
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
733
0
       "%s: unable to create destination hash values.",
734
0
       function );
735
736
0
      goto on_error;
737
0
    }
738
0
    internal_destination_handle->hash_values_parsed = internal_source_handle->hash_values_parsed;
739
0
  }
740
0
  internal_destination_handle->maximum_number_of_open_handles = internal_source_handle->maximum_number_of_open_handles;
741
0
  internal_destination_handle->date_format                    = internal_source_handle->date_format;
742
743
0
  *destination_handle = (libewf_handle_t *) internal_destination_handle;
744
745
0
  return( 1 );
746
747
0
on_error:
748
0
  if( internal_destination_handle != NULL )
749
0
  {
750
0
    if( internal_destination_handle->hash_values != NULL )
751
0
    {
752
0
      libfvalue_table_free(
753
0
       &( internal_destination_handle->hash_values ),
754
0
       NULL );
755
0
    }
756
0
    if( internal_destination_handle->header_values != NULL )
757
0
    {
758
0
      libfvalue_table_free(
759
0
       &( internal_destination_handle->header_values ),
760
0
       NULL );
761
0
    }
762
0
    if( internal_destination_handle->hash_sections != NULL )
763
0
    {
764
0
      libewf_hash_sections_free(
765
0
       &( internal_destination_handle->hash_sections ),
766
0
       NULL );
767
0
    }
768
0
    if( internal_destination_handle->chunk_table != NULL )
769
0
    {
770
0
      libewf_chunk_table_free(
771
0
       &( internal_destination_handle->chunk_table ),
772
0
       NULL );
773
0
    }
774
0
    if( internal_destination_handle->segment_table != NULL )
775
0
    {
776
0
      libewf_segment_table_free(
777
0
       &( internal_destination_handle->segment_table ),
778
0
       NULL );
779
0
    }
780
0
    if( internal_destination_handle->write_io_handle != NULL )
781
0
    {
782
0
      libewf_write_io_handle_free(
783
0
       &( internal_destination_handle->write_io_handle ),
784
0
       NULL );
785
0
    }
786
0
    if( internal_destination_handle->read_io_handle != NULL )
787
0
    {
788
0
      libewf_read_io_handle_free(
789
0
       &( internal_destination_handle->read_io_handle ),
790
0
       NULL );
791
0
    }
792
0
    if( internal_destination_handle->file_io_pool != NULL )
793
0
    {
794
0
      libbfio_pool_free(
795
0
       &( internal_destination_handle->file_io_pool ),
796
0
       NULL );
797
0
    }
798
0
    if( internal_destination_handle->acquiry_errors != NULL )
799
0
    {
800
0
      libcdata_range_list_free(
801
0
       &( internal_destination_handle->acquiry_errors ),
802
0
       NULL,
803
0
       NULL );
804
0
    }
805
0
    if( internal_destination_handle->tracks != NULL )
806
0
    {
807
0
      libcdata_array_free(
808
0
       &( internal_destination_handle->tracks ),
809
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
810
0
       NULL );
811
0
    }
812
0
    if( internal_destination_handle->sessions != NULL )
813
0
    {
814
0
      libcdata_array_free(
815
0
       &( internal_destination_handle->sessions ),
816
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
817
0
       NULL );
818
0
    }
819
0
    if( internal_destination_handle->media_values != NULL )
820
0
    {
821
0
      libewf_media_values_free(
822
0
       &( internal_destination_handle->media_values ),
823
0
       NULL );
824
0
    }
825
0
    if( internal_destination_handle->io_handle != NULL )
826
0
    {
827
0
      libewf_io_handle_free(
828
0
       &( internal_destination_handle->io_handle ),
829
0
       NULL );
830
0
    }
831
0
    memory_free(
832
0
     internal_destination_handle );
833
0
  }
834
0
  return( -1 );
835
0
}
836
837
/* Signals the handle to abort its current activity
838
 * Returns 1 if successful or -1 on error
839
 */
840
int libewf_handle_signal_abort(
841
     libewf_handle_t *handle,
842
     libcerror_error_t **error )
843
0
{
844
0
  libewf_internal_handle_t *internal_handle = NULL;
845
0
  static char *function                     = "libewf_handle_signal_abort";
846
847
0
  if( handle == NULL )
848
0
  {
849
0
    libcerror_error_set(
850
0
     error,
851
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
852
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
853
0
     "%s: invalid handle.",
854
0
     function );
855
856
0
    return( -1 );
857
0
  }
858
0
  internal_handle = (libewf_internal_handle_t *) handle;
859
860
0
  if( internal_handle->io_handle == NULL )
861
0
  {
862
0
    libcerror_error_set(
863
0
     error,
864
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
865
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
866
0
     "%s: invalid handle - missing IO handle.",
867
0
     function );
868
869
0
    return( -1 );
870
0
  }
871
0
  internal_handle->io_handle->abort = 1;
872
873
0
  return( 1 );
874
0
}
875
876
/* Opens a set of EWF file(s)
877
 * For reading files should contain all filenames that make up an EWF image
878
 * For writing files should contain the base of the filename, extensions like .e01 will be automatically added
879
 * Returns 1 if successful or -1 on error
880
 */
881
int libewf_handle_open(
882
     libewf_handle_t *handle,
883
     char * const filenames[],
884
     int number_of_filenames,
885
     int access_flags,
886
     libcerror_error_t **error )
887
0
{
888
0
  libbfio_handle_t *file_io_handle          = NULL;
889
0
  libbfio_pool_t *file_io_pool              = NULL;
890
0
  libewf_internal_handle_t *internal_handle = NULL;
891
0
  char *first_segment_filename              = NULL;
892
0
  static char *function                     = "libewf_handle_open";
893
0
  size_t filename_length                    = 0;
894
0
  int file_io_pool_entry                    = 0;
895
0
  int filename_index                        = 0;
896
0
  int maximum_number_of_open_handles        = 0;
897
0
  int result                                = 0;
898
899
0
  if( handle == NULL )
900
0
  {
901
0
    libcerror_error_set(
902
0
     error,
903
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
904
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
905
0
     "%s: invalid handle.",
906
0
     function );
907
908
0
    return( -1 );
909
0
  }
910
0
  internal_handle = (libewf_internal_handle_t *) handle;
911
912
0
  if( filenames == NULL )
913
0
  {
914
0
    libcerror_error_set(
915
0
     error,
916
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
917
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
918
0
     "%s: invalid filenames.",
919
0
     function );
920
921
0
    return( -1 );
922
0
  }
923
0
  if( number_of_filenames <= 0 )
924
0
  {
925
0
    libcerror_error_set(
926
0
     error,
927
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
928
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_ZERO_OR_LESS,
929
0
     "%s: invalid number of files zero or less.",
930
0
     function );
931
932
0
    return( -1 );
933
0
  }
934
0
#if !defined( HAVE_WRITE_SUPPORT )
935
0
  if( ( access_flags & LIBEWF_ACCESS_FLAG_WRITE ) != 0 )
936
0
  {
937
0
    libcerror_error_set(
938
0
     error,
939
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
940
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
941
0
     "%s: write access currently not supported - compiled without zlib.",
942
0
     function );
943
944
0
    return( -1 );
945
0
  }
946
0
#endif
947
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
948
0
  if( libcthreads_read_write_lock_grab_for_read(
949
0
       internal_handle->read_write_lock,
950
0
       error ) != 1 )
951
0
  {
952
0
    libcerror_error_set(
953
0
     error,
954
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
955
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
956
0
     "%s: unable to grab read/write lock for reading.",
957
0
     function );
958
959
0
    return( -1 );
960
0
  }
961
0
#endif
962
0
  maximum_number_of_open_handles = internal_handle->maximum_number_of_open_handles;
963
964
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
965
0
  if( libcthreads_read_write_lock_release_for_read(
966
0
       internal_handle->read_write_lock,
967
0
       error ) != 1 )
968
0
  {
969
0
    libcerror_error_set(
970
0
     error,
971
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
972
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
973
0
     "%s: unable to release read/write lock for reading.",
974
0
     function );
975
976
0
    return( -1 );
977
0
  }
978
0
#endif
979
0
  if( libbfio_pool_initialize(
980
0
       &file_io_pool,
981
0
       0,
982
0
       maximum_number_of_open_handles,
983
0
       error ) != 1 )
984
0
  {
985
0
    libcerror_error_set(
986
0
     error,
987
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
988
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
989
0
     "%s: unable to create file IO pool.",
990
0
     function );
991
992
0
    goto on_error;
993
0
  }
994
0
  if( ( ( access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
995
0
   || ( ( access_flags & LIBEWF_ACCESS_FLAG_RESUME ) != 0 ) )
996
0
  {
997
0
    for( filename_index = 0;
998
0
         filename_index < number_of_filenames;
999
0
         filename_index++ )
1000
0
    {
1001
0
      filename_length = narrow_string_length(
1002
0
             filenames[ filename_index ] );
1003
1004
      /* Make sure there is more to the filename than the extension
1005
       */
1006
0
      if( filename_length <= 4 )
1007
0
      {
1008
0
        libcerror_error_set(
1009
0
         error,
1010
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1011
0
         LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1012
0
         "%s: filename: %s is too small.",
1013
0
         function,
1014
0
         filenames[ filename_index ] );
1015
1016
0
        goto on_error;
1017
0
      }
1018
0
      if( libbfio_file_initialize(
1019
0
           &file_io_handle,
1020
0
           error ) != 1 )
1021
0
      {
1022
0
        libcerror_error_set(
1023
0
         error,
1024
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1025
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1026
0
         "%s: unable to create file IO handle.",
1027
0
         function );
1028
1029
0
        goto on_error;
1030
0
      }
1031
#if defined( HAVE_DEBUG_OUTPUT )
1032
      if( libbfio_handle_set_track_offsets_read(
1033
           file_io_handle,
1034
           1,
1035
           error ) != 1 )
1036
      {
1037
                    libcerror_error_set(
1038
                     error,
1039
                     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1040
                     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1041
                     "%s: unable to set track offsets read in file IO handle.",
1042
                     function );
1043
1044
        goto on_error;
1045
      }
1046
#endif
1047
0
      if( libbfio_file_set_name(
1048
0
           file_io_handle,
1049
0
           filenames[ filename_index ],
1050
0
           filename_length,
1051
0
           error ) != 1 )
1052
0
      {
1053
0
        libcerror_error_set(
1054
0
         error,
1055
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1056
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1057
0
         "%s: unable to set name in file IO handle.",
1058
0
         function );
1059
1060
0
        goto on_error;
1061
0
      }
1062
0
      if( libbfio_pool_append_handle(
1063
0
           file_io_pool,
1064
0
           &file_io_pool_entry,
1065
0
           file_io_handle,
1066
0
           LIBBFIO_OPEN_READ,
1067
0
           error ) != 1 )
1068
0
      {
1069
0
        libcerror_error_set(
1070
0
         error,
1071
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1072
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1073
0
         "%s: unable to append file IO handle to pool.",
1074
0
         function );
1075
1076
0
        goto on_error;
1077
0
      }
1078
0
      file_io_handle = NULL;
1079
1080
#if defined( HAVE_DEBUG_OUTPUT )
1081
      if( libcnotify_verbose != 0 )
1082
      {
1083
        libcnotify_printf(
1084
         "%s: added file IO pool entry: %d with filename: %s.\n",
1085
         function,
1086
         file_io_pool_entry,
1087
         filenames[ filename_index ] );
1088
      }
1089
#endif
1090
0
      if( ( filenames[ filename_index ][ filename_length - 3 ] == 'e' )
1091
0
       || ( filenames[ filename_index ][ filename_length - 3 ] == 'E' )
1092
0
       || ( filenames[ filename_index ][ filename_length - 3 ] == 'l' )
1093
0
       || ( filenames[ filename_index ][ filename_length - 3 ] == 'L' )
1094
0
       || ( filenames[ filename_index ][ filename_length - 3 ] == 's' )
1095
0
       || ( filenames[ filename_index ][ filename_length - 3 ] == 'S' ) )
1096
0
      {
1097
0
        if( ( filenames[ filename_index ][ filename_length - 2 ] == '0' )
1098
0
         && ( filenames[ filename_index ][ filename_length - 1 ] == '1' ) )
1099
0
        {
1100
0
          first_segment_filename = filenames[ filename_index ];
1101
0
        }
1102
0
      }
1103
0
    }
1104
0
  }
1105
0
  if( ( ( access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
1106
0
   || ( ( access_flags & LIBEWF_ACCESS_FLAG_RESUME ) != 0 ) )
1107
0
  {
1108
    /* Get the basename of the first segment file
1109
     */
1110
0
    if( first_segment_filename != NULL )
1111
0
    {
1112
0
      filename_length = narrow_string_length(
1113
0
             first_segment_filename );
1114
1115
      /* Set segment table basename
1116
       */
1117
0
      if( libewf_segment_table_set_basename(
1118
0
           internal_handle->segment_table,
1119
0
           first_segment_filename,
1120
0
           filename_length - 4,
1121
0
           error ) != 1 )
1122
0
      {
1123
0
        libcerror_error_set(
1124
0
         error,
1125
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1126
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1127
0
         "%s: unable to set basename in segment table.",
1128
0
         function );
1129
1130
0
        goto on_error;
1131
0
      }
1132
0
    }
1133
0
  }
1134
0
  else if( ( access_flags & LIBEWF_ACCESS_FLAG_WRITE ) != 0 )
1135
0
  {
1136
    /* Get the basename and store it in the segment tables
1137
     */
1138
0
    filename_length = narrow_string_length(
1139
0
           filenames[ 0 ] );
1140
1141
    /* Set segment table basename
1142
     */
1143
0
    if( libewf_segment_table_set_basename(
1144
0
         internal_handle->segment_table,
1145
0
         filenames[ 0 ],
1146
0
         filename_length,
1147
0
         error ) != 1 )
1148
0
    {
1149
0
      libcerror_error_set(
1150
0
       error,
1151
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1152
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1153
0
       "%s: unable to set basename in segment table.",
1154
0
       function );
1155
1156
0
      goto on_error;
1157
0
    }
1158
0
  }
1159
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
1160
0
  if( libcthreads_read_write_lock_grab_for_write(
1161
0
       internal_handle->read_write_lock,
1162
0
       error ) != 1 )
1163
0
  {
1164
0
    libcerror_error_set(
1165
0
     error,
1166
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1167
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1168
0
     "%s: unable to grab read/write lock for writing.",
1169
0
     function );
1170
1171
0
    goto on_error;
1172
0
  }
1173
0
#endif
1174
0
  result = libewf_internal_handle_open_file_io_pool(
1175
0
            internal_handle,
1176
0
            file_io_pool,
1177
0
            access_flags,
1178
0
            internal_handle->segment_table,
1179
0
            error );
1180
1181
0
  if( result != 1 )
1182
0
  {
1183
0
    libcerror_error_set(
1184
0
     error,
1185
0
     LIBCERROR_ERROR_DOMAIN_IO,
1186
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
1187
0
     "%s: unable to open handle using a file IO pool.",
1188
0
     function );
1189
1190
0
    libbfio_pool_free(
1191
0
     &file_io_pool,
1192
0
     NULL );
1193
1194
0
    result = -1;
1195
0
  }
1196
0
  else
1197
0
  {
1198
0
    internal_handle->file_io_pool                    = file_io_pool;
1199
0
    internal_handle->file_io_pool_created_in_library = 1;
1200
0
  }
1201
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
1202
0
  if( libcthreads_read_write_lock_release_for_write(
1203
0
       internal_handle->read_write_lock,
1204
0
       error ) != 1 )
1205
0
  {
1206
0
    libcerror_error_set(
1207
0
     error,
1208
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1209
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1210
0
     "%s: unable to release read/write lock for writing.",
1211
0
     function );
1212
1213
0
    result = -1;
1214
0
  }
1215
0
#endif
1216
0
  if( result != 1 )
1217
0
  {
1218
0
    goto on_error;
1219
0
  }
1220
0
  return( 1 );
1221
1222
0
on_error:
1223
0
  if( file_io_handle != NULL )
1224
0
  {
1225
0
    libbfio_handle_free(
1226
0
     &file_io_handle,
1227
0
     NULL );
1228
0
  }
1229
0
  if( file_io_pool != NULL )
1230
0
  {
1231
0
    libbfio_pool_free(
1232
0
     &file_io_pool,
1233
0
     NULL );
1234
0
  }
1235
0
  internal_handle->file_io_pool                    = NULL;
1236
0
  internal_handle->file_io_pool_created_in_library = 0;
1237
1238
0
  return( -1 );
1239
0
}
1240
1241
#if defined( HAVE_WIDE_CHARACTER_TYPE )
1242
1243
/* Opens a set of EWF file(s)
1244
 * For reading files should contain all filenames that make up an EWF image
1245
 * For writing files should contain the base of the filename, extensions like .e01 will be automatically added
1246
 * Returns 1 if successful or -1 on error
1247
 */
1248
int libewf_handle_open_wide(
1249
     libewf_handle_t *handle,
1250
     wchar_t * const filenames[],
1251
     int number_of_filenames,
1252
     int access_flags,
1253
     libcerror_error_t **error )
1254
{
1255
  libbfio_handle_t *file_io_handle          = NULL;
1256
  libbfio_pool_t *file_io_pool              = NULL;
1257
  libewf_internal_handle_t *internal_handle = NULL;
1258
  wchar_t *first_segment_filename           = NULL;
1259
  static char *function                     = "libewf_handle_open_wide";
1260
  size_t filename_length                    = 0;
1261
  int file_io_pool_entry                    = 0;
1262
  int filename_index                        = 0;
1263
  int maximum_number_of_open_handles        = 0;
1264
  int result                                = 0;
1265
1266
  if( handle == NULL )
1267
  {
1268
    libcerror_error_set(
1269
     error,
1270
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1271
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1272
     "%s: invalid handle.",
1273
     function );
1274
1275
    return( -1 );
1276
  }
1277
  internal_handle = (libewf_internal_handle_t *) handle;
1278
1279
  if( filenames == NULL )
1280
  {
1281
    libcerror_error_set(
1282
     error,
1283
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1284
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1285
     "%s: invalid filenames.",
1286
     function );
1287
1288
    return( -1 );
1289
  }
1290
  if( number_of_filenames <= 0 )
1291
  {
1292
    libcerror_error_set(
1293
     error,
1294
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1295
     LIBCERROR_ARGUMENT_ERROR_VALUE_ZERO_OR_LESS,
1296
     "%s: invalid number of files zero or less.",
1297
     function );
1298
1299
    return( -1 );
1300
  }
1301
#if !defined( HAVE_WRITE_SUPPORT )
1302
  if( ( access_flags & LIBEWF_ACCESS_FLAG_WRITE ) != 0 )
1303
  {
1304
    libcerror_error_set(
1305
     error,
1306
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1307
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1308
     "%s: write access currently not supported - compiled without zlib.",
1309
     function );
1310
1311
    return( -1 );
1312
  }
1313
#endif
1314
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
1315
  if( libcthreads_read_write_lock_grab_for_read(
1316
       internal_handle->read_write_lock,
1317
       error ) != 1 )
1318
  {
1319
    libcerror_error_set(
1320
     error,
1321
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1322
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1323
     "%s: unable to grab read/write lock for reading.",
1324
     function );
1325
1326
    return( -1 );
1327
  }
1328
#endif
1329
  maximum_number_of_open_handles = internal_handle->maximum_number_of_open_handles;
1330
1331
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
1332
  if( libcthreads_read_write_lock_release_for_read(
1333
       internal_handle->read_write_lock,
1334
       error ) != 1 )
1335
  {
1336
    libcerror_error_set(
1337
     error,
1338
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1339
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1340
     "%s: unable to release read/write lock for reading.",
1341
     function );
1342
1343
    return( -1 );
1344
  }
1345
#endif
1346
  if( libbfio_pool_initialize(
1347
       &file_io_pool,
1348
       0,
1349
       maximum_number_of_open_handles,
1350
       error ) != 1 )
1351
  {
1352
    libcerror_error_set(
1353
     error,
1354
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1355
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1356
     "%s: unable to create file IO pool.",
1357
     function );
1358
1359
    goto on_error;
1360
  }
1361
  if( ( ( access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
1362
   || ( ( access_flags & LIBEWF_ACCESS_FLAG_RESUME ) != 0 ) )
1363
  {
1364
    for( filename_index = 0;
1365
         filename_index < number_of_filenames;
1366
         filename_index++ )
1367
    {
1368
      filename_length = wide_string_length(
1369
             filenames[ filename_index ] );
1370
1371
      /* Make sure there is more to the filename than the extension
1372
       */
1373
      if( filename_length <= 4 )
1374
      {
1375
        libcerror_error_set(
1376
         error,
1377
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1378
         LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1379
         "%s: filename: %ls is too small.",
1380
         function,
1381
         filenames[ filename_index ] );
1382
1383
        goto on_error;
1384
      }
1385
      if( libbfio_file_initialize(
1386
           &file_io_handle,
1387
           error ) != 1 )
1388
      {
1389
        libcerror_error_set(
1390
         error,
1391
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1392
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1393
         "%s: unable to create file IO handle.",
1394
         function );
1395
1396
        goto on_error;
1397
      }
1398
#if defined( HAVE_DEBUG_OUTPUT )
1399
      if( libbfio_handle_set_track_offsets_read(
1400
           file_io_handle,
1401
           1,
1402
           error ) != 1 )
1403
      {
1404
                    libcerror_error_set(
1405
                     error,
1406
                     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1407
                     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1408
                     "%s: unable to set track offsets read in file IO handle.",
1409
                     function );
1410
1411
        goto on_error;
1412
      }
1413
#endif
1414
      if( libbfio_file_set_name_wide(
1415
           file_io_handle,
1416
           filenames[ filename_index ],
1417
           filename_length,
1418
           error ) != 1 )
1419
      {
1420
        libcerror_error_set(
1421
         error,
1422
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1423
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1424
         "%s: unable to set name in file IO handle.",
1425
         function );
1426
1427
        goto on_error;
1428
      }
1429
      if( libbfio_pool_append_handle(
1430
           file_io_pool,
1431
           &file_io_pool_entry,
1432
           file_io_handle,
1433
           LIBBFIO_OPEN_READ,
1434
           error ) != 1 )
1435
      {
1436
        libcerror_error_set(
1437
         error,
1438
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1439
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1440
         "%s: unable to append file IO handle to pool.",
1441
         function );
1442
1443
        goto on_error;
1444
      }
1445
      file_io_handle = NULL;
1446
1447
#if defined( HAVE_DEBUG_OUTPUT )
1448
      if( libcnotify_verbose != 0 )
1449
      {
1450
        libcnotify_printf(
1451
         "%s: added file IO pool entry: %d with filename: %ls.\n",
1452
         function,
1453
         file_io_pool_entry,
1454
         filenames[ filename_index ] );
1455
      }
1456
#endif
1457
      if( ( filenames[ filename_index ][ filename_length - 3 ] == 'e' )
1458
       || ( filenames[ filename_index ][ filename_length - 3 ] == 'E' )
1459
       || ( filenames[ filename_index ][ filename_length - 3 ] == 'l' )
1460
       || ( filenames[ filename_index ][ filename_length - 3 ] == 'L' )
1461
       || ( filenames[ filename_index ][ filename_length - 3 ] == 's' )
1462
       || ( filenames[ filename_index ][ filename_length - 3 ] == 'S' ) )
1463
      {
1464
        if( ( filenames[ filename_index ][ filename_length - 2 ] == '0' )
1465
         && ( filenames[ filename_index ][ filename_length - 1 ] == '1' ) )
1466
        {
1467
          first_segment_filename = filenames[ filename_index ];
1468
        }
1469
      }
1470
    }
1471
  }
1472
  if( ( ( access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
1473
   || ( ( access_flags & LIBEWF_ACCESS_FLAG_RESUME ) != 0 ) )
1474
  {
1475
    /* Get the basename of the first segment file
1476
     */
1477
    if( first_segment_filename != NULL )
1478
    {
1479
      filename_length = wide_string_length(
1480
             first_segment_filename );
1481
1482
      /* Set segment table basename
1483
       */
1484
      if( libewf_segment_table_set_basename_wide(
1485
           internal_handle->segment_table,
1486
           first_segment_filename,
1487
           filename_length - 4,
1488
           error ) != 1 )
1489
      {
1490
        libcerror_error_set(
1491
         error,
1492
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1493
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1494
         "%s: unable to set basename in segment table.",
1495
         function );
1496
1497
        goto on_error;
1498
      }
1499
    }
1500
  }
1501
  else if( ( access_flags & LIBEWF_ACCESS_FLAG_WRITE ) != 0 )
1502
  {
1503
    /* Get the basename and store it in the segment tables
1504
     */
1505
    filename_length = wide_string_length(
1506
           filenames[ 0 ] );
1507
1508
    /* Set segment table basename
1509
     */
1510
    if( libewf_segment_table_set_basename_wide(
1511
         internal_handle->segment_table,
1512
         filenames[ 0 ],
1513
         filename_length,
1514
         error ) != 1 )
1515
    {
1516
      libcerror_error_set(
1517
       error,
1518
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1519
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1520
       "%s: unable to set basename in segment table.",
1521
       function );
1522
1523
      goto on_error;
1524
    }
1525
  }
1526
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
1527
  if( libcthreads_read_write_lock_grab_for_write(
1528
       internal_handle->read_write_lock,
1529
       error ) != 1 )
1530
  {
1531
    libcerror_error_set(
1532
     error,
1533
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1534
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1535
     "%s: unable to grab read/write lock for writing.",
1536
     function );
1537
1538
    goto on_error;
1539
  }
1540
#endif
1541
  result = libewf_internal_handle_open_file_io_pool(
1542
            internal_handle,
1543
            file_io_pool,
1544
            access_flags,
1545
            internal_handle->segment_table,
1546
            error );
1547
1548
  if( result != 1 )
1549
  {
1550
    libcerror_error_set(
1551
     error,
1552
     LIBCERROR_ERROR_DOMAIN_IO,
1553
     LIBCERROR_IO_ERROR_OPEN_FAILED,
1554
     "%s: unable to open handle using a file IO pool.",
1555
     function );
1556
1557
    result = -1;
1558
  }
1559
  else
1560
  {
1561
    internal_handle->file_io_pool                    = file_io_pool;
1562
    internal_handle->file_io_pool_created_in_library = 1;
1563
  }
1564
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
1565
  if( libcthreads_read_write_lock_release_for_write(
1566
       internal_handle->read_write_lock,
1567
       error ) != 1 )
1568
  {
1569
    libcerror_error_set(
1570
     error,
1571
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1572
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1573
     "%s: unable to release read/write lock for writing.",
1574
     function );
1575
1576
    result = -1;
1577
  }
1578
#endif
1579
  if( result != 1 )
1580
  {
1581
    goto on_error;
1582
  }
1583
  return( 1 );
1584
1585
on_error:
1586
  if( file_io_handle != NULL )
1587
  {
1588
    libbfio_handle_free(
1589
     &file_io_handle,
1590
     NULL );
1591
  }
1592
  if( file_io_pool != NULL )
1593
  {
1594
    libbfio_pool_free(
1595
     &file_io_pool,
1596
     NULL );
1597
  }
1598
  internal_handle->file_io_pool                    = NULL;
1599
  internal_handle->file_io_pool_created_in_library = 0;
1600
1601
  return( -1 );
1602
}
1603
1604
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
1605
1606
/* Reads the section data from a segment file
1607
 * Returns 1 if successful or -1 on error
1608
 */
1609
int libewf_internal_handle_open_read_segment_file_section_data(
1610
     libewf_internal_handle_t *internal_handle,
1611
     libewf_segment_file_t *segment_file,
1612
     libbfio_pool_t *file_io_pool,
1613
     int file_io_pool_entry,
1614
     libcerror_error_t **error )
1615
2.88k
{
1616
2.88k
  libewf_header_sections_t *header_sections       = NULL;
1617
2.88k
  libewf_section_descriptor_t *section_descriptor = NULL;
1618
2.88k
  libfcache_cache_t *sections_cache               = NULL;
1619
2.88k
  libfdata_stream_t *single_files_data_stream     = NULL;
1620
2.88k
  uint8_t *string_data                            = NULL;
1621
2.88k
  static char *function                           = "libewf_internal_handle_open_read_segment_file_section_data";
1622
2.88k
  size_t string_data_size                         = 0;
1623
2.88k
  ssize_t read_count                              = 0;
1624
2.88k
  off64_t section_data_offset                     = 0;
1625
2.88k
  uint8_t header_section_found                    = 0;
1626
2.88k
  uint8_t initialize_chunk_values                 = 0;
1627
2.88k
  int number_of_sections                          = 0;
1628
2.88k
  int read_table_sections                         = 0;
1629
2.88k
  int result                                      = 0;
1630
2.88k
  int section_index                               = 0;
1631
2.88k
  int set_identifier_change                       = 0;
1632
1633
#if defined( HAVE_VERBOSE_OUTPUT )
1634
  int known_section                               = 0;
1635
#endif
1636
1637
2.88k
  if( internal_handle == NULL )
1638
0
  {
1639
0
    libcerror_error_set(
1640
0
     error,
1641
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1642
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1643
0
     "%s: invalid handle.",
1644
0
     function );
1645
1646
0
    return( -1 );
1647
0
  }
1648
2.88k
  if( internal_handle->io_handle == NULL )
1649
0
  {
1650
0
    libcerror_error_set(
1651
0
     error,
1652
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1653
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1654
0
     "%s: invalid handle - missing IO handle.",
1655
0
     function );
1656
1657
0
    return( -1 );
1658
0
  }
1659
2.88k
  if( internal_handle->read_io_handle == NULL )
1660
0
  {
1661
0
    libcerror_error_set(
1662
0
     error,
1663
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1664
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1665
0
     "%s: invalid handle - missing read IO handle.",
1666
0
     function );
1667
1668
0
    return( -1 );
1669
0
  }
1670
2.88k
  if( internal_handle->media_values == NULL )
1671
0
  {
1672
0
    libcerror_error_set(
1673
0
     error,
1674
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1675
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1676
0
     "%s: invalid handle - missing media values.",
1677
0
     function );
1678
1679
0
    return( -1 );
1680
0
  }
1681
2.88k
  if( internal_handle->single_files != NULL )
1682
0
  {
1683
0
    libcerror_error_set(
1684
0
     error,
1685
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1686
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1687
0
     "%s: invalid handle - single files value already set.",
1688
0
     function );
1689
1690
0
    return( -1 );
1691
0
  }
1692
2.88k
  if( segment_file == NULL )
1693
0
  {
1694
0
    libcerror_error_set(
1695
0
     error,
1696
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1697
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1698
0
     "%s: invalid segment file.",
1699
0
     function );
1700
1701
0
    return( -1 );
1702
0
  }
1703
2.88k
  if( libfcache_cache_initialize(
1704
2.88k
       &sections_cache,
1705
2.88k
       LIBEWF_MAXIMUM_CACHE_ENTRIES_SECTIONS,
1706
2.88k
       error ) != 1 )
1707
0
  {
1708
0
    libcerror_error_set(
1709
0
     error,
1710
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1711
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1712
0
     "%s: unable to create sections cache.",
1713
0
     function );
1714
1715
0
    goto on_error;
1716
0
  }
1717
2.88k
  if( libewf_header_sections_initialize(
1718
2.88k
       &header_sections,
1719
2.88k
       error ) != 1 )
1720
0
  {
1721
0
    libcerror_error_set(
1722
0
     error,
1723
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1724
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1725
0
     "%s: unable to create header sections.",
1726
0
     function );
1727
1728
0
    goto on_error;
1729
0
  }
1730
2.88k
  if( libfdata_list_get_number_of_elements(
1731
2.88k
       segment_file->sections_list,
1732
2.88k
       &number_of_sections,
1733
2.88k
       error ) != 1 )
1734
0
  {
1735
0
    libcerror_error_set(
1736
0
     error,
1737
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1738
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1739
0
     "%s: unable to retrieve the number of sections in the sections list.",
1740
0
     function );
1741
1742
0
    goto on_error;
1743
0
  }
1744
2.88k
  for( section_index = 0;
1745
9.37k
       section_index < number_of_sections;
1746
6.48k
       section_index++ )
1747
7.98k
  {
1748
7.98k
    if( libfdata_list_get_element_value_by_index(
1749
7.98k
         segment_file->sections_list,
1750
7.98k
         (intptr_t *) file_io_pool,
1751
7.98k
         (libfdata_cache_t *) sections_cache,
1752
7.98k
         section_index,
1753
7.98k
         (intptr_t **) &section_descriptor,
1754
7.98k
         0,
1755
7.98k
         error ) != 1 )
1756
0
    {
1757
0
      libcerror_error_set(
1758
0
       error,
1759
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1760
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1761
0
       "%s: unable to retrieve section: %d descriptor from list.",
1762
0
       function,
1763
0
       section_index );
1764
1765
0
      goto on_error;
1766
0
    }
1767
7.98k
    result = libewf_section_descriptor_get_data_offset(
1768
7.98k
              section_descriptor,
1769
7.98k
              segment_file->major_version,
1770
7.98k
              &section_data_offset,
1771
7.98k
              error );
1772
1773
7.98k
    if( result == -1 )
1774
0
    {
1775
0
      libcerror_error_set(
1776
0
       error,
1777
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1778
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1779
0
       "%s: unable to retrieve section: %d data offset.",
1780
0
       function,
1781
0
       section_index );
1782
1783
0
      goto on_error;
1784
0
    }
1785
7.98k
    else if( result != 0 )
1786
7.98k
    {
1787
7.98k
      if( libewf_segment_file_seek_offset(
1788
7.98k
           segment_file,
1789
7.98k
           file_io_pool,
1790
7.98k
           file_io_pool_entry,
1791
7.98k
           section_data_offset,
1792
7.98k
           error ) == -1 )
1793
0
      {
1794
0
        libcerror_error_set(
1795
0
         error,
1796
0
         LIBCERROR_ERROR_DOMAIN_IO,
1797
0
         LIBCERROR_IO_ERROR_OPEN_FAILED,
1798
0
         "%s: unable to seek section: %d data offset: %" PRIu64 ".",
1799
0
         function,
1800
0
         section_index,
1801
0
         section_data_offset );
1802
1803
0
        goto on_error;
1804
0
      }
1805
#if defined( HAVE_DEBUG_OUTPUT )
1806
      if( libcnotify_verbose != 0 )
1807
      {
1808
        if( segment_file->major_version == 1 )
1809
        {
1810
          libcnotify_printf(
1811
           "%s: reading %s section data from file IO pool entry: %d at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
1812
           function,
1813
           (char *) section_descriptor->type_string,
1814
           file_io_pool_entry,
1815
           segment_file->current_offset,
1816
           segment_file->current_offset );
1817
        }
1818
        else if( segment_file->major_version == 2 )
1819
        {
1820
          libcnotify_printf(
1821
           "%s: reading 0x%08" PRIx32 " section data from file IO pool entry: %d at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
1822
           function,
1823
           section_descriptor->type,
1824
           file_io_pool_entry,
1825
           segment_file->current_offset,
1826
           segment_file->current_offset );
1827
        }
1828
      }
1829
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1830
7.98k
    }
1831
7.98k
    if( section_descriptor->type != 0 )
1832
2.04k
    {
1833
2.04k
      switch( section_descriptor->type )
1834
2.04k
      {
1835
0
        case LIBEWF_SECTION_TYPE_DEVICE_INFORMATION:
1836
0
          read_count = libewf_device_information_section_read_file_io_pool(
1837
0
                  section_descriptor,
1838
0
                  internal_handle->io_handle,
1839
0
                  file_io_pool,
1840
0
                  file_io_pool_entry,
1841
0
                  internal_handle->read_io_handle,
1842
0
                  internal_handle->media_values,
1843
0
                  internal_handle->header_values,
1844
0
                  error );
1845
#if defined( HAVE_VERBOSE_OUTPUT )
1846
          known_section = 1;
1847
#endif
1848
0
          break;
1849
1850
0
        case LIBEWF_SECTION_TYPE_CASE_DATA:
1851
0
          if( internal_handle->read_io_handle->case_data == NULL )
1852
0
          {
1853
0
            initialize_chunk_values = 1;
1854
0
          }
1855
0
          read_count = libewf_case_data_section_read_file_io_pool(
1856
0
                  section_descriptor,
1857
0
                  internal_handle->io_handle,
1858
0
                  file_io_pool,
1859
0
                  file_io_pool_entry,
1860
0
                  internal_handle->read_io_handle,
1861
0
                  internal_handle->media_values,
1862
0
                  internal_handle->header_values,
1863
0
                  error );
1864
1865
#if defined( HAVE_VERBOSE_OUTPUT )
1866
          known_section = 1;
1867
#endif
1868
0
          break;
1869
1870
717
        case LIBEWF_SECTION_TYPE_SECTOR_DATA:
1871
#if defined( HAVE_VERBOSE_OUTPUT )
1872
          if( libcnotify_verbose != 0 )
1873
          {
1874
            if( internal_handle->io_handle->segment_file_type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
1875
            {
1876
              libcnotify_printf(
1877
               "%s: found sectors section in EWF-S01 format.\n",
1878
               function );
1879
            }
1880
          }
1881
#endif
1882
          /* Nothing to do for the sectors section
1883
           */
1884
#if defined( HAVE_VERBOSE_OUTPUT )
1885
          known_section = 1;
1886
#endif
1887
717
          break;
1888
1889
747
        case LIBEWF_SECTION_TYPE_SECTOR_TABLE:
1890
          /* If the chunk_size was unknown when the segment file was opened we
1891
           * have to read the chunk groups here
1892
           */
1893
747
          if( segment_file->number_of_chunks == 0 )
1894
743
          {
1895
743
            read_table_sections = 1;
1896
743
          }
1897
747
          if( read_table_sections != 0 )
1898
747
          {
1899
747
            read_count = libewf_segment_file_read_table_section(
1900
747
                    segment_file,
1901
747
                    section_descriptor,
1902
747
                    file_io_pool,
1903
747
                    file_io_pool_entry,
1904
747
                    internal_handle->media_values->chunk_size,
1905
747
                    error );
1906
747
          }
1907
#if defined( HAVE_VERBOSE_OUTPUT )
1908
          known_section = 1;
1909
#endif
1910
747
          break;
1911
1912
38
        case LIBEWF_SECTION_TYPE_ERROR_TABLE:
1913
#if defined( HAVE_VERBOSE_OUTPUT )
1914
          if( libcnotify_verbose != 0 )
1915
          {
1916
            if( internal_handle->io_handle->segment_file_type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
1917
            {
1918
              libcnotify_printf(
1919
               "%s: found error section in EWF-S01 format.\n",
1920
               function );
1921
            }
1922
          }
1923
#endif
1924
38
          read_count = libewf_error2_section_read_file_io_pool(
1925
38
                  section_descriptor,
1926
38
                  internal_handle->io_handle,
1927
38
                  file_io_pool,
1928
38
                  file_io_pool_entry,
1929
38
                  segment_file->major_version,
1930
38
                  internal_handle->acquiry_errors,
1931
38
                  error );
1932
1933
#if defined( HAVE_VERBOSE_OUTPUT )
1934
          known_section = 1;
1935
#endif
1936
38
          break;
1937
1938
158
        case LIBEWF_SECTION_TYPE_SESSION_TABLE:
1939
#if defined( HAVE_VERBOSE_OUTPUT )
1940
          if( libcnotify_verbose != 0 )
1941
          {
1942
            if( internal_handle->io_handle->segment_file_type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
1943
            {
1944
              libcnotify_printf(
1945
               "%s: found session section in EWF-S01 format.\n",
1946
               function );
1947
            }
1948
          }
1949
#endif
1950
158
          read_count = libewf_session_section_read_file_io_pool(
1951
158
                  section_descriptor,
1952
158
                  internal_handle->io_handle,
1953
158
                  file_io_pool,
1954
158
                  file_io_pool_entry,
1955
158
                  segment_file->major_version,
1956
158
                  internal_handle->media_values,
1957
158
                  internal_handle->sessions,
1958
158
                  internal_handle->tracks,
1959
158
                  error );
1960
1961
#if defined( HAVE_VERBOSE_OUTPUT )
1962
          known_section = 1;
1963
#endif
1964
158
          break;
1965
1966
0
        case LIBEWF_SECTION_TYPE_INCREMENT_DATA:
1967
#if defined( HAVE_VERBOSE_OUTPUT )
1968
          known_section = 1;
1969
#endif
1970
0
          break;
1971
1972
47
        case LIBEWF_SECTION_TYPE_MD5_HASH:
1973
47
          read_count = libewf_md5_hash_section_read_file_io_pool(
1974
47
                  section_descriptor,
1975
47
                  internal_handle->io_handle,
1976
47
                  file_io_pool,
1977
47
                  file_io_pool_entry,
1978
47
                  segment_file->major_version,
1979
47
                  internal_handle->hash_sections,
1980
47
                  error );
1981
1982
#if defined( HAVE_VERBOSE_OUTPUT )
1983
          known_section = 1;
1984
#endif
1985
47
          break;
1986
1987
0
        case LIBEWF_SECTION_TYPE_SHA1_HASH:
1988
0
          read_count = libewf_sha1_hash_section_read_file_io_pool(
1989
0
                  section_descriptor,
1990
0
                  internal_handle->io_handle,
1991
0
                  file_io_pool,
1992
0
                  file_io_pool_entry,
1993
0
                  internal_handle->hash_sections,
1994
0
                  error );
1995
1996
#if defined( HAVE_VERBOSE_OUTPUT )
1997
          known_section = 1;
1998
#endif
1999
0
          break;
2000
2001
0
        case LIBEWF_SECTION_TYPE_RESTART_DATA:
2002
0
          read_count = libewf_section_compressed_string_read(
2003
0
                  section_descriptor,
2004
0
                        internal_handle->io_handle,
2005
0
                  file_io_pool,
2006
0
                  file_io_pool_entry,
2007
0
                        internal_handle->io_handle->compression_method,
2008
0
                  &string_data,
2009
0
                  &string_data_size,
2010
0
                  error );
2011
2012
0
          if( read_count == -1 )
2013
0
          {
2014
0
            libcerror_error_set(
2015
0
             error,
2016
0
             LIBCERROR_ERROR_DOMAIN_IO,
2017
0
             LIBCERROR_IO_ERROR_READ_FAILED,
2018
0
             "%s: unable to read restart data file object string.",
2019
0
             function );
2020
2021
0
            goto on_error;
2022
0
          }
2023
0
          if( libewf_restart_data_parse(
2024
0
               string_data,
2025
0
               string_data_size,
2026
0
               error ) != 1 )
2027
0
          {
2028
0
            libcerror_error_set(
2029
0
             error,
2030
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
2031
0
             LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2032
0
             "%s: unable to parse restart data.",
2033
0
             function );
2034
2035
0
            goto on_error;
2036
0
          }
2037
0
          memory_free(
2038
0
           string_data );
2039
2040
0
          string_data = NULL;
2041
2042
#if defined( HAVE_VERBOSE_OUTPUT )
2043
          known_section = 1;
2044
#endif
2045
0
          break;
2046
2047
0
        case LIBEWF_SECTION_TYPE_ENCRYPTION_KEYS:
2048
#if defined( HAVE_VERBOSE_OUTPUT )
2049
          known_section = 1;
2050
#endif
2051
0
          break;
2052
2053
0
        case LIBEWF_SECTION_TYPE_MEMORY_EXTENTS_TABLE:
2054
#if defined( HAVE_VERBOSE_OUTPUT )
2055
          known_section = 1;
2056
#endif
2057
0
          break;
2058
2059
0
        case LIBEWF_SECTION_TYPE_NEXT:
2060
          /* Nothing to do for the next section
2061
           */
2062
#if defined( HAVE_VERBOSE_OUTPUT )
2063
          known_section = 1;
2064
#endif
2065
0
          break;
2066
2067
0
        case LIBEWF_SECTION_TYPE_FINAL_INFORMATION:
2068
#if defined( HAVE_VERBOSE_OUTPUT )
2069
          known_section = 1;
2070
#endif
2071
0
          break;
2072
2073
9
        case LIBEWF_SECTION_TYPE_DONE:
2074
          /* Nothing to do for the done section
2075
           */
2076
#if defined( HAVE_VERBOSE_OUTPUT )
2077
          known_section = 1;
2078
#endif
2079
9
          break;
2080
2081
0
        case LIBEWF_SECTION_TYPE_ANALYTICAL_DATA:
2082
0
          read_count = libewf_section_compressed_string_read(
2083
0
                  section_descriptor,
2084
0
                        internal_handle->io_handle,
2085
0
                  file_io_pool,
2086
0
                  file_io_pool_entry,
2087
0
                        internal_handle->io_handle->compression_method,
2088
0
                  &string_data,
2089
0
                  &string_data_size,
2090
0
                  error );
2091
2092
0
          if( read_count == -1 )
2093
0
          {
2094
0
            libcerror_error_set(
2095
0
             error,
2096
0
             LIBCERROR_ERROR_DOMAIN_IO,
2097
0
             LIBCERROR_IO_ERROR_READ_FAILED,
2098
0
             "%s: unable to read analytical data file object string.",
2099
0
             function );
2100
2101
0
            goto on_error;
2102
0
          }
2103
0
          else if( read_count != 0 )
2104
0
          {
2105
0
            if( libewf_analytical_data_parse(
2106
0
                 string_data,
2107
0
                 string_data_size,
2108
0
                 error ) != 1 )
2109
0
            {
2110
0
              libcerror_error_set(
2111
0
               error,
2112
0
               LIBCERROR_ERROR_DOMAIN_RUNTIME,
2113
0
               LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2114
0
               "%s: unable to parse analytical data.",
2115
0
               function );
2116
2117
0
              goto on_error;
2118
0
            }
2119
0
            memory_free(
2120
0
             string_data );
2121
2122
0
            string_data = NULL;
2123
0
          }
2124
#if defined( HAVE_VERBOSE_OUTPUT )
2125
          known_section = 1;
2126
#endif
2127
0
          break;
2128
2129
333
        case LIBEWF_SECTION_TYPE_SINGLE_FILES_DATA:
2130
#if defined( HAVE_VERBOSE_OUTPUT )
2131
          if( ( internal_handle->io_handle->segment_file_type != LIBEWF_SEGMENT_FILE_TYPE_EWF1_LOGICAL )
2132
           && ( internal_handle->io_handle->segment_file_type != LIBEWF_SEGMENT_FILE_TYPE_EWF2_LOGICAL ) )
2133
          {
2134
            if( libcnotify_verbose != 0 )
2135
            {
2136
              libcnotify_printf(
2137
               "%s: found single files data section in none logical evidence format.\n",
2138
               function );
2139
            }
2140
          }
2141
#endif
2142
333
          read_count = libewf_ltree_section_read_file_io_pool(
2143
333
                  section_descriptor,
2144
333
                  internal_handle->io_handle,
2145
333
                  file_io_pool,
2146
333
                  file_io_pool_entry,
2147
333
                  segment_file->major_version,
2148
333
                  &single_files_data_stream,
2149
333
                  error );
2150
2151
#if defined( HAVE_VERBOSE_OUTPUT )
2152
          known_section = 1;
2153
#endif
2154
333
          break;
2155
2.04k
      }
2156
2.04k
    }
2157
5.94k
    else if( section_descriptor->type_string_length == 4 )
2158
567
    {
2159
567
      if( memory_compare(
2160
567
           (void *) section_descriptor->type_string,
2161
567
           (void *) "data",
2162
567
           4 ) == 0 )
2163
557
      {
2164
#if defined( HAVE_VERBOSE_OUTPUT )
2165
        if( libcnotify_verbose != 0 )
2166
        {
2167
          if( internal_handle->io_handle->segment_file_type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
2168
          {
2169
            libcnotify_printf(
2170
             "%s: found data section in EWF-S01 format.\n",
2171
             function );
2172
          }
2173
        }
2174
#endif
2175
557
        read_count = libewf_section_data_read(
2176
557
                section_descriptor,
2177
557
                internal_handle->io_handle,
2178
557
                file_io_pool,
2179
557
                file_io_pool_entry,
2180
557
                internal_handle->media_values,
2181
557
                      &set_identifier_change,
2182
557
                      error );
2183
2184
557
        if( set_identifier_change != 0 )
2185
94
        {
2186
#if defined( HAVE_VERBOSE_OUTPUT )
2187
          if( libcnotify_verbose != 0 )
2188
          {
2189
            libcnotify_printf(
2190
             "%s: set identifier does not match.",
2191
             function );
2192
          }
2193
#endif
2194
94
          segment_file->flags |= LIBEWF_SEGMENT_FILE_FLAG_IS_CORRUPTED;
2195
94
        }
2196
#if defined( HAVE_VERBOSE_OUTPUT )
2197
        known_section = 1;
2198
#endif
2199
557
      }
2200
10
      else if( memory_compare(
2201
10
          (void *) section_descriptor->type_string,
2202
10
          (void *) "disk",
2203
10
          4 ) == 0 )
2204
0
      {
2205
0
        read_count = libewf_segment_file_read_volume_section(
2206
0
                segment_file,
2207
0
                section_descriptor,
2208
0
                file_io_pool,
2209
0
                file_io_pool_entry,
2210
0
                internal_handle->media_values,
2211
0
                error );
2212
2213
0
        initialize_chunk_values = 1;
2214
2215
#if defined( HAVE_VERBOSE_OUTPUT )
2216
        known_section = 1;
2217
#endif
2218
0
      }
2219
567
    }
2220
5.37k
    else if( section_descriptor->type_string_length == 5 )
2221
40
    {
2222
40
      if( memory_compare(
2223
40
           (void *) section_descriptor->type_string,
2224
40
           (void *) "xhash",
2225
40
           5 ) == 0 )
2226
0
      {
2227
#if defined( HAVE_VERBOSE_OUTPUT )
2228
        if( libcnotify_verbose != 0 )
2229
        {
2230
          if( internal_handle->io_handle->segment_file_type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
2231
          {
2232
            libcnotify_printf(
2233
             "%s: found xhash section in EWF-S01 format.\n",
2234
             function );
2235
          }
2236
        }
2237
#endif
2238
0
        read_count = libewf_section_compressed_string_read(
2239
0
                section_descriptor,
2240
0
                      internal_handle->io_handle,
2241
0
                file_io_pool,
2242
0
                file_io_pool_entry,
2243
0
                internal_handle->io_handle->compression_method,
2244
0
                &string_data,
2245
0
                &string_data_size,
2246
0
                error );
2247
2248
0
        if( read_count == -1 )
2249
0
        {
2250
0
          libcerror_error_set(
2251
0
           error,
2252
0
           LIBCERROR_ERROR_DOMAIN_IO,
2253
0
           LIBCERROR_IO_ERROR_READ_FAILED,
2254
0
           "%s: unable to read xhash string.",
2255
0
           function );
2256
2257
0
          goto on_error;
2258
0
        }
2259
#if defined( HAVE_DEBUG_OUTPUT )
2260
        if( libcnotify_verbose != 0 )
2261
        {
2262
           if( libewf_debug_utf8_stream_print(
2263
                "XHash",
2264
                string_data,
2265
                string_data_size,
2266
                error ) != 1 )
2267
          {
2268
            libcerror_error_set(
2269
             error,
2270
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
2271
             LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
2272
             "%s: unable to print xhash.",
2273
             function );
2274
2275
            goto on_error;
2276
          }
2277
        }
2278
#endif
2279
0
        if( internal_handle->hash_sections->xhash == NULL )
2280
0
        {
2281
0
          internal_handle->hash_sections->xhash      = string_data;
2282
0
          internal_handle->hash_sections->xhash_size = string_data_size;
2283
0
        }
2284
0
        else
2285
0
        {
2286
0
          memory_free(
2287
0
           string_data );
2288
0
        }
2289
0
        string_data = NULL;
2290
#if defined( HAVE_VERBOSE_OUTPUT )
2291
        known_section = 1;
2292
#endif
2293
0
      }
2294
40
    }
2295
5.33k
    else if( section_descriptor->type_string_length == 6 )
2296
2.51k
    {
2297
2.51k
      if( memory_compare(
2298
2.51k
           (void *) section_descriptor->type_string,
2299
2.51k
           (void *) "digest",
2300
2.51k
           6 ) == 0 )
2301
8
      {
2302
#if defined( HAVE_VERBOSE_OUTPUT )
2303
        if( libcnotify_verbose != 0 )
2304
        {
2305
          if( internal_handle->io_handle->segment_file_type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
2306
          {
2307
            libcnotify_printf(
2308
             "%s: found digest section in EWF-S01 format.\n",
2309
             function );
2310
          }
2311
        }
2312
#endif
2313
8
        read_count = libewf_digest_section_read_file_io_pool(
2314
8
                section_descriptor,
2315
8
                      internal_handle->io_handle,
2316
8
                file_io_pool,
2317
8
                file_io_pool_entry,
2318
8
                internal_handle->hash_sections,
2319
8
                error );
2320
2321
#if defined( HAVE_VERBOSE_OUTPUT )
2322
        known_section = 1;
2323
#endif
2324
8
      }
2325
2.50k
      else if( memory_compare(
2326
2.50k
          (void *) section_descriptor->type_string,
2327
2.50k
          (void *) "header",
2328
2.50k
          6 ) == 0 )
2329
1.09k
      {
2330
1.09k
        read_count = libewf_section_compressed_string_read(
2331
1.09k
                section_descriptor,
2332
1.09k
                      internal_handle->io_handle,
2333
1.09k
                file_io_pool,
2334
1.09k
                file_io_pool_entry,
2335
1.09k
                      internal_handle->io_handle->compression_method,
2336
1.09k
                &string_data,
2337
1.09k
                &string_data_size,
2338
1.09k
                error );
2339
2340
1.09k
        if( read_count == -1 )
2341
93
        {
2342
93
          libcerror_error_set(
2343
93
           error,
2344
93
           LIBCERROR_ERROR_DOMAIN_IO,
2345
93
           LIBCERROR_IO_ERROR_READ_FAILED,
2346
93
           "%s: unable to read header file object string.",
2347
93
           function );
2348
2349
93
          goto on_error;
2350
93
        }
2351
#if defined( HAVE_DEBUG_OUTPUT )
2352
        if( libcnotify_verbose != 0 )
2353
        {
2354
          if( libewf_debug_byte_stream_print(
2355
               "Header",
2356
               string_data,
2357
               string_data_size,
2358
               error ) != 1 )
2359
          {
2360
            libcerror_error_set(
2361
             error,
2362
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
2363
             LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
2364
             "%s: unable to print header.",
2365
             function );
2366
2367
            goto on_error;
2368
          }
2369
        }
2370
#endif
2371
1.00k
        if( header_sections->header == NULL )
2372
1.00k
        {
2373
1.00k
          header_sections->header      = string_data;
2374
1.00k
          header_sections->header_size = string_data_size;
2375
1.00k
        }
2376
0
        else
2377
0
        {
2378
0
          memory_free(
2379
0
           string_data );
2380
0
        }
2381
1.00k
        string_data = NULL;
2382
2383
1.00k
        header_sections->number_of_header_sections += 1;
2384
2385
1.00k
        header_section_found = 1;
2386
2387
#if defined( HAVE_VERBOSE_OUTPUT )
2388
        known_section = 1;
2389
#endif
2390
1.00k
      }
2391
1.40k
      else if( memory_compare(
2392
1.40k
          (void *) section_descriptor->type_string,
2393
1.40k
          (void *) "table2",
2394
1.40k
          6 ) == 0 )
2395
579
      {
2396
579
        if( read_table_sections != 0 )
2397
578
        {
2398
578
          read_count = libewf_segment_file_read_table2_section(
2399
578
                  segment_file,
2400
578
                  section_descriptor,
2401
578
                  file_io_pool,
2402
578
                  file_io_pool_entry,
2403
578
                  error );
2404
578
        }
2405
#if defined( HAVE_VERBOSE_OUTPUT )
2406
        known_section = 1;
2407
#endif
2408
579
      }
2409
830
      else if( memory_compare(
2410
830
          (void *) section_descriptor->type_string,
2411
830
          (void *) "volume",
2412
830
          6 ) == 0 )
2413
762
      {
2414
762
        read_count = libewf_segment_file_read_volume_section(
2415
762
                segment_file,
2416
762
                section_descriptor,
2417
762
                file_io_pool,
2418
762
                file_io_pool_entry,
2419
762
                internal_handle->media_values,
2420
762
                error );
2421
2422
762
        initialize_chunk_values = 1;
2423
2424
#if defined( HAVE_VERBOSE_OUTPUT )
2425
        known_section = 1;
2426
#endif
2427
762
      }
2428
2.51k
    }
2429
2.82k
    else if( section_descriptor->type_string_length == 7 )
2430
2.79k
    {
2431
2.79k
      if( memory_compare(
2432
2.79k
           (void *) section_descriptor->type_string,
2433
2.79k
           (void *) "header2",
2434
2.79k
           7 ) == 0 )
2435
2.47k
      {
2436
2.47k
        read_count = libewf_section_compressed_string_read(
2437
2.47k
                section_descriptor,
2438
2.47k
                      internal_handle->io_handle,
2439
2.47k
                file_io_pool,
2440
2.47k
                file_io_pool_entry,
2441
2.47k
                      internal_handle->io_handle->compression_method,
2442
2.47k
                &string_data,
2443
2.47k
                &string_data_size,
2444
2.47k
                error );
2445
2446
2.47k
        if( read_count == -1 )
2447
444
        {
2448
444
          libcerror_error_set(
2449
444
           error,
2450
444
           LIBCERROR_ERROR_DOMAIN_IO,
2451
444
           LIBCERROR_IO_ERROR_READ_FAILED,
2452
444
           "%s: unable to read header2 file object string.",
2453
444
           function );
2454
2455
444
          goto on_error;
2456
444
        }
2457
#if defined( HAVE_DEBUG_OUTPUT )
2458
        if( libcnotify_verbose != 0 )
2459
        {
2460
          if( libewf_debug_utf16_stream_print(
2461
               "Header2",
2462
               string_data,
2463
               string_data_size,
2464
               LIBUNA_ENDIAN_LITTLE,
2465
               error ) != 1 )
2466
          {
2467
            libcerror_error_set(
2468
             error,
2469
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
2470
             LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
2471
             "%s: unable to print header2.",
2472
             function );
2473
2474
            goto on_error;
2475
          }
2476
        }
2477
#endif
2478
2.03k
        if( header_sections->header2 == NULL )
2479
1.21k
        {
2480
1.21k
          header_sections->header2      = string_data;
2481
1.21k
          header_sections->header2_size = string_data_size;
2482
1.21k
        }
2483
812
        else
2484
812
        {
2485
812
          memory_free(
2486
812
           string_data );
2487
812
        }
2488
2.03k
        string_data = NULL;
2489
2490
2.03k
        header_sections->number_of_header_sections += 1;
2491
2492
2.03k
        header_section_found = 1;
2493
2494
#if defined( HAVE_VERBOSE_OUTPUT )
2495
        known_section = 1;
2496
#endif
2497
2.03k
      }
2498
317
      else if( memory_compare(
2499
317
          (void *) section_descriptor->type_string,
2500
317
          (void *) "xheader",
2501
317
          7 ) == 0 )
2502
71
      {
2503
71
        read_count = libewf_section_compressed_string_read(
2504
71
                section_descriptor,
2505
71
                      internal_handle->io_handle,
2506
71
                file_io_pool,
2507
71
                file_io_pool_entry,
2508
71
                      internal_handle->io_handle->compression_method,
2509
71
                &string_data,
2510
71
                &string_data_size,
2511
71
                error );
2512
2513
71
        if( read_count == -1 )
2514
8
        {
2515
8
          libcerror_error_set(
2516
8
           error,
2517
8
           LIBCERROR_ERROR_DOMAIN_IO,
2518
8
           LIBCERROR_IO_ERROR_READ_FAILED,
2519
8
           "%s: unable to read xheader string.",
2520
8
           function );
2521
2522
8
          goto on_error;
2523
8
        }
2524
#if defined( HAVE_DEBUG_OUTPUT )
2525
        if( libcnotify_verbose != 0 )
2526
        {
2527
          if( libewf_debug_utf8_stream_print(
2528
               "XHeader",
2529
               string_data,
2530
               string_data_size,
2531
               error ) != 1 )
2532
          {
2533
            libcerror_error_set(
2534
             error,
2535
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
2536
             LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
2537
             "%s: unable to print xheader.",
2538
             function );
2539
2540
            goto on_error;
2541
          }
2542
        }
2543
#endif
2544
63
        if( header_sections->xheader == NULL )
2545
63
        {
2546
63
          header_sections->xheader      = string_data;
2547
63
          header_sections->xheader_size = string_data_size;
2548
63
        }
2549
0
        else
2550
0
        {
2551
0
          memory_free(
2552
0
           string_data );
2553
0
        }
2554
63
        string_data = NULL;
2555
2556
63
        header_sections->number_of_header_sections += 1;
2557
2558
63
        header_section_found = 1;
2559
2560
#if defined( HAVE_VERBOSE_OUTPUT )
2561
        known_section = 1;
2562
#endif
2563
63
      }
2564
2.79k
    }
2565
#if defined( HAVE_VERBOSE_OUTPUT )
2566
    if( libcnotify_verbose != 0 )
2567
    {
2568
      if( known_section == 0 )
2569
      {
2570
        if( segment_file->major_version == 1 )
2571
        {
2572
          libcnotify_printf(
2573
           "%s: unsupported section type: %s.\n",
2574
           function,
2575
           (char *) section_descriptor->type_string );
2576
        }
2577
        else if( segment_file->major_version == 2 )
2578
        {
2579
          libcnotify_printf(
2580
           "%s: unsupported section type: 0x%08" PRIx32 ".\n",
2581
           function,
2582
           section_descriptor->type );
2583
        }
2584
      }
2585
    }
2586
#endif
2587
7.44k
    if( read_count == -1 )
2588
953
    {
2589
953
      if( section_descriptor->type_string_length > 0 )
2590
953
      {
2591
953
        libcerror_error_set(
2592
953
         error,
2593
953
         LIBCERROR_ERROR_DOMAIN_IO,
2594
953
         LIBCERROR_IO_ERROR_READ_FAILED,
2595
953
         "%s: unable to read section: %s.",
2596
953
         function,
2597
953
         (char *) section_descriptor->type_string );
2598
953
      }
2599
0
      else
2600
0
      {
2601
0
        libcerror_error_set(
2602
0
         error,
2603
0
         LIBCERROR_ERROR_DOMAIN_IO,
2604
0
         LIBCERROR_IO_ERROR_READ_FAILED,
2605
0
         "%s: unable to read section: 0x%08" PRIx32 ".",
2606
0
         function,
2607
0
         section_descriptor->type );
2608
0
      }
2609
953
      goto on_error;
2610
953
    }
2611
6.49k
    if( initialize_chunk_values != 0 )
2612
717
    {
2613
717
      if( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART )
2614
0
      {
2615
0
        segment_file->io_handle->segment_file_type = LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART;
2616
0
        segment_file->io_handle->format            = LIBEWF_FORMAT_SMART;
2617
0
      }
2618
717
      if( libewf_media_values_calculate_chunk_size(
2619
717
           internal_handle->media_values,
2620
717
           error ) != 1 )
2621
5
      {
2622
5
        libcerror_error_set(
2623
5
         error,
2624
5
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2625
5
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2626
5
         "%s: unable to calculate chunk size.",
2627
5
         function );
2628
2629
5
        goto on_error;
2630
5
      }
2631
/* TODO refactor */
2632
712
      internal_handle->io_handle->chunk_size = internal_handle->media_values->chunk_size;
2633
2634
      /* Do a preliminary detection of the EWF format for reading the sector table section
2635
       */
2636
712
      if( internal_handle->io_handle->segment_file_type == LIBEWF_SEGMENT_FILE_TYPE_EWF1 )
2637
663
      {
2638
663
        if( header_sections->number_of_header_sections == 1 )
2639
90
        {
2640
90
          internal_handle->io_handle->format = LIBEWF_FORMAT_ENCASE1;
2641
90
        }
2642
573
        else if( internal_handle->media_values->error_granularity == 0 )
2643
2
        {
2644
2
          internal_handle->io_handle->format = LIBEWF_FORMAT_ENCASE2;
2645
2
        }
2646
663
      }
2647
712
      initialize_chunk_values = 0;
2648
712
    }
2649
6.49k
  }
2650
1.38k
  if( header_section_found != 0 )
2651
822
  {
2652
822
    if( libewf_header_sections_parse(
2653
822
         header_sections,
2654
822
         internal_handle->io_handle,
2655
822
         internal_handle->header_values,
2656
822
         &( internal_handle->io_handle->format ),
2657
822
         error ) == -1 )
2658
1
    {
2659
1
      libcerror_error_set(
2660
1
       error,
2661
1
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2662
1
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2663
1
       "%s: unable to parse header sections.",
2664
1
       function );
2665
2666
1
      goto on_error;
2667
1
    }
2668
822
  }
2669
1.38k
  if( single_files_data_stream != NULL )
2670
217
  {
2671
217
    if( libewf_single_files_initialize(
2672
217
         &( internal_handle->single_files ),
2673
217
         error ) != 1 )
2674
0
    {
2675
0
      libcerror_error_set(
2676
0
       error,
2677
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2678
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2679
0
       "%s: unable to create single files.",
2680
0
       function );
2681
2682
0
      goto on_error;
2683
0
    }
2684
217
    if( libewf_single_files_read_data_stream(
2685
217
         internal_handle->single_files,
2686
217
         single_files_data_stream,
2687
217
         file_io_pool,
2688
217
         &( internal_handle->media_values->media_size ),
2689
217
         &( internal_handle->io_handle->format ),
2690
217
         error ) != 1 )
2691
217
    {
2692
217
      libcerror_error_set(
2693
217
       error,
2694
217
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2695
217
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2696
217
       "%s: unable to parse single files.",
2697
217
       function );
2698
2699
217
      goto on_error;
2700
217
    }
2701
0
    if( internal_handle->io_handle->segment_file_type == LIBEWF_SEGMENT_FILE_TYPE_EWF2_LOGICAL )
2702
0
    {
2703
0
      internal_handle->io_handle->format = LIBEWF_FORMAT_V2_LOGICAL_ENCASE7;
2704
0
    }
2705
0
    internal_handle->media_values->number_of_sectors = internal_handle->media_values->media_size
2706
0
                                                     / internal_handle->media_values->bytes_per_sector;
2707
2708
0
    if( ( internal_handle->media_values->media_size % internal_handle->media_values->bytes_per_sector ) != 0 )
2709
0
    {
2710
0
      internal_handle->media_values->number_of_sectors += 1;
2711
0
    }
2712
0
    if( libfdata_stream_free(
2713
0
         &single_files_data_stream,
2714
0
         error ) != 1 )
2715
0
    {
2716
0
      libcerror_error_set(
2717
0
       error,
2718
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2719
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2720
0
       "%s: unable to free single files data stream.",
2721
0
       function );
2722
2723
0
      goto on_error;
2724
0
    }
2725
0
  }
2726
1.16k
  if( libewf_header_sections_free(
2727
1.16k
       &header_sections,
2728
1.16k
       error ) != 1 )
2729
0
  {
2730
0
    libcerror_error_set(
2731
0
     error,
2732
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2733
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2734
0
     "%s: unable to free header sections.",
2735
0
     function );
2736
2737
0
    goto on_error;
2738
0
  }
2739
1.16k
  if( libfcache_cache_free(
2740
1.16k
       &sections_cache,
2741
1.16k
       error ) != 1 )
2742
0
  {
2743
0
    libcerror_error_set(
2744
0
     error,
2745
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2746
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2747
0
     "%s: unable to free sections cache.",
2748
0
     function );
2749
2750
0
    goto on_error;
2751
0
  }
2752
1.16k
  return( 1 );
2753
2754
1.72k
on_error:
2755
1.72k
  if( internal_handle->single_files != NULL )
2756
217
  {
2757
217
    libewf_single_files_free(
2758
217
     &( internal_handle->single_files ),
2759
217
     NULL );
2760
217
  }
2761
1.72k
  if( single_files_data_stream != NULL )
2762
218
  {
2763
218
    libfdata_stream_free(
2764
218
     &single_files_data_stream,
2765
218
     NULL );
2766
218
  }
2767
1.72k
  if( string_data != NULL )
2768
0
  {
2769
0
    memory_free(
2770
0
     string_data );
2771
0
  }
2772
1.72k
  if( header_sections != NULL )
2773
1.72k
  {
2774
1.72k
    libewf_header_sections_free(
2775
1.72k
     &header_sections,
2776
1.72k
     NULL );
2777
1.72k
  }
2778
1.72k
  if( sections_cache != NULL )
2779
1.72k
  {
2780
1.72k
    libfcache_cache_free(
2781
1.72k
     &sections_cache,
2782
1.72k
     NULL );
2783
1.72k
  }
2784
1.72k
  return( -1 );
2785
1.16k
}
2786
2787
/* Opens the segment files for reading
2788
 * Returns 1 if successful or -1 on error
2789
 */
2790
int libewf_internal_handle_open_read_segment_files(
2791
     libewf_internal_handle_t *internal_handle,
2792
     libbfio_pool_t *file_io_pool,
2793
     libewf_segment_table_t *segment_table,
2794
     libcerror_error_t **error )
2795
3.16k
{
2796
3.16k
  libewf_segment_file_t *segment_file = NULL;
2797
3.16k
  static char *function               = "libewf_internal_handle_open_read_segment_files";
2798
3.16k
  size64_t maximum_segment_size       = 0;
2799
3.16k
  size64_t segment_file_size          = 0;
2800
3.16k
  uint32_t number_of_segments         = 0;
2801
3.16k
  uint32_t segment_number             = 0;
2802
3.16k
  int file_io_pool_entry              = 0;
2803
3.16k
  int last_segment_file               = 0;
2804
2805
3.16k
  if( internal_handle == NULL )
2806
0
  {
2807
0
    libcerror_error_set(
2808
0
     error,
2809
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2810
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2811
0
     "%s: invalid handle.",
2812
0
     function );
2813
2814
0
    return( -1 );
2815
0
  }
2816
3.16k
  if( internal_handle->io_handle == NULL )
2817
0
  {
2818
0
    libcerror_error_set(
2819
0
     error,
2820
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2821
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2822
0
     "%s: invalid handle - missing IO handle.",
2823
0
     function );
2824
2825
0
    return( -1 );
2826
0
  }
2827
3.16k
  if( internal_handle->read_io_handle == NULL )
2828
0
  {
2829
0
    libcerror_error_set(
2830
0
     error,
2831
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2832
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2833
0
     "%s: invalid handle - missing read IO handle.",
2834
0
     function );
2835
2836
0
    return( -1 );
2837
0
  }
2838
3.16k
  if( segment_table == NULL )
2839
0
  {
2840
0
    libcerror_error_set(
2841
0
     error,
2842
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2843
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2844
0
     "%s: invalid segment table.",
2845
0
     function );
2846
2847
0
    return( -1 );
2848
0
  }
2849
3.16k
  if( libewf_segment_table_get_number_of_segments(
2850
3.16k
       segment_table,
2851
3.16k
       &number_of_segments,
2852
3.16k
       error ) != 1 )
2853
0
  {
2854
0
    libcerror_error_set(
2855
0
     error,
2856
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2857
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2858
0
     "%s: unable to retrieve number of segments from segment table.",
2859
0
     function );
2860
2861
0
    return( -1 );
2862
0
  }
2863
  /* Make sure to read the device information section first so we
2864
   * have the correct chunk size when reading Lx01 files.
2865
   */
2866
3.16k
  if( libewf_internal_handle_open_read_device_information(
2867
3.16k
       internal_handle,
2868
3.16k
       file_io_pool,
2869
3.16k
       segment_table,
2870
3.16k
       number_of_segments,
2871
3.16k
       error ) != 1 )
2872
280
  {
2873
280
    libcerror_error_set(
2874
280
     error,
2875
280
     LIBCERROR_ERROR_DOMAIN_IO,
2876
280
     LIBCERROR_IO_ERROR_READ_FAILED,
2877
280
     "%s: unable to read device information.",
2878
280
     function );
2879
2880
280
    return( -1 );
2881
280
  }
2882
2.88k
  for( segment_number = 0;
2883
4.04k
       segment_number < number_of_segments;
2884
2.88k
       segment_number++ )
2885
2.88k
  {
2886
2.88k
    if( libewf_segment_table_get_segment_by_index(
2887
2.88k
         segment_table,
2888
2.88k
         segment_number,
2889
2.88k
         &file_io_pool_entry,
2890
2.88k
         &segment_file_size,
2891
2.88k
         error ) != 1 )
2892
0
    {
2893
0
      libcerror_error_set(
2894
0
       error,
2895
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2896
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2897
0
       "%s: unable to retrieve segment: %" PRIu32 " from segment table.",
2898
0
       function,
2899
0
       segment_number );
2900
2901
0
      return( -1 );
2902
0
    }
2903
2.88k
    if( ( segment_number == 0 )
2904
2.88k
     && ( number_of_segments > 1 ) )
2905
0
    {
2906
      /* Round the maximum segment size to nearest number of KiB
2907
       */
2908
0
      maximum_segment_size = ( segment_file_size >> 10 ) << 10;
2909
2910
0
      if( libewf_segment_table_set_maximum_segment_size(
2911
0
           segment_table,
2912
0
           maximum_segment_size,
2913
0
           error ) != 1 )
2914
0
      {
2915
0
        libcerror_error_set(
2916
0
         error,
2917
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2918
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2919
0
         "%s: unable to set maximum segment size in segment table.",
2920
0
         function );
2921
2922
0
        return( -1 );
2923
0
      }
2924
0
    }
2925
2.88k
    if( libewf_segment_table_get_segment_file_by_index(
2926
2.88k
         segment_table,
2927
2.88k
         segment_number,
2928
2.88k
         file_io_pool,
2929
2.88k
         &segment_file,
2930
2.88k
         error ) != 1 )
2931
0
    {
2932
0
      libcerror_error_set(
2933
0
       error,
2934
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2935
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2936
0
       "%s: unable to retrieve segment file: %" PRIu32 " from segment table.",
2937
0
       function,
2938
0
       segment_number );
2939
2940
0
      return( -1 );
2941
0
    }
2942
2.88k
    if( segment_file == NULL )
2943
0
    {
2944
0
      libcerror_error_set(
2945
0
       error,
2946
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2947
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2948
0
       "%s: missing segment file: %" PRIu32 ".",
2949
0
       function,
2950
0
       segment_number );
2951
2952
0
      return( -1 );
2953
0
    }
2954
2.88k
    if( segment_file->segment_number != ( segment_number + 1 ) )
2955
0
    {
2956
0
      libcerror_error_set(
2957
0
       error,
2958
0
       LIBCERROR_ERROR_DOMAIN_INPUT,
2959
0
       LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
2960
0
       "%s: segment number mismatch ( stored: %" PRIu32 ", expected: %" PRIu32 " ).",
2961
0
       function,
2962
0
       segment_file->segment_number,
2963
0
       segment_number + 1 );
2964
2965
0
      return( -1 );
2966
0
    }
2967
2.88k
    if( segment_file->segment_number == 1 )
2968
2.88k
    {
2969
2.88k
      internal_handle->io_handle->segment_file_type  = segment_file->type;
2970
2.88k
      internal_handle->io_handle->major_version      = segment_file->major_version;
2971
2.88k
      internal_handle->io_handle->minor_version      = segment_file->minor_version;
2972
2.88k
      internal_handle->io_handle->compression_method = segment_file->compression_method;
2973
2974
2.88k
      if( segment_file->major_version == 2 )
2975
0
      {
2976
0
        if( memory_copy(
2977
0
             internal_handle->media_values->set_identifier,
2978
0
             segment_file->set_identifier,
2979
0
             16 ) == NULL )
2980
0
        {
2981
0
          libcerror_error_set(
2982
0
           error,
2983
0
           LIBCERROR_ERROR_DOMAIN_MEMORY,
2984
0
           LIBCERROR_MEMORY_ERROR_COPY_FAILED,
2985
0
           "%s: unable to copy segment file set identifier to media values.",
2986
0
           function );
2987
2988
0
          return( -1 );
2989
0
        }
2990
0
      }
2991
2.88k
    }
2992
0
    else
2993
0
    {
2994
0
      if( ( segment_file->major_version != internal_handle->io_handle->major_version )
2995
0
       || ( segment_file->minor_version != internal_handle->io_handle->minor_version ) )
2996
0
      {
2997
0
        libcerror_error_set(
2998
0
         error,
2999
0
         LIBCERROR_ERROR_DOMAIN_INPUT,
3000
0
         LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
3001
0
         "%s: segment file format version value mismatch.",
3002
0
         function );
3003
3004
0
        return( -1 );
3005
0
      }
3006
0
      if( internal_handle->io_handle->major_version == 2 )
3007
0
      {
3008
0
        if( segment_file->compression_method != internal_handle->io_handle->compression_method )
3009
0
        {
3010
0
          libcerror_error_set(
3011
0
           error,
3012
0
           LIBCERROR_ERROR_DOMAIN_INPUT,
3013
0
           LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
3014
0
           "%s: segment file compression method value mismatch.",
3015
0
           function );
3016
3017
0
          return( -1 );
3018
0
        }
3019
0
        if( memory_compare(
3020
0
             internal_handle->media_values->set_identifier,
3021
0
             segment_file->set_identifier,
3022
0
             16 ) != 0 )
3023
0
        {
3024
0
          libcerror_error_set(
3025
0
           error,
3026
0
           LIBCERROR_ERROR_DOMAIN_INPUT,
3027
0
           LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
3028
0
           "%s: segment file set identifier value mismatch.",
3029
0
           function );
3030
3031
0
          return( -1 );
3032
0
        }
3033
0
      }
3034
0
    }
3035
2.88k
    if( ( segment_file->flags & LIBEWF_SEGMENT_FILE_FLAG_IS_LAST ) != 0 )
3036
12
    {
3037
12
      last_segment_file = 1;
3038
12
    }
3039
2.88k
    if( ( segment_file->flags & LIBEWF_SEGMENT_FILE_FLAG_IS_ENCRYPTED ) != 0 )
3040
0
    {
3041
/* TODO get key info */
3042
0
      internal_handle->io_handle->format       = LIBEWF_FORMAT_V2_ENCASE7;
3043
0
      internal_handle->io_handle->is_encrypted = 1;
3044
0
    }
3045
2.88k
    if( libewf_internal_handle_open_read_segment_file_section_data(
3046
2.88k
         internal_handle,
3047
2.88k
         segment_file,
3048
2.88k
         file_io_pool,
3049
2.88k
         file_io_pool_entry,
3050
2.88k
         error ) != 1 )
3051
1.72k
    {
3052
1.72k
      libcerror_error_set(
3053
1.72k
       error,
3054
1.72k
       LIBCERROR_ERROR_DOMAIN_IO,
3055
1.72k
       LIBCERROR_IO_ERROR_READ_FAILED,
3056
1.72k
       "%s: unable to read section data from segment file: %" PRIu32 ".",
3057
1.72k
       function,
3058
1.72k
       segment_number );
3059
3060
1.72k
      return( -1 );
3061
1.72k
    }
3062
1.16k
    if( ( segment_file->flags & LIBEWF_SEGMENT_FILE_FLAG_IS_CORRUPTED ) != 0 )
3063
1.15k
    {
3064
1.15k
      segment_table->flags |= LIBEWF_SEGMENT_TABLE_FLAG_IS_CORRUPTED;
3065
1.15k
    }
3066
1.16k
    if( libewf_segment_table_set_segment_storage_media_size_by_index(
3067
1.16k
         segment_table,
3068
1.16k
         segment_number,
3069
1.16k
         segment_file->storage_media_size,
3070
1.16k
         error ) != 1 )
3071
0
    {
3072
0
      libcerror_error_set(
3073
0
       error,
3074
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3075
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
3076
0
       "%s: unable to set mapped range of element: %" PRIu32 " in segment table.",
3077
0
       function,
3078
0
       segment_number );
3079
3080
0
      return( -1 );
3081
0
    }
3082
1.16k
    internal_handle->read_io_handle->storage_media_size_read += segment_file->storage_media_size;
3083
1.16k
    internal_handle->read_io_handle->number_of_chunks_read   += segment_file->number_of_chunks;
3084
1.16k
  }
3085
1.16k
  if( last_segment_file == 0 )
3086
1.15k
  {
3087
1.15k
    libcerror_error_set(
3088
1.15k
     error,
3089
1.15k
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3090
1.15k
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3091
1.15k
     "%s: missing done section.",
3092
1.15k
     function );
3093
3094
#if defined( HAVE_DEBUG_OUTPUT )
3095
    if( libcnotify_verbose != 0 )
3096
    {
3097
      if( ( error != NULL )
3098
       && ( *error != NULL ) )
3099
      {
3100
        libcnotify_print_error_backtrace(
3101
         *error );
3102
      }
3103
    }
3104
#endif
3105
1.15k
    libcerror_error_free(
3106
1.15k
     error );
3107
3108
1.15k
    segment_table->flags |= LIBEWF_SEGMENT_TABLE_FLAG_IS_CORRUPTED;
3109
1.15k
  }
3110
1.16k
  return( 1 );
3111
2.88k
}
3112
3113
/* Reads the device information from the segment files
3114
 * Returns 1 if successful or -1 on error
3115
 */
3116
int libewf_internal_handle_open_read_device_information(
3117
     libewf_internal_handle_t *internal_handle,
3118
     libbfio_pool_t *file_io_pool,
3119
     libewf_segment_table_t *segment_table,
3120
     uint32_t number_of_segments,
3121
     libcerror_error_t **error )
3122
3.16k
{
3123
3.16k
  libewf_section_descriptor_t *section_descriptor = NULL;
3124
3.16k
  libewf_segment_file_t *segment_file             = NULL;
3125
3.16k
  libfcache_cache_t *sections_cache               = NULL;
3126
3.16k
  static char *function                           = "libewf_internal_handle_open_read_device_information";
3127
3.16k
  size64_t segment_file_size                      = 0;
3128
3.16k
  ssize_t read_count                              = 0;
3129
3.16k
  uint32_t segment_number                         = 0;
3130
3.16k
  int file_io_pool_entry                          = 0;
3131
3132
3.16k
  if( internal_handle == NULL )
3133
0
  {
3134
0
    libcerror_error_set(
3135
0
     error,
3136
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3137
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3138
0
     "%s: invalid handle.",
3139
0
     function );
3140
3141
0
    return( -1 );
3142
0
  }
3143
3.16k
  if( number_of_segments == 0 )
3144
0
  {
3145
0
    libcerror_error_set(
3146
0
     error,
3147
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3148
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3149
0
     "%s: invalid number of segments value out of bounds.",
3150
0
     function );
3151
3152
0
    return( -1 );
3153
0
  }
3154
3.16k
  if( libewf_segment_table_get_segment_file_by_index(
3155
3.16k
       segment_table,
3156
3.16k
       segment_number,
3157
3.16k
       file_io_pool,
3158
3.16k
       &segment_file,
3159
3.16k
       error ) != 1 )
3160
87
  {
3161
87
    libcerror_error_set(
3162
87
     error,
3163
87
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3164
87
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3165
87
     "%s: unable to retrieve segment file: %" PRIu32 " from segment table.",
3166
87
     function,
3167
87
     segment_number );
3168
3169
87
    goto on_error;
3170
87
  }
3171
3.07k
  if( segment_file == NULL )
3172
0
  {
3173
0
    libcerror_error_set(
3174
0
     error,
3175
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3176
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3177
0
     "%s: missing segment file: %" PRIu32 ".",
3178
0
     function,
3179
0
     segment_number );
3180
3181
0
    goto on_error;
3182
0
  }
3183
3.07k
  if( segment_file->major_version != 2 )
3184
2.88k
  {
3185
2.88k
    return( 1 );
3186
2.88k
  }
3187
193
  if( segment_file->device_information_section_index == -1 )
3188
193
  {
3189
    /* Lx01 stores the device information in the last segment file
3190
     */
3191
193
    segment_number = number_of_segments - 1;
3192
3193
193
    if( libewf_segment_table_get_segment_file_by_index(
3194
193
         segment_table,
3195
193
         segment_number,
3196
193
         file_io_pool,
3197
193
         &segment_file,
3198
193
         error ) != 1 )
3199
0
    {
3200
0
      libcerror_error_set(
3201
0
       error,
3202
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3203
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3204
0
       "%s: unable to retrieve segment file: %" PRIu32 " from segment table.",
3205
0
       function,
3206
0
       segment_number );
3207
3208
0
      goto on_error;
3209
0
    }
3210
193
    if( segment_file == NULL )
3211
0
    {
3212
0
      libcerror_error_set(
3213
0
       error,
3214
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3215
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3216
0
       "%s: missing segment file: %" PRIu32 ".",
3217
0
       function,
3218
0
       segment_number );
3219
3220
0
      goto on_error;
3221
0
    }
3222
193
  }
3223
193
  if( segment_file->device_information_section_index == -1 )
3224
193
  {
3225
193
    libcerror_error_set(
3226
193
     error,
3227
193
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3228
193
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3229
193
     "%s: unable to locate a device information section.",
3230
193
     function );
3231
3232
193
    goto on_error;
3233
193
  }
3234
0
  if( libewf_segment_table_get_segment_by_index(
3235
0
       segment_table,
3236
0
       segment_number,
3237
0
       &file_io_pool_entry,
3238
0
       &segment_file_size,
3239
0
       error ) != 1 )
3240
0
  {
3241
0
    libcerror_error_set(
3242
0
     error,
3243
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3244
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3245
0
     "%s: unable to retrieve segment: %" PRIu32 " from segment table.",
3246
0
     function,
3247
0
     segment_number );
3248
3249
0
    goto on_error;
3250
0
  }
3251
0
  if( libfcache_cache_initialize(
3252
0
       &sections_cache,
3253
0
       LIBEWF_MAXIMUM_CACHE_ENTRIES_SECTIONS,
3254
0
       error ) != 1 )
3255
0
  {
3256
0
    libcerror_error_set(
3257
0
     error,
3258
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3259
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3260
0
     "%s: unable to create sections cache.",
3261
0
     function );
3262
3263
0
    goto on_error;
3264
0
  }
3265
0
  if( libfdata_list_get_element_value_by_index(
3266
0
       segment_file->sections_list,
3267
0
       (intptr_t *) file_io_pool,
3268
0
       (libfdata_cache_t *) sections_cache,
3269
0
       segment_file->device_information_section_index,
3270
0
       (intptr_t **) &section_descriptor,
3271
0
       0,
3272
0
       error ) != 1 )
3273
0
  {
3274
0
    libcerror_error_set(
3275
0
     error,
3276
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3277
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3278
0
     "%s: unable to retrieve section: %d from sections list.",
3279
0
     function,
3280
0
     segment_file->device_information_section_index );
3281
3282
0
    goto on_error;
3283
0
  }
3284
0
  if( libewf_segment_file_seek_offset(
3285
0
       segment_file,
3286
0
       file_io_pool,
3287
0
       file_io_pool_entry,
3288
0
       section_descriptor->start_offset,
3289
0
       error ) == -1 )
3290
0
  {
3291
0
    libcerror_error_set(
3292
0
     error,
3293
0
     LIBCERROR_ERROR_DOMAIN_IO,
3294
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
3295
0
     "%s: unable to seek section: %d data offset: %" PRIu64 " (0x%08%" PRIx64 ").",
3296
0
     function,
3297
0
     segment_file->device_information_section_index,
3298
0
     section_descriptor->start_offset );
3299
3300
0
    goto on_error;
3301
0
  }
3302
0
  read_count = libewf_device_information_section_read_file_io_pool(
3303
0
          section_descriptor,
3304
0
          internal_handle->io_handle,
3305
0
          file_io_pool,
3306
0
          file_io_pool_entry,
3307
0
          internal_handle->read_io_handle,
3308
0
          internal_handle->media_values,
3309
0
          internal_handle->header_values,
3310
0
          error );
3311
3312
0
  if( read_count == -1 )
3313
0
  {
3314
0
    libcerror_error_set(
3315
0
     error,
3316
0
     LIBCERROR_ERROR_DOMAIN_IO,
3317
0
     LIBCERROR_IO_ERROR_READ_FAILED,
3318
0
     "%s: unable to read device information section: %d.",
3319
0
     function,
3320
0
     segment_file->device_information_section_index );
3321
3322
0
    goto on_error;
3323
0
  }
3324
0
  if( libfcache_cache_free(
3325
0
       &sections_cache,
3326
0
       error ) != 1 )
3327
0
  {
3328
0
    libcerror_error_set(
3329
0
     error,
3330
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3331
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3332
0
     "%s: unable to free sections cache.",
3333
0
     function );
3334
3335
0
    goto on_error;
3336
0
  }
3337
0
  return( 1 );
3338
3339
280
on_error:
3340
280
  if( sections_cache != NULL )
3341
0
  {
3342
0
    libfcache_cache_free(
3343
0
     &sections_cache,
3344
0
     NULL );
3345
0
  }
3346
280
  return( -1 );
3347
0
}
3348
3349
/* Opens a set of EWF file(s) using a Basic File IO (bfio) pool
3350
 * This function is not multi-thread safe acquire write lock before call
3351
 * Returns 1 if successful or -1 on error
3352
 */
3353
int libewf_internal_handle_open_file_io_pool(
3354
     libewf_internal_handle_t *internal_handle,
3355
     libbfio_pool_t *file_io_pool,
3356
     int access_flags,
3357
     libewf_segment_table_t *segment_table,
3358
     libcerror_error_t **error )
3359
3.31k
{
3360
3.31k
  libbfio_handle_t *file_io_handle    = NULL;
3361
3.31k
  libewf_segment_file_t *segment_file = NULL;
3362
3.31k
  static char *function               = "libewf_internal_handle_open_file_io_pool";
3363
3.31k
  size64_t segment_file_size          = 0;
3364
3.31k
  ssize_t read_count                  = 0;
3365
3.31k
  int file_io_pool_entry              = 0;
3366
3.31k
  int number_of_file_io_handles       = 0;
3367
3368
3.31k
  if( internal_handle == NULL )
3369
0
  {
3370
0
    libcerror_error_set(
3371
0
     error,
3372
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3373
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3374
0
     "%s: invalid handle.",
3375
0
     function );
3376
3377
0
    return( -1 );
3378
0
  }
3379
3.31k
  if( internal_handle->io_handle == NULL )
3380
0
  {
3381
0
    libcerror_error_set(
3382
0
     error,
3383
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3384
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3385
0
     "%s: invalid handle - missing IO handle.",
3386
0
     function );
3387
3388
0
    return( -1 );
3389
0
  }
3390
3.31k
  if( internal_handle->file_io_pool != NULL )
3391
0
  {
3392
0
    libcerror_error_set(
3393
0
     error,
3394
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3395
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3396
0
     "%s: invalid handle - file IO pool value already set.",
3397
0
     function );
3398
3399
0
    return( -1 );
3400
0
  }
3401
3.31k
  if( internal_handle->chunk_table != NULL )
3402
0
  {
3403
0
    libcerror_error_set(
3404
0
     error,
3405
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3406
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3407
0
     "%s: invalid handle - chunk table value already set.",
3408
0
     function );
3409
3410
0
    return( -1 );
3411
0
  }
3412
3.31k
  if( internal_handle->hash_sections != NULL )
3413
0
  {
3414
0
    libcerror_error_set(
3415
0
     error,
3416
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3417
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3418
0
     "%s: invalid handle - hash sections value already set.",
3419
0
     function );
3420
3421
0
    return( -1 );
3422
0
  }
3423
3.31k
  if( internal_handle->single_files != NULL )
3424
0
  {
3425
0
    libcerror_error_set(
3426
0
     error,
3427
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3428
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3429
0
     "%s: invalid handle - single files value already set.",
3430
0
     function );
3431
3432
0
    return( -1 );
3433
0
  }
3434
3.31k
  if( file_io_pool == NULL )
3435
0
  {
3436
0
    libcerror_error_set(
3437
0
     error,
3438
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3439
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3440
0
     "%s: invalid file IO pool.",
3441
0
     function );
3442
3443
0
    return( -1 );
3444
0
  }
3445
3.31k
  if( ( ( access_flags & ~( LIBEWF_ACCESS_FLAG_READ | LIBEWF_ACCESS_FLAG_WRITE | LIBEWF_ACCESS_FLAG_RESUME ) ) != 0 )
3446
3.31k
   || ( ( ( access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
3447
3.31k
    &&  ( ( access_flags & LIBEWF_ACCESS_FLAG_WRITE ) != 0 ) ) )
3448
0
  {
3449
0
    libcerror_error_set(
3450
0
     error,
3451
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3452
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3453
0
     "%s: unsupported access flags.",
3454
0
     function );
3455
3456
0
    return( -1 );
3457
0
  }
3458
3.31k
  if( ( ( access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
3459
0
   || ( ( access_flags & LIBEWF_ACCESS_FLAG_RESUME ) != 0 ) )
3460
3.31k
  {
3461
3.31k
    if( libewf_read_io_handle_initialize(
3462
3.31k
         &( internal_handle->read_io_handle ),
3463
3.31k
         error ) != 1 )
3464
0
    {
3465
0
      libcerror_error_set(
3466
0
       error,
3467
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3468
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3469
0
       "%s: unable to create read IO handle.",
3470
0
       function );
3471
3472
0
      goto on_error;
3473
0
    }
3474
3.31k
  }
3475
3.31k
  if( ( access_flags & LIBEWF_ACCESS_FLAG_WRITE ) != 0 )
3476
0
  {
3477
0
    if( libewf_write_io_handle_initialize(
3478
0
         &( internal_handle->write_io_handle ),
3479
0
         internal_handle->io_handle,
3480
0
         error ) != 1 )
3481
0
    {
3482
0
      libcerror_error_set(
3483
0
       error,
3484
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3485
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3486
0
       "%s: unable to create write IO handle.",
3487
0
       function );
3488
3489
0
      goto on_error;
3490
0
    }
3491
0
  }
3492
3.31k
  if( libewf_chunk_table_initialize(
3493
3.31k
       &( internal_handle->chunk_table ),
3494
3.31k
       internal_handle->io_handle,
3495
3.31k
       error ) != 1 )
3496
0
  {
3497
0
    libcerror_error_set(
3498
0
     error,
3499
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3500
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3501
0
     "%s: unable to create chunk table.",
3502
0
     function );
3503
3504
0
    goto on_error;
3505
0
  }
3506
3.31k
  if( libewf_header_values_initialize(
3507
3.31k
       &( internal_handle->header_values ),
3508
3.31k
       error ) != 1 )
3509
0
  {
3510
0
    libcerror_error_set(
3511
0
     error,
3512
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3513
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3514
0
     "%s: unable to create header values.",
3515
0
     function );
3516
3517
0
    goto on_error;
3518
0
  }
3519
3.31k
  if( libewf_hash_sections_initialize(
3520
3.31k
       &( internal_handle->hash_sections ),
3521
3.31k
       error ) != 1 )
3522
0
  {
3523
0
    libcerror_error_set(
3524
0
     error,
3525
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3526
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3527
0
     "%s: unable to create hash sections.",
3528
0
     function );
3529
3530
0
    goto on_error;
3531
0
  }
3532
3.31k
  if( libcdata_array_empty(
3533
3.31k
       internal_handle->sessions,
3534
3.31k
       (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
3535
3.31k
       error ) != 1 )
3536
0
  {
3537
0
    libcerror_error_set(
3538
0
     error,
3539
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3540
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3541
0
     "%s: unable to empty sessions array.",
3542
0
     function );
3543
3544
0
    goto on_error;
3545
0
  }
3546
3.31k
  if( libcdata_array_empty(
3547
3.31k
       internal_handle->tracks,
3548
3.31k
       (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
3549
3.31k
       error ) != 1 )
3550
0
  {
3551
0
    libcerror_error_set(
3552
0
     error,
3553
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3554
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3555
0
     "%s: unable to empty tracks array.",
3556
0
     function );
3557
3558
0
    goto on_error;
3559
0
  }
3560
3.31k
  if( libcdata_range_list_empty(
3561
3.31k
       internal_handle->acquiry_errors,
3562
3.31k
       NULL,
3563
3.31k
       error ) != 1 )
3564
0
  {
3565
0
    libcerror_error_set(
3566
0
     error,
3567
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3568
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3569
0
     "%s: unable to empty acquiry errors range list.",
3570
0
     function );
3571
3572
0
    goto on_error;
3573
0
  }
3574
3.31k
  if( ( ( access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
3575
0
   || ( ( access_flags & LIBEWF_ACCESS_FLAG_RESUME ) != 0 ) )
3576
3.31k
  {
3577
3.31k
    if( libbfio_pool_get_number_of_handles(
3578
3.31k
         file_io_pool,
3579
3.31k
         &number_of_file_io_handles,
3580
3.31k
         error ) != 1 )
3581
0
    {
3582
0
      libcerror_error_set(
3583
0
       error,
3584
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3585
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3586
0
       "%s: unable to retrieve the number of handles in the pool.",
3587
0
       function );
3588
3589
0
      goto on_error;
3590
0
    }
3591
3.31k
    if( libewf_segment_file_initialize(
3592
3.31k
         &segment_file,
3593
3.31k
         internal_handle->io_handle,
3594
3.31k
         error ) != 1 )
3595
0
    {
3596
0
      libcerror_error_set(
3597
0
       error,
3598
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3599
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3600
0
       "%s: unable to create segment file.",
3601
0
       function );
3602
3603
0
      goto on_error;
3604
0
    }
3605
3.31k
    for( file_io_pool_entry = 0;
3606
6.48k
         file_io_pool_entry < number_of_file_io_handles;
3607
3.31k
         file_io_pool_entry++ )
3608
3.31k
    {
3609
3.31k
      if( libbfio_pool_get_size(
3610
3.31k
           file_io_pool,
3611
3.31k
           file_io_pool_entry,
3612
3.31k
           &segment_file_size,
3613
3.31k
           error ) != 1 )
3614
0
      {
3615
0
        libcerror_error_set(
3616
0
         error,
3617
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3618
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3619
0
         "%s: unable to retrieve size of file IO pool entry: %d.",
3620
0
         function,
3621
0
         file_io_pool_entry );
3622
3623
0
        goto on_error;
3624
0
      }
3625
3.31k
      if( libbfio_pool_get_handle(
3626
3.31k
           file_io_pool,
3627
3.31k
           file_io_pool_entry,
3628
3.31k
           &file_io_handle,
3629
3.31k
           error ) != 1 )
3630
0
      {
3631
0
        libcerror_error_set(
3632
0
         error,
3633
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3634
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
3635
0
         "%s: unable to retrieve file IO handle: %d from pool.",
3636
0
         function,
3637
0
         file_io_pool_entry );
3638
3639
0
        goto on_error;
3640
0
      }
3641
#if defined( HAVE_DEBUG_OUTPUT )
3642
      if( libcnotify_verbose != 0 )
3643
      {
3644
        libcnotify_printf(
3645
         "%s: processing file IO pool entry: %d.\n",
3646
         function,
3647
         file_io_pool_entry );
3648
      }
3649
#endif
3650
3.31k
      read_count = libewf_segment_file_read_file_header_file_io_pool(
3651
3.31k
              segment_file,
3652
3.31k
              file_io_pool,
3653
3.31k
              file_io_pool_entry,
3654
3.31k
              error );
3655
3656
3.31k
      if( read_count < 0 )
3657
86
      {
3658
86
        libcerror_error_set(
3659
86
         error,
3660
86
         LIBCERROR_ERROR_DOMAIN_IO,
3661
86
         LIBCERROR_IO_ERROR_READ_FAILED,
3662
86
         "%s: unable to read segment file header.",
3663
86
         function );
3664
3665
86
        goto on_error;
3666
86
      }
3667
3.23k
      if( segment_file->segment_number == 0 )
3668
1
      {
3669
1
        libcerror_error_set(
3670
1
         error,
3671
1
         LIBCERROR_ERROR_DOMAIN_INPUT,
3672
1
         LIBCERROR_INPUT_ERROR_INVALID_DATA,
3673
1
         "%s: invalid segment number: 0 in file IO pool entry: %d.",
3674
1
         function,
3675
1
         file_io_pool_entry );
3676
3677
1
        goto on_error;
3678
1
      }
3679
3.23k
      if( libewf_segment_table_append_segment_by_segment_file(
3680
3.23k
           segment_table,
3681
3.23k
           segment_file,
3682
3.23k
           file_io_pool_entry,
3683
3.23k
           segment_file_size,
3684
3.23k
           error ) != 1 )
3685
68
      {
3686
68
        libcerror_error_set(
3687
68
         error,
3688
68
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3689
68
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
3690
68
         "%s: unable to append segment: %" PRIu32 " to segment table.",
3691
68
         function,
3692
68
         segment_file->segment_number );
3693
3694
68
        goto on_error;
3695
68
      }
3696
3.23k
    }
3697
3.16k
    if( libewf_segment_file_free(
3698
3.16k
         &segment_file,
3699
3.16k
         error ) != 1 )
3700
0
    {
3701
0
      libcerror_error_set(
3702
0
       error,
3703
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3704
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3705
0
       "%s: unable to free segment file.",
3706
0
       function );
3707
3708
0
      goto on_error;
3709
0
    }
3710
3.16k
    if( libewf_internal_handle_open_read_segment_files(
3711
3.16k
         internal_handle,
3712
3.16k
         file_io_pool,
3713
3.16k
         segment_table,
3714
3.16k
         error ) != 1 )
3715
2.00k
    {
3716
2.00k
      libcerror_error_set(
3717
2.00k
       error,
3718
2.00k
       LIBCERROR_ERROR_DOMAIN_IO,
3719
2.00k
       LIBCERROR_IO_ERROR_READ_FAILED,
3720
2.00k
       "%s: unable to read segment files.",
3721
2.00k
       function );
3722
3723
2.00k
      if( ( access_flags & LIBEWF_ACCESS_FLAG_RESUME ) == 0 )
3724
2.00k
      {
3725
2.00k
        goto on_error;
3726
2.00k
      }
3727
#if defined( HAVE_DEBUG_OUTPUT )
3728
      if( libcnotify_verbose != 0 )
3729
      {
3730
        if( ( error != NULL )
3731
         && ( *error != NULL ) )
3732
        {
3733
          libcnotify_print_error_backtrace(
3734
           *error );
3735
        }
3736
      }
3737
#endif
3738
0
      libcerror_error_free(
3739
0
       error );
3740
0
    }
3741
1.16k
    if( internal_handle->media_values == NULL )
3742
0
    {
3743
0
      libcerror_error_set(
3744
0
       error,
3745
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3746
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3747
0
       "%s: invalid handle - missing media values.",
3748
0
       function );
3749
3750
0
      goto on_error;
3751
0
    }
3752
/* TODO refactor */
3753
1.16k
    if( internal_handle->single_files == NULL )
3754
1.16k
    {
3755
1.16k
      if( libewf_internal_handle_get_media_values(
3756
1.16k
           internal_handle,
3757
1.16k
           &( internal_handle->media_values->media_size ),
3758
1.16k
           error ) != 1 )
3759
0
      {
3760
0
        libcerror_error_set(
3761
0
         error,
3762
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3763
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3764
0
         "%s: unable to determine media values.",
3765
0
         function );
3766
3767
0
        goto on_error;
3768
0
      }
3769
1.16k
    }
3770
1.16k
  }
3771
1.16k
  if( ( ( access_flags & LIBEWF_ACCESS_FLAG_WRITE ) != 0 )
3772
0
   && ( ( access_flags & LIBEWF_ACCESS_FLAG_RESUME ) != 0 ) )
3773
0
  {
3774
0
    if( ( internal_handle->write_io_handle != NULL )
3775
0
     && ( internal_handle->write_io_handle->values_initialized == 0 ) )
3776
0
    {
3777
0
      if( libewf_write_io_handle_initialize_values(
3778
0
           internal_handle->write_io_handle,
3779
0
           internal_handle->io_handle,
3780
0
           internal_handle->media_values,
3781
0
           segment_table,
3782
0
           error ) != 1 )
3783
0
      {
3784
0
        libcerror_error_set(
3785
0
         error,
3786
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3787
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3788
0
         "%s: unable to initialize write IO handle values.",
3789
0
         function );
3790
3791
0
        goto on_error;
3792
0
      }
3793
0
    }
3794
0
    if( libewf_write_io_handle_initialize_resume(
3795
0
         internal_handle->write_io_handle,
3796
0
         internal_handle->io_handle,
3797
0
         file_io_pool,
3798
0
         internal_handle->media_values,
3799
0
         segment_table,
3800
0
         internal_handle->read_io_handle,
3801
0
         &( internal_handle->current_offset ),
3802
0
         error ) != 1 )
3803
0
    {
3804
0
      libcerror_error_set(
3805
0
       error,
3806
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3807
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3808
0
       "%s: unable to initialize write IO handle to resume.",
3809
0
       function );
3810
3811
0
      goto on_error;
3812
0
    }
3813
0
  }
3814
1.16k
  internal_handle->io_handle->chunk_size   = internal_handle->media_values->chunk_size;
3815
1.16k
  internal_handle->io_handle->access_flags = access_flags;
3816
3817
1.16k
  return( 1 );
3818
3819
2.15k
on_error:
3820
2.15k
  if( segment_file != NULL )
3821
155
  {
3822
155
    libewf_segment_file_free(
3823
155
     &segment_file,
3824
155
     NULL );
3825
155
  }
3826
2.15k
  if( internal_handle->single_files != NULL )
3827
0
  {
3828
0
    libewf_single_files_free(
3829
0
     &( internal_handle->single_files ),
3830
0
     NULL );
3831
0
  }
3832
2.15k
  if( internal_handle->hash_sections != NULL )
3833
2.15k
  {
3834
2.15k
    libewf_hash_sections_free(
3835
2.15k
     &( internal_handle->hash_sections ),
3836
2.15k
     NULL );
3837
2.15k
  }
3838
2.15k
  if( internal_handle->header_values != NULL )
3839
2.15k
  {
3840
2.15k
    libfvalue_table_free(
3841
2.15k
     &( internal_handle->header_values ),
3842
2.15k
     NULL );
3843
2.15k
  }
3844
2.15k
  if( internal_handle->chunk_table != NULL )
3845
2.15k
  {
3846
2.15k
    libewf_chunk_table_free(
3847
2.15k
     &( internal_handle->chunk_table ),
3848
2.15k
     NULL );
3849
2.15k
  }
3850
2.15k
  if( internal_handle->write_io_handle != NULL )
3851
0
  {
3852
0
    libewf_write_io_handle_free(
3853
0
     &( internal_handle->write_io_handle ),
3854
0
     NULL );
3855
0
  }
3856
2.15k
  if( internal_handle->read_io_handle != NULL )
3857
2.15k
  {
3858
2.15k
    libewf_read_io_handle_free(
3859
2.15k
     &( internal_handle->read_io_handle ),
3860
2.15k
     NULL );
3861
2.15k
  }
3862
2.15k
  return( -1 );
3863
1.16k
}
3864
3865
/* Opens a set of EWF file(s) using a Basic File IO (bfio) pool
3866
 * Returns 1 if successful or -1 on error
3867
 */
3868
int libewf_handle_open_file_io_pool(
3869
     libewf_handle_t *handle,
3870
     libbfio_pool_t *file_io_pool,
3871
     int access_flags,
3872
     libcerror_error_t **error )
3873
3.31k
{
3874
3.31k
  libewf_internal_handle_t *internal_handle = NULL;
3875
3.31k
  static char *function                     = "libewf_handle_open_file_io_pool";
3876
3.31k
  int result                                = 0;
3877
3878
3.31k
  if( handle == NULL )
3879
0
  {
3880
0
    libcerror_error_set(
3881
0
     error,
3882
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3883
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3884
0
     "%s: invalid handle.",
3885
0
     function );
3886
3887
0
    return( -1 );
3888
0
  }
3889
3.31k
  internal_handle = (libewf_internal_handle_t *) handle;
3890
3891
3.31k
  if( internal_handle->file_io_pool != NULL )
3892
0
  {
3893
0
    libcerror_error_set(
3894
0
     error,
3895
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3896
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3897
0
     "%s: invalid handle - file IO pool value already set.",
3898
0
     function );
3899
3900
0
    return( -1 );
3901
0
  }
3902
3.31k
#if !defined( HAVE_WRITE_SUPPORT )
3903
3.31k
  if( ( access_flags & LIBEWF_ACCESS_FLAG_WRITE ) != 0 )
3904
0
  {
3905
0
    libcerror_error_set(
3906
0
     error,
3907
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3908
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3909
0
     "%s: write access currently not supported - compiled without zlib.",
3910
0
     function );
3911
3912
0
    return( -1 );
3913
0
  }
3914
3.31k
#endif
3915
3.31k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
3916
3.31k
  if( libcthreads_read_write_lock_grab_for_write(
3917
3.31k
       internal_handle->read_write_lock,
3918
3.31k
       error ) != 1 )
3919
0
  {
3920
0
    libcerror_error_set(
3921
0
     error,
3922
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3923
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3924
0
     "%s: unable to grab read/write lock for writing.",
3925
0
     function );
3926
3927
0
    return( -1 );
3928
0
  }
3929
3.31k
#endif
3930
3.31k
  result = libewf_internal_handle_open_file_io_pool(
3931
3.31k
            internal_handle,
3932
3.31k
            file_io_pool,
3933
3.31k
            access_flags,
3934
3.31k
            internal_handle->segment_table,
3935
3.31k
            error );
3936
3937
3.31k
  if( result != 1 )
3938
2.15k
  {
3939
2.15k
    libcerror_error_set(
3940
2.15k
     error,
3941
2.15k
     LIBCERROR_ERROR_DOMAIN_IO,
3942
2.15k
     LIBCERROR_IO_ERROR_OPEN_FAILED,
3943
2.15k
     "%s: unable to open handle using a file IO pool.",
3944
2.15k
     function );
3945
2.15k
  }
3946
1.16k
  else
3947
1.16k
  {
3948
1.16k
    internal_handle->file_io_pool = file_io_pool;
3949
1.16k
  }
3950
3.31k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
3951
3.31k
  if( libcthreads_read_write_lock_release_for_write(
3952
3.31k
       internal_handle->read_write_lock,
3953
3.31k
       error ) != 1 )
3954
0
  {
3955
0
    libcerror_error_set(
3956
0
     error,
3957
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3958
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3959
0
     "%s: unable to release read/write lock for writing.",
3960
0
     function );
3961
3962
0
    result = -1;
3963
0
  }
3964
3.31k
#endif
3965
3.31k
  if( result != 1 )
3966
2.15k
  {
3967
2.15k
    goto on_error;
3968
2.15k
  }
3969
1.16k
  return( 1 );
3970
3971
2.15k
on_error:
3972
2.15k
  internal_handle->file_io_pool = NULL;
3973
3974
2.15k
  return( -1 );
3975
3.31k
}
3976
3977
/* Closes the EWF handle
3978
 * Returns 0 if successful or -1 on error
3979
 */
3980
int libewf_handle_close(
3981
     libewf_handle_t *handle,
3982
     libcerror_error_t **error )
3983
1.16k
{
3984
1.16k
  libewf_internal_handle_t *internal_handle = NULL;
3985
1.16k
  static char *function                     = "libewf_handle_close";
3986
1.16k
  ssize_t write_count                       = 0;
3987
1.16k
  int result                                = 0;
3988
3989
1.16k
  if( handle == NULL )
3990
0
  {
3991
0
    libcerror_error_set(
3992
0
     error,
3993
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3994
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3995
0
     "%s: invalid handle.",
3996
0
     function );
3997
3998
0
    return( -1 );
3999
0
  }
4000
1.16k
  internal_handle = (libewf_internal_handle_t *) handle;
4001
4002
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
4003
1.16k
  if( libcthreads_read_write_lock_grab_for_write(
4004
1.16k
       internal_handle->read_write_lock,
4005
1.16k
       error ) != 1 )
4006
0
  {
4007
0
    libcerror_error_set(
4008
0
     error,
4009
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4010
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4011
0
     "%s: unable to grab read/write lock for writing.",
4012
0
     function );
4013
4014
0
    return( -1 );
4015
0
  }
4016
1.16k
#endif
4017
1.16k
  if( ( internal_handle->write_io_handle != NULL )
4018
0
   && ( internal_handle->write_io_handle->write_finalized == 0 ) )
4019
0
  {
4020
0
    write_count = libewf_internal_handle_write_finalize_file_io_pool(
4021
0
                   internal_handle,
4022
0
                   internal_handle->file_io_pool,
4023
0
                   error );
4024
4025
0
    if( write_count < 0 )
4026
0
    {
4027
0
      libcerror_error_set(
4028
0
       error,
4029
0
       LIBCERROR_ERROR_DOMAIN_IO,
4030
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
4031
0
       "%s: unable to finalize write.",
4032
0
       function );
4033
4034
0
      result = -1;
4035
0
    }
4036
0
  }
4037
1.16k
  if( internal_handle->file_io_pool_created_in_library != 0 )
4038
0
  {
4039
0
    if( libbfio_pool_close_all(
4040
0
         internal_handle->file_io_pool,
4041
0
         error ) != 0 )
4042
0
    {
4043
0
      libcerror_error_set(
4044
0
       error,
4045
0
       LIBCERROR_ERROR_DOMAIN_IO,
4046
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
4047
0
       "%s: unable to close all file IO pool handles.",
4048
0
       function );
4049
4050
0
      result = -1;
4051
0
    }
4052
0
    if( libbfio_pool_free(
4053
0
         &( internal_handle->file_io_pool ),
4054
0
         error ) != 1 )
4055
0
    {
4056
0
      libcerror_error_set(
4057
0
       error,
4058
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4059
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4060
0
       "%s: unable to free file IO pool.",
4061
0
       function );
4062
4063
0
      result = -1;
4064
0
    }
4065
0
    internal_handle->file_io_pool_created_in_library = 0;
4066
0
  }
4067
1.16k
  internal_handle->file_io_pool = NULL;
4068
4069
1.16k
  if( libewf_io_handle_clear(
4070
1.16k
       internal_handle->io_handle,
4071
1.16k
       error ) != 1 )
4072
0
  {
4073
0
    libcerror_error_set(
4074
0
     error,
4075
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4076
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4077
0
     "%s: unable to clear IO handle.",
4078
0
     function );
4079
4080
0
    result = -1;
4081
0
  }
4082
1.16k
  if( libewf_media_values_clear(
4083
1.16k
       internal_handle->media_values,
4084
1.16k
       error ) != 1 )
4085
0
  {
4086
0
    libcerror_error_set(
4087
0
     error,
4088
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4089
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4090
0
     "%s: unable to clear media values.",
4091
0
     function );
4092
4093
0
    result = -1;
4094
0
  }
4095
1.16k
  if( internal_handle->read_io_handle != NULL )
4096
1.16k
  {
4097
1.16k
    if( libewf_read_io_handle_free(
4098
1.16k
         &( internal_handle->read_io_handle ),
4099
1.16k
         error ) != 1 )
4100
0
    {
4101
0
      libcerror_error_set(
4102
0
       error,
4103
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4104
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4105
0
       "%s: unable to free read IO handle.",
4106
0
       function );
4107
4108
0
      result = -1;
4109
0
    }
4110
1.16k
  }
4111
1.16k
  if( internal_handle->write_io_handle != NULL )
4112
0
  {
4113
0
    if( libewf_write_io_handle_free(
4114
0
         &( internal_handle->write_io_handle ),
4115
0
         error ) != 1 )
4116
0
    {
4117
0
      libcerror_error_set(
4118
0
       error,
4119
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4120
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4121
0
       "%s: unable to free write IO handle.",
4122
0
       function );
4123
4124
0
      result = -1;
4125
0
    }
4126
0
  }
4127
  /* Free the chunk data if it could not be passed to libfcache_cache_set_value_by_index
4128
   */
4129
1.16k
  if( internal_handle->chunk_data != NULL )
4130
0
  {
4131
0
    if( libewf_chunk_data_free(
4132
0
         &( internal_handle->chunk_data ),
4133
0
         error ) != 1 )
4134
0
    {
4135
0
      libcerror_error_set(
4136
0
       error,
4137
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4138
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4139
0
       "%s: unable to free chunk data.",
4140
0
       function );
4141
4142
0
      result = -1;
4143
0
    }
4144
0
  }
4145
1.16k
  if( internal_handle->chunk_table != NULL )
4146
1.16k
  {
4147
1.16k
    if( libewf_chunk_table_free(
4148
1.16k
         &( internal_handle->chunk_table ),
4149
1.16k
         error ) != 1 )
4150
0
    {
4151
0
      libcerror_error_set(
4152
0
       error,
4153
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4154
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4155
0
       "%s: unable to free chunk table.",
4156
0
       function );
4157
4158
0
      result = -1;
4159
0
    }
4160
1.16k
  }
4161
1.16k
  if( internal_handle->hash_sections != NULL )
4162
1.16k
  {
4163
1.16k
    if( libewf_hash_sections_free(
4164
1.16k
         &( internal_handle->hash_sections ),
4165
1.16k
         error ) != 1 )
4166
0
    {
4167
0
      libcerror_error_set(
4168
0
       error,
4169
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4170
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4171
0
       "%s: unable to free hash sections.",
4172
0
       function );
4173
4174
0
      result = -1;
4175
0
    }
4176
1.16k
  }
4177
1.16k
  if( internal_handle->header_values != NULL )
4178
1.16k
  {
4179
1.16k
    if( libfvalue_table_free(
4180
1.16k
         &( internal_handle->header_values ),
4181
1.16k
         error ) != 1 )
4182
0
    {
4183
0
      libcerror_error_set(
4184
0
       error,
4185
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4186
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4187
0
       "%s: unable to free header values.",
4188
0
       function );
4189
4190
0
      result = -1;
4191
0
    }
4192
1.16k
  }
4193
1.16k
  if( internal_handle->hash_values != NULL )
4194
0
  {
4195
0
    if( libfvalue_table_free(
4196
0
         &( internal_handle->hash_values ),
4197
0
         error ) != 1 )
4198
0
    {
4199
0
      libcerror_error_set(
4200
0
       error,
4201
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4202
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4203
0
       "%s: unable to free hash values.",
4204
0
       function );
4205
4206
0
      result = -1;
4207
0
    }
4208
0
  }
4209
1.16k
  if( internal_handle->single_files != NULL )
4210
0
  {
4211
0
    if( libewf_single_files_free(
4212
0
         &( internal_handle->single_files ),
4213
0
         error ) != 1 )
4214
0
    {
4215
0
      libcerror_error_set(
4216
0
       error,
4217
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4218
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4219
0
       "%s: unable to free single files.",
4220
0
       function );
4221
4222
0
      result = -1;
4223
0
    }
4224
0
  }
4225
1.16k
  if( libcdata_array_empty(
4226
1.16k
       internal_handle->sessions,
4227
1.16k
       (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
4228
1.16k
       error ) != 1 )
4229
0
  {
4230
0
    libcerror_error_set(
4231
0
     error,
4232
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4233
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4234
0
     "%s: unable to empty sessions array.",
4235
0
     function );
4236
4237
0
    result = -1;
4238
0
  }
4239
1.16k
  if( libcdata_array_empty(
4240
1.16k
       internal_handle->tracks,
4241
1.16k
       (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
4242
1.16k
       error ) != 1 )
4243
0
  {
4244
0
    libcerror_error_set(
4245
0
     error,
4246
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4247
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4248
0
     "%s: unable to empty tracks array.",
4249
0
     function );
4250
4251
0
    result = -1;
4252
0
  }
4253
1.16k
  if( libcdata_range_list_empty(
4254
1.16k
       internal_handle->acquiry_errors,
4255
1.16k
       NULL,
4256
1.16k
       error ) != 1 )
4257
0
  {
4258
0
    libcerror_error_set(
4259
0
     error,
4260
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4261
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4262
0
     "%s: unable to empty acquiry errors range list.",
4263
0
     function );
4264
4265
0
    result = -1;
4266
0
  }
4267
1.16k
  if( libewf_segment_table_clear(
4268
1.16k
       internal_handle->segment_table,
4269
1.16k
       error ) != 1 )
4270
0
  {
4271
0
    libcerror_error_set(
4272
0
     error,
4273
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4274
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4275
0
     "%s: unable to clear segment table.",
4276
0
     function );
4277
4278
0
    result = -1;
4279
0
  }
4280
1.16k
  if( libewf_io_handle_clear(
4281
1.16k
       internal_handle->io_handle,
4282
1.16k
       error ) != 1 )
4283
0
  {
4284
0
    libcerror_error_set(
4285
0
     error,
4286
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4287
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4288
0
     "%s: unable to clear IO handle.",
4289
0
     function );
4290
4291
0
    result = -1;
4292
0
  }
4293
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
4294
1.16k
  if( libcthreads_read_write_lock_release_for_write(
4295
1.16k
       internal_handle->read_write_lock,
4296
1.16k
       error ) != 1 )
4297
0
  {
4298
0
    libcerror_error_set(
4299
0
     error,
4300
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4301
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4302
0
     "%s: unable to release read/write lock for writing.",
4303
0
     function );
4304
4305
0
    result = -1;
4306
0
  }
4307
1.16k
#endif
4308
1.16k
  return( result );
4309
1.16k
}
4310
4311
/* Reads (media) data from the last current into a buffer using a Basic File IO (bfio) pool
4312
 * This function is not multi-thread safe acquire write lock before call
4313
 * Returns the number of bytes read, 0 when no longer data can be read or -1 on error
4314
 */
4315
ssize_t libewf_internal_handle_read_buffer_from_file_io_pool(
4316
         libewf_internal_handle_t *internal_handle,
4317
         libbfio_pool_t *file_io_pool,
4318
         void *buffer,
4319
         size_t buffer_size,
4320
         libcerror_error_t **error )
4321
0
{
4322
0
  libewf_chunk_data_t *chunk_data = NULL;
4323
0
  static char *function           = "libewf_internal_handle_read_buffer_from_file_io_pool";
4324
0
  off64_t chunk_data_offset       = 0;
4325
0
  size_t buffer_offset            = 0;
4326
0
  size_t read_size                = 0;
4327
4328
0
  if( internal_handle == NULL )
4329
0
  {
4330
0
    libcerror_error_set(
4331
0
     error,
4332
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4333
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4334
0
     "%s: invalid handle.",
4335
0
     function );
4336
4337
0
    return( -1 );
4338
0
  }
4339
0
  if( internal_handle->io_handle == NULL )
4340
0
  {
4341
0
    libcerror_error_set(
4342
0
     error,
4343
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4344
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4345
0
     "%s: invalid handle - missing IO handle.",
4346
0
     function );
4347
4348
0
    return( -1 );
4349
0
  }
4350
0
  if( internal_handle->chunk_data != NULL )
4351
0
  {
4352
0
    libcerror_error_set(
4353
0
     error,
4354
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4355
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
4356
0
     "%s: invalid handle - chunk data set.",
4357
0
     function );
4358
4359
0
    return( -1 );
4360
0
  }
4361
0
  if( internal_handle->current_offset < 0 )
4362
0
  {
4363
0
    libcerror_error_set(
4364
0
     error,
4365
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4366
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4367
0
     "%s: invalid handle - invalid IO handle - current offset value out of bounds.",
4368
0
     function );
4369
4370
0
    return( -1 );
4371
0
  }
4372
0
  if( internal_handle->media_values == NULL )
4373
0
  {
4374
0
    libcerror_error_set(
4375
0
     error,
4376
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4377
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4378
0
     "%s: invalid handle - missing media values.",
4379
0
     function );
4380
4381
0
    return( -1 );
4382
0
  }
4383
0
  if( internal_handle->media_values->chunk_size == 0 )
4384
0
  {
4385
0
    libcerror_error_set(
4386
0
     error,
4387
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4388
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4389
0
     "%s: invalid handle - invalid media values - missing chunk size.",
4390
0
     function );
4391
4392
0
    return( -1 );
4393
0
  }
4394
0
  if( buffer == NULL )
4395
0
  {
4396
0
    libcerror_error_set(
4397
0
     error,
4398
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4399
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4400
0
     "%s: invalid buffer.",
4401
0
     function );
4402
4403
0
    return( -1 );
4404
0
  }
4405
0
  if( buffer_size > (size_t) SSIZE_MAX )
4406
0
  {
4407
0
    libcerror_error_set(
4408
0
     error,
4409
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4410
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4411
0
     "%s: invalid buffer size value exceeds maximum.",
4412
0
     function );
4413
4414
0
    return( -1 );
4415
0
  }
4416
0
  if( (size64_t) internal_handle->current_offset >= internal_handle->media_values->media_size )
4417
0
  {
4418
0
    return( 0 );
4419
0
  }
4420
0
  internal_handle->io_handle->abort = 0;
4421
4422
0
  if( (size64_t) ( internal_handle->current_offset + buffer_size ) >= internal_handle->media_values->media_size )
4423
0
  {
4424
0
    buffer_size = (size_t) ( internal_handle->media_values->media_size - internal_handle->current_offset );
4425
0
  }
4426
0
  while( buffer_size > 0 )
4427
0
  {
4428
0
    if( libewf_chunk_table_get_chunk_data_by_offset(
4429
0
         internal_handle->chunk_table,
4430
0
         internal_handle->io_handle,
4431
0
         file_io_pool,
4432
0
         internal_handle->media_values,
4433
0
         internal_handle->segment_table,
4434
0
         internal_handle->current_offset,
4435
0
         &chunk_data_offset,
4436
0
         &chunk_data,
4437
0
         error ) != 1 )
4438
0
    {
4439
0
      libcerror_error_set(
4440
0
       error,
4441
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4442
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4443
0
       "%s: unable to retrieve chunk data for offset: %" PRIi64 " (0x%08" PRIx64 ").",
4444
0
       function,
4445
0
       internal_handle->current_offset,
4446
0
       internal_handle->current_offset );
4447
4448
0
      return( -1 );
4449
0
    }
4450
0
    if( chunk_data == NULL )
4451
0
    {
4452
0
      libcerror_error_set(
4453
0
       error,
4454
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4455
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4456
0
       "%s: missing chunk data for offset: %" PRIi64 " (0x%08" PRIx64 ").",
4457
0
       function,
4458
0
       internal_handle->current_offset,
4459
0
       internal_handle->current_offset );
4460
4461
0
      return( -1 );
4462
0
    }
4463
0
    if( (off64_t) chunk_data_offset > (off64_t) chunk_data->data_size )
4464
0
    {
4465
0
      libcerror_error_set(
4466
0
       error,
4467
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4468
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4469
0
       "%s: chunk: %" PRIu64 " offset exceeds data size.",
4470
0
       function,
4471
0
       chunk_data->chunk_index );
4472
4473
0
      return( -1 );
4474
0
    }
4475
0
    read_size = (size_t) ( chunk_data->data_size - chunk_data_offset );
4476
4477
0
    if( read_size > buffer_size )
4478
0
    {
4479
0
      read_size = buffer_size;
4480
0
    }
4481
0
    if( read_size == 0 )
4482
0
    {
4483
0
      break;
4484
0
    }
4485
0
    if( memory_copy(
4486
0
         &( ( (uint8_t *) buffer )[ buffer_offset ] ),
4487
0
         &( ( chunk_data->data )[ chunk_data_offset ] ),
4488
0
         read_size ) == NULL )
4489
0
    {
4490
0
      libcerror_error_set(
4491
0
       error,
4492
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
4493
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
4494
0
       "%s: unable to copy chunk: %" PRIu64 " data to buffer.",
4495
0
       function,
4496
0
       chunk_data->chunk_index );
4497
4498
0
      return( -1 );
4499
0
    }
4500
0
    buffer_offset += read_size;
4501
0
    buffer_size   -= read_size;
4502
4503
0
    internal_handle->current_offset += (off64_t) read_size;
4504
4505
0
    if( (size64_t) internal_handle->current_offset >= internal_handle->media_values->media_size )
4506
0
    {
4507
0
      break;
4508
0
    }
4509
0
    if( internal_handle->io_handle->abort != 0 )
4510
0
    {
4511
0
      break;
4512
0
    }
4513
0
    chunk_data        = NULL;
4514
0
    chunk_data_offset = 0;
4515
0
  }
4516
0
  internal_handle->io_handle->abort = 0;
4517
4518
0
  return( (ssize_t) buffer_offset );
4519
0
}
4520
4521
/* Reads (media) data at the current offset into a buffer
4522
 * Returns the number of bytes read, 0 when no longer data can be read or -1 on error
4523
 */
4524
ssize_t libewf_handle_read_buffer(
4525
         libewf_handle_t *handle,
4526
         void *buffer,
4527
         size_t buffer_size,
4528
         libcerror_error_t **error )
4529
0
{
4530
0
  libewf_internal_handle_t *internal_handle = NULL;
4531
0
  static char *function                     = "libewf_handle_read_buffer";
4532
0
  ssize_t read_count                        = 0;
4533
4534
0
  if( handle == NULL )
4535
0
  {
4536
0
    libcerror_error_set(
4537
0
     error,
4538
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4539
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4540
0
     "%s: invalid handle.",
4541
0
     function );
4542
4543
0
    return( -1 );
4544
0
  }
4545
0
  internal_handle = (libewf_internal_handle_t *) handle;
4546
4547
0
  if( internal_handle->file_io_pool == NULL )
4548
0
  {
4549
0
    libcerror_error_set(
4550
0
     error,
4551
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4552
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4553
0
     "%s: invalid handle - missing file IO pool.",
4554
0
     function );
4555
4556
0
    return( -1 );
4557
0
  }
4558
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
4559
0
  if( libcthreads_read_write_lock_grab_for_write(
4560
0
       internal_handle->read_write_lock,
4561
0
       error ) != 1 )
4562
0
  {
4563
0
    libcerror_error_set(
4564
0
     error,
4565
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4566
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4567
0
     "%s: unable to grab read/write lock for writing.",
4568
0
     function );
4569
4570
0
    return( -1 );
4571
0
  }
4572
0
#endif
4573
0
  read_count = libewf_internal_handle_read_buffer_from_file_io_pool(
4574
0
          internal_handle,
4575
0
          internal_handle->file_io_pool,
4576
0
          buffer,
4577
0
          buffer_size,
4578
0
          error );
4579
4580
0
  if( read_count == -1 )
4581
0
  {
4582
0
    libcerror_error_set(
4583
0
     error,
4584
0
     LIBCERROR_ERROR_DOMAIN_IO,
4585
0
     LIBCERROR_IO_ERROR_READ_FAILED,
4586
0
     "%s: unable to read buffer.",
4587
0
     function );
4588
4589
0
    read_count = -1;
4590
0
  }
4591
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
4592
0
  if( libcthreads_read_write_lock_release_for_write(
4593
0
       internal_handle->read_write_lock,
4594
0
       error ) != 1 )
4595
0
  {
4596
0
    libcerror_error_set(
4597
0
     error,
4598
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4599
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4600
0
     "%s: unable to release read/write lock for writing.",
4601
0
     function );
4602
4603
0
    return( -1 );
4604
0
  }
4605
0
#endif
4606
0
  return( read_count );
4607
0
}
4608
4609
/* Reads (media) data at a specific offset
4610
 * Returns the number of bytes read, 0 when no longer data can be read or -1 on error
4611
 */
4612
ssize_t libewf_handle_read_buffer_at_offset(
4613
         libewf_handle_t *handle,
4614
         void *buffer,
4615
         size_t buffer_size,
4616
         off64_t offset,
4617
         libcerror_error_t **error )
4618
0
{
4619
0
  libewf_internal_handle_t *internal_handle = NULL;
4620
0
  static char *function                     = "libewf_handle_read_buffer_at_offset";
4621
0
  ssize_t read_count                        = 0;
4622
4623
0
  if( handle == NULL )
4624
0
  {
4625
0
    libcerror_error_set(
4626
0
     error,
4627
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4628
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4629
0
     "%s: invalid handle.",
4630
0
     function );
4631
4632
0
    return( -1 );
4633
0
  }
4634
0
  internal_handle = (libewf_internal_handle_t *) handle;
4635
4636
0
  if( internal_handle->file_io_pool == NULL )
4637
0
  {
4638
0
    libcerror_error_set(
4639
0
     error,
4640
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4641
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4642
0
     "%s: invalid handle - missing file IO pool.",
4643
0
     function );
4644
4645
0
    return( -1 );
4646
0
  }
4647
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
4648
0
  if( libcthreads_read_write_lock_grab_for_write(
4649
0
       internal_handle->read_write_lock,
4650
0
       error ) != 1 )
4651
0
  {
4652
0
    libcerror_error_set(
4653
0
     error,
4654
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4655
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4656
0
     "%s: unable to grab read/write lock for writing.",
4657
0
     function );
4658
4659
0
    return( -1 );
4660
0
  }
4661
0
#endif
4662
0
  if( libewf_internal_handle_seek_offset(
4663
0
       internal_handle,
4664
0
       offset,
4665
0
       SEEK_SET,
4666
0
       error ) == -1 )
4667
0
  {
4668
0
    libcerror_error_set(
4669
0
     error,
4670
0
     LIBCERROR_ERROR_DOMAIN_IO,
4671
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
4672
0
     "%s: unable to seek offset.",
4673
0
     function );
4674
4675
0
    read_count = -1;
4676
0
  }
4677
0
  if( read_count != -1 )
4678
0
  {
4679
0
    read_count = libewf_internal_handle_read_buffer_from_file_io_pool(
4680
0
                  internal_handle,
4681
0
                  internal_handle->file_io_pool,
4682
0
                  buffer,
4683
0
                  buffer_size,
4684
0
                  error );
4685
4686
0
    if( read_count == -1 )
4687
0
    {
4688
0
      libcerror_error_set(
4689
0
       error,
4690
0
       LIBCERROR_ERROR_DOMAIN_IO,
4691
0
       LIBCERROR_IO_ERROR_READ_FAILED,
4692
0
       "%s: unable to read buffer.",
4693
0
       function );
4694
4695
0
      read_count = -1;
4696
0
    }
4697
0
  }
4698
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
4699
0
  if( libcthreads_read_write_lock_release_for_write(
4700
0
       internal_handle->read_write_lock,
4701
0
       error ) != 1 )
4702
0
  {
4703
0
    libcerror_error_set(
4704
0
     error,
4705
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4706
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4707
0
     "%s: unable to release read/write lock for writing.",
4708
0
     function );
4709
4710
0
    return( -1 );
4711
0
  }
4712
0
#endif
4713
0
  return( read_count );
4714
0
}
4715
4716
/* Writes (media) data at the current offset from a buffer using a Basic File IO (bfio) pool
4717
 * the necessary settings of the write values must have been made
4718
 * Will initialize write if necessary
4719
 * This function is not multi-thread safe acquire write lock before call
4720
 * Returns the number of bytes written, 0 when no longer data can be written or -1 on error
4721
 */
4722
ssize_t libewf_internal_handle_write_buffer_to_file_io_pool(
4723
         libewf_internal_handle_t *internal_handle,
4724
         libbfio_pool_t *file_io_pool,
4725
         const void *buffer,
4726
         size_t buffer_size,
4727
         libcerror_error_t **error )
4728
0
{
4729
0
  static char *function     = "libewf_internal_handle_write_buffer_to_file_io_pool";
4730
0
  size_t buffer_offset      = 0;
4731
0
  size_t input_data_size    = 0;
4732
0
  size_t write_size         = 0;
4733
0
  ssize_t write_count       = 0;
4734
0
  off64_t chunk_data_offset = 0;
4735
0
  uint64_t chunk_index      = 0;
4736
0
  int write_chunk           = 0;
4737
4738
0
  if( internal_handle == NULL )
4739
0
  {
4740
0
    libcerror_error_set(
4741
0
     error,
4742
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4743
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4744
0
     "%s: invalid handle.",
4745
0
     function );
4746
4747
0
    return( -1 );
4748
0
  }
4749
0
  if( internal_handle->io_handle == NULL )
4750
0
  {
4751
0
    libcerror_error_set(
4752
0
     error,
4753
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4754
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4755
0
     "%s: invalid handle - missing IO handle.",
4756
0
     function );
4757
4758
0
    return( -1 );
4759
0
  }
4760
0
  if( internal_handle->current_offset < 0 )
4761
0
  {
4762
0
    libcerror_error_set(
4763
0
     error,
4764
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4765
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4766
0
     "%s: invalid handle - invalid IO handle - current offset value out of bounds.",
4767
0
     function );
4768
4769
0
    return( -1 );
4770
0
  }
4771
0
  if( ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
4772
0
   && ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_RESUME ) == 0 ) )
4773
0
  {
4774
0
    if( internal_handle->chunk_data != NULL )
4775
0
    {
4776
0
      libcerror_error_set(
4777
0
       error,
4778
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4779
0
       LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
4780
0
       "%s: invalid handle - chunk data set.",
4781
0
       function );
4782
4783
0
      return( -1 );
4784
0
    }
4785
0
  }
4786
0
  if( internal_handle->media_values == NULL )
4787
0
  {
4788
0
    libcerror_error_set(
4789
0
     error,
4790
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4791
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4792
0
     "%s: invalid handle - missing media values.",
4793
0
     function );
4794
4795
0
    return( -1 );
4796
0
  }
4797
0
  if( internal_handle->media_values->chunk_size == 0 )
4798
0
  {
4799
0
    libcerror_error_set(
4800
0
     error,
4801
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4802
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4803
0
     "%s: invalid handle - invalid media values - missing chunk size.",
4804
0
     function );
4805
4806
0
    return( -1 );
4807
0
  }
4808
0
  if( internal_handle->write_io_handle == NULL )
4809
0
  {
4810
0
    libcerror_error_set(
4811
0
     error,
4812
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4813
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4814
0
     "%s: invalid handle - missing write IO handle.",
4815
0
     function );
4816
4817
0
    return( -1 );
4818
0
  }
4819
0
  if( buffer == NULL )
4820
0
  {
4821
0
    libcerror_error_set(
4822
0
     error,
4823
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4824
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4825
0
     "%s: invalid buffer.",
4826
0
     function );
4827
4828
0
    return( -1 );
4829
0
  }
4830
0
  if( buffer_size > (size_t) SSIZE_MAX )
4831
0
  {
4832
0
    libcerror_error_set(
4833
0
     error,
4834
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4835
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4836
0
     "%s: invalid buffer size value exceeds maximum.",
4837
0
     function );
4838
4839
0
    return( -1 );
4840
0
  }
4841
0
  if( internal_handle->current_offset < 0 )
4842
0
  {
4843
0
    libcerror_error_set(
4844
0
     error,
4845
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4846
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4847
0
     "%s: invalid offset value out of bounds.",
4848
0
     function );
4849
4850
0
    return( -1 );
4851
0
  }
4852
0
  if( ( internal_handle->media_values->media_size != 0 )
4853
0
   && ( (size64_t) internal_handle->current_offset >= internal_handle->media_values->media_size ) )
4854
0
  {
4855
0
    return( 0 );
4856
0
  }
4857
0
  internal_handle->io_handle->abort = 0;
4858
4859
0
  if( ( internal_handle->media_values->media_size != 0 )
4860
0
   && ( (size64_t) ( internal_handle->current_offset + buffer_size ) >= internal_handle->media_values->media_size ) )
4861
0
  {
4862
0
    buffer_size = (size_t) ( internal_handle->media_values->media_size - internal_handle->current_offset );
4863
0
  }
4864
0
  chunk_index = internal_handle->current_offset / internal_handle->media_values->chunk_size;
4865
4866
0
  if( chunk_index >= (uint64_t) INT_MAX )
4867
0
  {
4868
0
    libcerror_error_set(
4869
0
     error,
4870
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4871
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
4872
0
     "%s: invalid chunk index value exceeds maximum.",
4873
0
     function );
4874
4875
0
    return( -1 );
4876
0
  }
4877
0
  chunk_data_offset = chunk_index * internal_handle->media_values->chunk_size;
4878
0
  chunk_data_offset = internal_handle->current_offset - chunk_data_offset;
4879
4880
0
  if( chunk_data_offset >= (off64_t) SSIZE_MAX )
4881
0
  {
4882
0
    libcerror_error_set(
4883
0
     error,
4884
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4885
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
4886
0
     "%s: invalid chunk data offset value exceeds maximum.",
4887
0
     function );
4888
4889
0
    return( -1 );
4890
0
  }
4891
0
  while( buffer_size > 0 )
4892
0
  {
4893
0
    if( chunk_index < internal_handle->write_io_handle->number_of_chunks_written )
4894
0
    {
4895
0
      libcerror_error_set(
4896
0
       error,
4897
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4898
0
       LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
4899
0
       "%s: chunk: %" PRIu64 " already exists.",
4900
0
       function,
4901
0
       chunk_index );
4902
4903
0
      return( -1 );
4904
0
    }
4905
0
    if( internal_handle->write_io_handle->write_finalized != 0 )
4906
0
    {
4907
0
      break;
4908
0
    }
4909
0
    if( internal_handle->chunk_data == NULL )
4910
0
    {
4911
0
      if( libewf_chunk_data_initialize(
4912
0
           &( internal_handle->chunk_data ),
4913
0
           internal_handle->media_values->chunk_size,
4914
0
           0,
4915
0
           error ) != 1 )
4916
0
      {
4917
0
        libcerror_error_set(
4918
0
         error,
4919
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4920
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4921
0
         "%s: unable to create chunk: %" PRIu64 " data.",
4922
0
         function,
4923
0
         chunk_index );
4924
4925
0
        return( -1 );
4926
0
      }
4927
0
    }
4928
0
    if( internal_handle->chunk_data == NULL )
4929
0
    {
4930
0
      libcerror_error_set(
4931
0
       error,
4932
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4933
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4934
0
       "%s: internal handle - missing chunk: %" PRIu64 " data.",
4935
0
       function,
4936
0
       chunk_index );
4937
4938
0
      return( -1 );
4939
0
    }
4940
0
    if( chunk_data_offset > internal_handle->media_values->chunk_size )
4941
0
    {
4942
0
      libcerror_error_set(
4943
0
       error,
4944
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4945
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4946
0
       "%s: chunk offset exceeds chunk data size.",
4947
0
       function );
4948
4949
0
      return( -1 );
4950
0
    }
4951
0
    write_size = (size_t) ( internal_handle->media_values->chunk_size - chunk_data_offset );
4952
4953
0
    if( write_size > buffer_size )
4954
0
    {
4955
0
      write_size = buffer_size;
4956
0
    }
4957
0
    if( write_size == 0 )
4958
0
    {
4959
0
      break;
4960
0
    }
4961
0
    if( memory_copy(
4962
0
         &( ( internal_handle->chunk_data->data )[ chunk_data_offset ] ),
4963
0
         &( ( (uint8_t *) buffer )[ buffer_offset ] ),
4964
0
         write_size ) == NULL )
4965
0
    {
4966
0
      libcerror_error_set(
4967
0
       error,
4968
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
4969
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
4970
0
       "%s: unable to copy buffer to chunk data.",
4971
0
       function );
4972
4973
0
      return( -1 );
4974
0
    }
4975
0
    internal_handle->chunk_data->data_size = (size_t) ( chunk_data_offset + write_size );
4976
4977
0
    buffer_offset += write_size;
4978
0
    buffer_size   -= write_size;
4979
4980
0
    if( internal_handle->chunk_data->data_size == internal_handle->media_values->chunk_size )
4981
0
    {
4982
0
      write_chunk = 1;
4983
0
    }
4984
0
    else if( ( internal_handle->media_values->media_size != 0 )
4985
0
          && ( ( (size64_t) internal_handle->current_offset + write_size ) == internal_handle->media_values->media_size ) )
4986
0
    {
4987
0
      write_chunk = 1;
4988
0
    }
4989
0
    else
4990
0
    {
4991
0
      write_chunk = 0;
4992
0
    }
4993
0
    if( write_chunk != 0 )
4994
0
    {
4995
0
      input_data_size = internal_handle->chunk_data->data_size;
4996
4997
0
      if( libewf_chunk_data_pack(
4998
0
           internal_handle->chunk_data,
4999
0
           internal_handle->io_handle,
5000
0
           internal_handle->write_io_handle->compressed_zero_byte_empty_block,
5001
0
           internal_handle->write_io_handle->compressed_zero_byte_empty_block_size,
5002
0
           internal_handle->write_io_handle->pack_flags,
5003
0
           error ) != 1 )
5004
0
      {
5005
0
        libcerror_error_set(
5006
0
         error,
5007
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
5008
0
         LIBCERROR_RUNTIME_ERROR_GENERIC,
5009
0
         "%s: unable to pack chunk: %" PRIu64 " data.",
5010
0
         function,
5011
0
         chunk_index );
5012
5013
0
        return( -1 );
5014
0
      }
5015
0
      write_count = libewf_write_io_handle_write_new_chunk(
5016
0
                     internal_handle->write_io_handle,
5017
0
                     internal_handle->io_handle,
5018
0
                     file_io_pool,
5019
0
                     internal_handle->media_values,
5020
0
                     internal_handle->segment_table,
5021
0
                     internal_handle->header_values,
5022
0
                     internal_handle->hash_values,
5023
0
                     internal_handle->hash_sections,
5024
0
                     internal_handle->sessions,
5025
0
                     internal_handle->tracks,
5026
0
                     internal_handle->acquiry_errors,
5027
0
                     chunk_index,
5028
0
                     internal_handle->chunk_data,
5029
0
                     input_data_size,
5030
0
                     error );
5031
5032
0
      if( write_count <= 0 )
5033
0
      {
5034
0
        libcerror_error_set(
5035
0
         error,
5036
0
         LIBCERROR_ERROR_DOMAIN_IO,
5037
0
         LIBCERROR_IO_ERROR_WRITE_FAILED,
5038
0
         "%s: unable to write new chunk.",
5039
0
         function );
5040
5041
0
        return( -1 );
5042
0
      }
5043
0
      if( libewf_chunk_data_free(
5044
0
           &( internal_handle->chunk_data ),
5045
0
           error ) != 1 )
5046
0
      {
5047
0
        libcerror_error_set(
5048
0
         error,
5049
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
5050
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
5051
0
         "%s: unable to free chunk data.",
5052
0
         function );
5053
5054
0
        return( -1 );
5055
0
      }
5056
0
    }
5057
0
    chunk_index      += 1;
5058
0
    chunk_data_offset = 0;
5059
5060
0
    internal_handle->current_offset += (off64_t) write_size;
5061
5062
0
    if( ( internal_handle->media_values->media_size != 0 )
5063
0
     && ( (size64_t) internal_handle->current_offset >= internal_handle->media_values->media_size ) )
5064
0
    {
5065
0
      break;
5066
0
    }
5067
0
    if( internal_handle->io_handle->abort != 0 )
5068
0
    {
5069
0
      break;
5070
0
    }
5071
0
  }
5072
0
  internal_handle->io_handle->abort = 0;
5073
5074
0
  return( (ssize_t) buffer_offset );
5075
0
}
5076
5077
/* Writes (media) data at the current offset
5078
 * the necessary settings of the write values must have been made
5079
 * Will initialize write if necessary
5080
 * Returns the number of bytes written, 0 when no longer data can be written or -1 on error
5081
 */
5082
ssize_t libewf_handle_write_buffer(
5083
         libewf_handle_t *handle,
5084
         const void *buffer,
5085
         size_t buffer_size,
5086
         libcerror_error_t **error )
5087
0
{
5088
0
  libewf_internal_handle_t *internal_handle = NULL;
5089
0
  static char *function                     = "libewf_handle_write_buffer";
5090
0
  ssize_t write_count                       = 0;
5091
5092
0
  if( handle == NULL )
5093
0
  {
5094
0
    libcerror_error_set(
5095
0
     error,
5096
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5097
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5098
0
     "%s: invalid handle.",
5099
0
     function );
5100
5101
0
    return( -1 );
5102
0
  }
5103
0
  internal_handle = (libewf_internal_handle_t *) handle;
5104
5105
0
  if( internal_handle->file_io_pool == NULL )
5106
0
  {
5107
0
    libcerror_error_set(
5108
0
     error,
5109
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5110
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5111
0
     "%s: invalid handle - missing file IO pool.",
5112
0
     function );
5113
5114
0
    return( -1 );
5115
0
  }
5116
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
5117
0
  if( libcthreads_read_write_lock_grab_for_write(
5118
0
       internal_handle->read_write_lock,
5119
0
       error ) != 1 )
5120
0
  {
5121
0
    libcerror_error_set(
5122
0
     error,
5123
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5124
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5125
0
     "%s: unable to grab read/write lock for writing.",
5126
0
     function );
5127
5128
0
    return( -1 );
5129
0
  }
5130
0
#endif
5131
0
  if( internal_handle->write_io_handle->values_initialized == 0 )
5132
0
  {
5133
0
    if( libewf_write_io_handle_initialize_values(
5134
0
         internal_handle->write_io_handle,
5135
0
         internal_handle->io_handle,
5136
0
         internal_handle->media_values,
5137
0
         internal_handle->segment_table,
5138
0
         error ) != 1 )
5139
0
    {
5140
0
      libcerror_error_set(
5141
0
       error,
5142
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5143
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5144
0
       "%s: unable to initialize write IO handle values.",
5145
0
       function );
5146
5147
0
      write_count = -1;
5148
0
    }
5149
0
  }
5150
0
  if( write_count != -1 )
5151
0
  {
5152
0
    write_count = libewf_internal_handle_write_buffer_to_file_io_pool(
5153
0
                   internal_handle,
5154
0
                   internal_handle->file_io_pool,
5155
0
                   buffer,
5156
0
                   buffer_size,
5157
0
                   error );
5158
5159
0
    if( write_count == -1 )
5160
0
    {
5161
0
      libcerror_error_set(
5162
0
       error,
5163
0
       LIBCERROR_ERROR_DOMAIN_IO,
5164
0
       LIBCERROR_IO_ERROR_READ_FAILED,
5165
0
       "%s: unable to write buffer.",
5166
0
       function );
5167
5168
0
      write_count = -1;
5169
0
    }
5170
0
  }
5171
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
5172
0
  if( libcthreads_read_write_lock_release_for_write(
5173
0
       internal_handle->read_write_lock,
5174
0
       error ) != 1 )
5175
0
  {
5176
0
    libcerror_error_set(
5177
0
     error,
5178
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5179
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5180
0
     "%s: unable to release read/write lock for writing.",
5181
0
     function );
5182
5183
0
    return( -1 );
5184
0
  }
5185
0
#endif
5186
0
  return( write_count );
5187
0
}
5188
5189
/* Writes (media) data at a specific offset,
5190
 * the necessary settings of the write values must have been made
5191
 * Will initialize write if necessary
5192
 * Returns the number of bytes written, 0 when no longer data can be written or -1 on error
5193
 */
5194
ssize_t libewf_handle_write_buffer_at_offset(
5195
         libewf_handle_t *handle,
5196
         const void *buffer,
5197
         size_t buffer_size,
5198
         off64_t offset,
5199
         libcerror_error_t **error )
5200
0
{
5201
0
  libewf_internal_handle_t *internal_handle = NULL;
5202
0
  static char *function                     = "libewf_handle_write_buffer_at_offset";
5203
0
  ssize_t write_count                       = 0;
5204
5205
0
  if( handle == NULL )
5206
0
  {
5207
0
    libcerror_error_set(
5208
0
     error,
5209
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5210
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5211
0
     "%s: invalid handle.",
5212
0
     function );
5213
5214
0
    return( -1 );
5215
0
  }
5216
0
  internal_handle = (libewf_internal_handle_t *) handle;
5217
5218
0
  if( internal_handle->file_io_pool == NULL )
5219
0
  {
5220
0
    libcerror_error_set(
5221
0
     error,
5222
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5223
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5224
0
     "%s: invalid handle - missing file IO pool.",
5225
0
     function );
5226
5227
0
    return( -1 );
5228
0
  }
5229
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
5230
0
  if( libcthreads_read_write_lock_grab_for_write(
5231
0
       internal_handle->read_write_lock,
5232
0
       error ) != 1 )
5233
0
  {
5234
0
    libcerror_error_set(
5235
0
     error,
5236
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5237
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5238
0
     "%s: unable to grab read/write lock for writing.",
5239
0
     function );
5240
5241
0
    return( -1 );
5242
0
  }
5243
0
#endif
5244
0
  if( internal_handle->write_io_handle->values_initialized == 0 )
5245
0
  {
5246
0
    if( libewf_write_io_handle_initialize_values(
5247
0
         internal_handle->write_io_handle,
5248
0
         internal_handle->io_handle,
5249
0
         internal_handle->media_values,
5250
0
         internal_handle->segment_table,
5251
0
         error ) != 1 )
5252
0
    {
5253
0
      libcerror_error_set(
5254
0
       error,
5255
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5256
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5257
0
       "%s: unable to initialize write IO handle values.",
5258
0
       function );
5259
5260
0
      write_count = -1;
5261
0
    }
5262
0
  }
5263
0
  if( write_count != -1 )
5264
0
  {
5265
0
    if( libewf_internal_handle_seek_offset(
5266
0
         internal_handle,
5267
0
         offset,
5268
0
         SEEK_SET,
5269
0
         error ) == -1 )
5270
0
    {
5271
0
      libcerror_error_set(
5272
0
       error,
5273
0
       LIBCERROR_ERROR_DOMAIN_IO,
5274
0
       LIBCERROR_IO_ERROR_SEEK_FAILED,
5275
0
       "%s: unable to seek offset.",
5276
0
       function );
5277
5278
0
      write_count = -1;
5279
0
    }
5280
0
  }
5281
0
  if( write_count != -1 )
5282
0
  {
5283
0
    write_count = libewf_internal_handle_write_buffer_to_file_io_pool(
5284
0
                   internal_handle,
5285
0
                   internal_handle->file_io_pool,
5286
0
                   buffer,
5287
0
                   buffer_size,
5288
0
                   error );
5289
5290
0
    if( write_count == -1 )
5291
0
    {
5292
0
      libcerror_error_set(
5293
0
       error,
5294
0
       LIBCERROR_ERROR_DOMAIN_IO,
5295
0
       LIBCERROR_IO_ERROR_READ_FAILED,
5296
0
       "%s: unable to write buffer.",
5297
0
       function );
5298
5299
0
      write_count = -1;
5300
0
    }
5301
0
  }
5302
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
5303
0
  if( libcthreads_read_write_lock_release_for_write(
5304
0
       internal_handle->read_write_lock,
5305
0
       error ) != 1 )
5306
0
  {
5307
0
    libcerror_error_set(
5308
0
     error,
5309
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5310
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5311
0
     "%s: unable to release read/write lock for writing.",
5312
0
     function );
5313
5314
0
    return( -1 );
5315
0
  }
5316
0
#endif
5317
0
  return( write_count );
5318
0
}
5319
5320
/* Retrieves a (media) data chunk
5321
 * Returns 1 if successful or -1 on error
5322
 */
5323
int libewf_handle_get_data_chunk(
5324
     libewf_handle_t *handle,
5325
     libewf_data_chunk_t **data_chunk,
5326
     libcerror_error_t **error )
5327
0
{
5328
0
  libewf_internal_handle_t *internal_handle = NULL;
5329
0
  static char *function                     = "libewf_handle_get_data_chunk";
5330
0
  int result                                = 1;
5331
5332
0
  if( handle == NULL )
5333
0
  {
5334
0
    libcerror_error_set(
5335
0
     error,
5336
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5337
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5338
0
     "%s: invalid handle.",
5339
0
     function );
5340
5341
0
    return( -1 );
5342
0
  }
5343
0
  internal_handle = (libewf_internal_handle_t *) handle;
5344
5345
0
  if( internal_handle->media_values == NULL )
5346
0
  {
5347
0
    libcerror_error_set(
5348
0
     error,
5349
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5350
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5351
0
     "%s: invalid handle - missing media values.",
5352
0
     function );
5353
5354
0
    return( -1 );
5355
0
  }
5356
0
  if( data_chunk == NULL )
5357
0
  {
5358
0
    libcerror_error_set(
5359
0
     error,
5360
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5361
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5362
0
     "%s: invalid data chunk.",
5363
0
     function );
5364
5365
0
    return( -1 );
5366
0
  }
5367
0
  if( *data_chunk != NULL )
5368
0
  {
5369
0
    libcerror_error_set(
5370
0
     error,
5371
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5372
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
5373
0
     "%s: data chunk value already set.",
5374
0
     function );
5375
5376
0
    return( -1 );
5377
0
  }
5378
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
5379
0
  if( libcthreads_read_write_lock_grab_for_write(
5380
0
       internal_handle->read_write_lock,
5381
0
       error ) != 1 )
5382
0
  {
5383
0
    libcerror_error_set(
5384
0
     error,
5385
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5386
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5387
0
     "%s: unable to grab read/write lock for writing.",
5388
0
     function );
5389
5390
0
    return( -1 );
5391
0
  }
5392
0
#endif
5393
0
  if( ( internal_handle->write_io_handle != NULL )
5394
0
   && ( internal_handle->write_io_handle->values_initialized == 0 ) )
5395
0
  {
5396
0
    if( libewf_write_io_handle_initialize_values(
5397
0
         internal_handle->write_io_handle,
5398
0
         internal_handle->io_handle,
5399
0
         internal_handle->media_values,
5400
0
         internal_handle->segment_table,
5401
0
         error ) != 1 )
5402
0
    {
5403
0
      libcerror_error_set(
5404
0
       error,
5405
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5406
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5407
0
       "%s: unable to initialize write IO handle values.",
5408
0
       function );
5409
5410
0
      result = -1;
5411
0
    }
5412
0
  }
5413
0
  if( result != -1 )
5414
0
  {
5415
0
    if( libewf_data_chunk_initialize(
5416
0
         data_chunk,
5417
0
         internal_handle->io_handle,
5418
0
         internal_handle->write_io_handle,
5419
0
         error ) != 1 )
5420
0
    {
5421
0
      libcerror_error_set(
5422
0
       error,
5423
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5424
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5425
0
       "%s: unable to create data chunk.",
5426
0
       function );
5427
5428
0
      result = -1;
5429
0
    }
5430
0
  }
5431
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
5432
0
  if( libcthreads_read_write_lock_release_for_write(
5433
0
       internal_handle->read_write_lock,
5434
0
       error ) != 1 )
5435
0
  {
5436
0
    libcerror_error_set(
5437
0
     error,
5438
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5439
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5440
0
     "%s: unable to release read/write lock for writing.",
5441
0
     function );
5442
5443
0
    return( -1 );
5444
0
  }
5445
0
#endif
5446
0
  return( result );
5447
0
}
5448
5449
/* Reads a (media) data chunk at the current offset
5450
 * This function is not multi-thread safe acquire write lock before call
5451
 * Returns the number of bytes in the data chunk, 0 when no longer data can be read or -1 on error
5452
 */
5453
ssize_t libewf_internal_handle_read_data_chunk_from_file_io_pool(
5454
         libewf_internal_handle_t *internal_handle,
5455
         libbfio_pool_t *file_io_pool,
5456
         libewf_internal_data_chunk_t *internal_data_chunk,
5457
         libcerror_error_t **error )
5458
0
{
5459
0
  libewf_chunk_data_t *chunk_data = NULL;
5460
0
  static char *function           = "libewf_internal_handle_read_data_chunk_from_file_io_pool";
5461
0
  off64_t chunk_data_offset       = 0;
5462
0
  size_t read_count               = 0;
5463
5464
0
  if( internal_handle == NULL )
5465
0
  {
5466
0
    libcerror_error_set(
5467
0
     error,
5468
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5469
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5470
0
     "%s: invalid handle.",
5471
0
     function );
5472
5473
0
    return( -1 );
5474
0
  }
5475
0
  if( internal_handle->io_handle == NULL )
5476
0
  {
5477
0
    libcerror_error_set(
5478
0
     error,
5479
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5480
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5481
0
     "%s: invalid handle - missing IO handle.",
5482
0
     function );
5483
5484
0
    return( -1 );
5485
0
  }
5486
0
  if( internal_handle->chunk_data != NULL )
5487
0
  {
5488
0
    libcerror_error_set(
5489
0
     error,
5490
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5491
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
5492
0
     "%s: invalid handle - chunk data set.",
5493
0
     function );
5494
5495
0
    return( -1 );
5496
0
  }
5497
0
  if( internal_handle->current_offset < 0 )
5498
0
  {
5499
0
    libcerror_error_set(
5500
0
     error,
5501
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5502
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5503
0
     "%s: invalid handle - invalid IO handle - current offset value out of bounds.",
5504
0
     function );
5505
5506
0
    return( -1 );
5507
0
  }
5508
0
  if( internal_handle->media_values == NULL )
5509
0
  {
5510
0
    libcerror_error_set(
5511
0
     error,
5512
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5513
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5514
0
     "%s: invalid handle - missing media values.",
5515
0
     function );
5516
5517
0
    return( -1 );
5518
0
  }
5519
0
  if( (size64_t) internal_handle->current_offset >= internal_handle->media_values->media_size )
5520
0
  {
5521
0
    return( 0 );
5522
0
  }
5523
0
  if( libewf_chunk_table_get_chunk_data_by_offset_no_cache(
5524
0
       internal_handle->chunk_table,
5525
0
       internal_handle->io_handle,
5526
0
       file_io_pool,
5527
0
       internal_handle->media_values,
5528
0
       internal_handle->segment_table,
5529
0
       internal_handle->current_offset,
5530
0
       &chunk_data_offset,
5531
0
       &chunk_data,
5532
0
       error ) != 1 )
5533
0
  {
5534
0
    libcerror_error_set(
5535
0
     error,
5536
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5537
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5538
0
     "%s: unable to retrieve chunk data for offset: %" PRIi64 " (0x%08" PRIx64 ").",
5539
0
     function,
5540
0
     internal_handle->current_offset,
5541
0
     internal_handle->current_offset );
5542
5543
0
    goto on_error;
5544
0
  }
5545
0
  if( chunk_data == NULL )
5546
0
  {
5547
0
    libcerror_error_set(
5548
0
     error,
5549
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5550
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5551
0
     "%s: missing chunk data for offset: %" PRIi64 " (0x%08" PRIx64 ").",
5552
0
     function,
5553
0
     internal_handle->current_offset,
5554
0
     internal_handle->current_offset );
5555
5556
0
    goto on_error;
5557
0
  }
5558
  /* data_chunk takes over management of chunk_data
5559
   */
5560
0
  if( libewf_internal_data_chunk_set_chunk_data(
5561
0
       internal_data_chunk,
5562
0
       chunk_data,
5563
0
       error ) != 1 )
5564
0
  {
5565
0
    libcerror_error_set(
5566
0
     error,
5567
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5568
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5569
0
     "%s: unable to set chunk: %" PRIu64 " data in data chunk.",
5570
0
     function,
5571
0
     chunk_data->chunk_index );
5572
5573
0
    goto on_error;
5574
0
  }
5575
0
  internal_handle->current_offset = chunk_data->range_end_offset;
5576
5577
0
  read_count = (ssize_t) ( chunk_data->range_end_offset - chunk_data->range_start_offset );
5578
5579
0
  return( read_count );
5580
5581
0
on_error:
5582
0
  if( chunk_data != NULL )
5583
0
  {
5584
0
    libewf_chunk_data_free(
5585
0
     &chunk_data,
5586
0
     NULL );
5587
0
  }
5588
0
  return( -1 );
5589
0
}
5590
5591
/* Reads a (media) data chunk at the current offset
5592
 * Returns the number of bytes read, 0 when no longer data can be read or -1 on error
5593
 * Returns the number of bytes in the data chunk, 0 when no longer data can be read or -1 on error
5594
 */
5595
ssize_t libewf_handle_read_data_chunk(
5596
         libewf_handle_t *handle,
5597
         libewf_data_chunk_t *data_chunk,
5598
         libcerror_error_t **error )
5599
0
{
5600
0
  libewf_internal_handle_t *internal_handle = NULL;
5601
0
  static char *function                     = "libewf_handle_read_data_chunk";
5602
0
  ssize_t read_count                        = 0;
5603
5604
0
  if( handle == NULL )
5605
0
  {
5606
0
    libcerror_error_set(
5607
0
     error,
5608
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5609
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5610
0
     "%s: invalid handle.",
5611
0
     function );
5612
5613
0
    return( -1 );
5614
0
  }
5615
0
  internal_handle = (libewf_internal_handle_t *) handle;
5616
5617
0
  if( internal_handle->file_io_pool == NULL )
5618
0
  {
5619
0
    libcerror_error_set(
5620
0
     error,
5621
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5622
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5623
0
     "%s: invalid handle - missing file IO pool.",
5624
0
     function );
5625
5626
0
    return( -1 );
5627
0
  }
5628
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
5629
0
  if( libcthreads_read_write_lock_grab_for_write(
5630
0
       internal_handle->read_write_lock,
5631
0
       error ) != 1 )
5632
0
  {
5633
0
    libcerror_error_set(
5634
0
     error,
5635
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5636
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5637
0
     "%s: unable to grab read/write lock for writing.",
5638
0
     function );
5639
5640
0
    return( -1 );
5641
0
  }
5642
0
#endif
5643
0
  read_count = libewf_internal_handle_read_data_chunk_from_file_io_pool(
5644
0
                internal_handle,
5645
0
                internal_handle->file_io_pool,
5646
0
                (libewf_internal_data_chunk_t *) data_chunk,
5647
0
                error );
5648
5649
0
  if( read_count < 0 )
5650
0
  {
5651
0
    libcerror_error_set(
5652
0
     error,
5653
0
     LIBCERROR_ERROR_DOMAIN_IO,
5654
0
     LIBCERROR_IO_ERROR_READ_FAILED,
5655
0
     "%s: unable to read data chunk.",
5656
0
     function );
5657
5658
0
    read_count = -1;
5659
0
  }
5660
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
5661
0
  if( libcthreads_read_write_lock_release_for_write(
5662
0
       internal_handle->read_write_lock,
5663
0
       error ) != 1 )
5664
0
  {
5665
0
    libcerror_error_set(
5666
0
     error,
5667
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5668
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5669
0
     "%s: unable to release read/write lock for writing.",
5670
0
     function );
5671
5672
0
    return( -1 );
5673
0
  }
5674
0
#endif
5675
0
  return( read_count );
5676
0
}
5677
5678
/* Writes a (media) data chunk at the current offset
5679
 * This function is not multi-thread safe acquire write lock before call
5680
 * Returns the number of bytes written, 0 when no longer data can be written or -1 on error
5681
 */
5682
ssize_t libewf_internal_handle_write_data_chunk_to_file_io_pool(
5683
         libewf_internal_handle_t *internal_handle,
5684
         libbfio_pool_t *file_io_pool,
5685
         libewf_internal_data_chunk_t *internal_data_chunk,
5686
         libcerror_error_t **error )
5687
0
{
5688
0
  static char *function        = "libewf_internal_handle_write_data_chunk_to_file_io_pool";
5689
0
  size_t data_size             = 0;
5690
0
  ssize_t write_count          = 0;
5691
0
  uint64_t current_chunk_index = 0;
5692
5693
0
  if( internal_handle == NULL )
5694
0
  {
5695
0
    libcerror_error_set(
5696
0
     error,
5697
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5698
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5699
0
     "%s: invalid handle.",
5700
0
     function );
5701
5702
0
    return( -1 );
5703
0
  }
5704
0
  if( internal_handle->io_handle == NULL )
5705
0
  {
5706
0
    libcerror_error_set(
5707
0
     error,
5708
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5709
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5710
0
     "%s: invalid handle - missing IO handle.",
5711
0
     function );
5712
5713
0
    return( -1 );
5714
0
  }
5715
0
  if( internal_handle->chunk_data != NULL )
5716
0
  {
5717
0
    libcerror_error_set(
5718
0
     error,
5719
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5720
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
5721
0
     "%s: invalid handle - chunk data set.",
5722
0
     function );
5723
5724
0
    return( -1 );
5725
0
  }
5726
0
  if( internal_handle->current_offset < 0 )
5727
0
  {
5728
0
    libcerror_error_set(
5729
0
     error,
5730
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5731
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5732
0
     "%s: invalid handle - invalid IO handle - current offset value out of bounds.",
5733
0
     function );
5734
5735
0
    return( -1 );
5736
0
  }
5737
0
  if( internal_handle->media_values == NULL )
5738
0
  {
5739
0
    libcerror_error_set(
5740
0
     error,
5741
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5742
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5743
0
     "%s: invalid handle - missing media values.",
5744
0
     function );
5745
5746
0
    return( -1 );
5747
0
  }
5748
0
  if( internal_handle->media_values->chunk_size == 0 )
5749
0
  {
5750
0
    libcerror_error_set(
5751
0
     error,
5752
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5753
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5754
0
     "%s: invalid handle - invalid media values - missing chunk size.",
5755
0
     function );
5756
5757
0
    return( -1 );
5758
0
  }
5759
0
  if( internal_handle->write_io_handle == NULL )
5760
0
  {
5761
0
    libcerror_error_set(
5762
0
     error,
5763
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5764
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5765
0
     "%s: invalid handle - missing write IO handle.",
5766
0
     function );
5767
5768
0
    return( -1 );
5769
0
  }
5770
0
  if( internal_data_chunk == NULL )
5771
0
  {
5772
0
    libcerror_error_set(
5773
0
     error,
5774
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5775
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5776
0
     "%s: invalid data chunk.",
5777
0
     function );
5778
5779
0
    return( -1 );
5780
0
  }
5781
0
  if( ( internal_handle->media_values->media_size != 0 )
5782
0
   && ( (size64_t) internal_handle->current_offset >= internal_handle->media_values->media_size ) )
5783
0
  {
5784
0
    return( 0 );
5785
0
  }
5786
0
  data_size = internal_data_chunk->data_size;
5787
5788
0
  if( internal_handle->media_values->media_size != 0 )
5789
0
  {
5790
0
    if( (size64_t) ( internal_handle->current_offset + data_size ) > internal_handle->media_values->media_size )
5791
0
    {
5792
0
      libcerror_error_set(
5793
0
       error,
5794
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5795
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5796
0
       "%s: last data chunk size value out of bounds.",
5797
0
       function );
5798
5799
0
      return( -1 );
5800
0
    }
5801
0
  }
5802
/* TODO remove need to calculate */
5803
0
  current_chunk_index = internal_handle->current_offset / internal_handle->media_values->chunk_size;
5804
5805
0
  internal_handle->current_offset = (off64_t) current_chunk_index * (off64_t) internal_handle->media_values->chunk_size;
5806
5807
#if defined( HAVE_DEBUG_OUTPUT )
5808
  if( libcnotify_verbose != 0 )
5809
  {
5810
    libcnotify_printf(
5811
     "%s: writing chunk: %" PRIu64 " of size: %" PRIzd ".\n",
5812
     function,
5813
     current_chunk_index,
5814
     data_size );
5815
  }
5816
#endif
5817
0
  if( current_chunk_index < internal_handle->write_io_handle->number_of_chunks_written )
5818
0
  {
5819
0
    libcerror_error_set(
5820
0
     error,
5821
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5822
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
5823
0
     "%s: chunk: %" PRIu64 " already exists.",
5824
0
     function,
5825
0
     current_chunk_index );
5826
5827
0
    return( -1 );
5828
0
  }
5829
0
  write_count = libewf_write_io_handle_write_new_chunk(
5830
0
                 internal_handle->write_io_handle,
5831
0
                 internal_handle->io_handle,
5832
0
                 file_io_pool,
5833
0
                 internal_handle->media_values,
5834
0
                 internal_handle->segment_table,
5835
0
                 internal_handle->header_values,
5836
0
                 internal_handle->hash_values,
5837
0
                 internal_handle->hash_sections,
5838
0
                 internal_handle->sessions,
5839
0
                 internal_handle->tracks,
5840
0
                 internal_handle->acquiry_errors,
5841
0
                 current_chunk_index,
5842
0
                 internal_data_chunk->chunk_data,
5843
0
                 data_size,
5844
0
                 error );
5845
5846
0
  if( write_count < 0 )
5847
0
  {
5848
0
    libcerror_error_set(
5849
0
     error,
5850
0
     LIBCERROR_ERROR_DOMAIN_IO,
5851
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
5852
0
     "%s: unable to write chunk data.",
5853
0
     function );
5854
5855
0
    return( -1 );
5856
0
  }
5857
0
  internal_handle->current_offset += (off64_t) data_size;
5858
5859
0
  return( write_count );
5860
0
}
5861
5862
/* Writes a (media) data chunk at the current offset
5863
 * Returns the number of bytes written, 0 when no longer data can be written or -1 on error
5864
 */
5865
ssize_t libewf_handle_write_data_chunk(
5866
         libewf_handle_t *handle,
5867
         libewf_data_chunk_t *data_chunk,
5868
         libcerror_error_t **error )
5869
0
{
5870
0
  libewf_internal_handle_t *internal_handle = NULL;
5871
0
  static char *function                     = "libewf_handle_write_data_chunk";
5872
0
  ssize_t write_count                       = 0;
5873
5874
0
  if( handle == NULL )
5875
0
  {
5876
0
    libcerror_error_set(
5877
0
     error,
5878
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5879
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5880
0
     "%s: invalid handle.",
5881
0
     function );
5882
5883
0
    return( -1 );
5884
0
  }
5885
0
  internal_handle = (libewf_internal_handle_t *) handle;
5886
5887
0
  if( internal_handle->file_io_pool == NULL )
5888
0
  {
5889
0
    libcerror_error_set(
5890
0
     error,
5891
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5892
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5893
0
     "%s: invalid handle - missing file IO pool.",
5894
0
     function );
5895
5896
0
    return( -1 );
5897
0
  }
5898
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
5899
0
  if( libcthreads_read_write_lock_grab_for_write(
5900
0
       internal_handle->read_write_lock,
5901
0
       error ) != 1 )
5902
0
  {
5903
0
    libcerror_error_set(
5904
0
     error,
5905
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5906
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5907
0
     "%s: unable to grab read/write lock for writing.",
5908
0
     function );
5909
5910
0
    return( -1 );
5911
0
  }
5912
0
#endif
5913
0
  write_count = libewf_internal_handle_write_data_chunk_to_file_io_pool(
5914
0
                 internal_handle,
5915
0
                 internal_handle->file_io_pool,
5916
0
                 (libewf_internal_data_chunk_t *) data_chunk,
5917
0
                 error );
5918
5919
0
  if( write_count < 0 )
5920
0
  {
5921
0
    libcerror_error_set(
5922
0
     error,
5923
0
     LIBCERROR_ERROR_DOMAIN_IO,
5924
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
5925
0
     "%s: unable to write data chunk.",
5926
0
     function );
5927
5928
0
    write_count = -1;
5929
0
  }
5930
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
5931
0
  if( libcthreads_read_write_lock_release_for_write(
5932
0
       internal_handle->read_write_lock,
5933
0
       error ) != 1 )
5934
0
  {
5935
0
    libcerror_error_set(
5936
0
     error,
5937
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5938
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5939
0
     "%s: unable to release read/write lock for writing.",
5940
0
     function );
5941
5942
0
    return( -1 );
5943
0
  }
5944
0
#endif
5945
0
  return( write_count );
5946
0
}
5947
5948
/* Finalizes the write by correcting the EWF the meta data in the segment files
5949
 * This function is required after write from stream
5950
 * Returns the number of bytes written or -1 on error
5951
 */
5952
ssize_t libewf_internal_handle_write_finalize_file_io_pool(
5953
         libewf_internal_handle_t *internal_handle,
5954
         libbfio_pool_t *file_io_pool,
5955
         libcerror_error_t **error )
5956
0
{
5957
0
  libewf_segment_file_t *segment_file = NULL;
5958
0
  static char *function               = "libewf_internal_handle_write_finalize_file_io_pool";
5959
0
  size64_t segment_file_size          = 0;
5960
0
  size_t input_data_size              = 0;
5961
0
  ssize_t write_count                 = 0;
5962
0
  ssize_t write_finalize_count        = 0;
5963
0
  uint64_t chunk_index                = 0;
5964
0
  uint32_t number_of_segments         = 0;
5965
0
  int file_io_pool_entry              = -1;
5966
5967
0
  if( internal_handle == NULL )
5968
0
  {
5969
0
    libcerror_error_set(
5970
0
     error,
5971
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5972
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5973
0
     "%s: invalid handle.",
5974
0
     function );
5975
5976
0
    return( -1 );
5977
0
  }
5978
0
  if( internal_handle->io_handle == NULL )
5979
0
  {
5980
0
    libcerror_error_set(
5981
0
     error,
5982
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5983
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5984
0
     "%s: invalid handle - missing IO handle.",
5985
0
     function );
5986
5987
0
    return( -1 );
5988
0
  }
5989
0
  if( internal_handle->current_offset < 0 )
5990
0
  {
5991
0
    libcerror_error_set(
5992
0
     error,
5993
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5994
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5995
0
     "%s: invalid handle - invalid IO handle - current offset value out of bounds.",
5996
0
     function );
5997
5998
0
    return( -1 );
5999
0
  }
6000
0
  if( ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
6001
0
   && ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_RESUME ) == 0 ) )
6002
0
  {
6003
0
    if( internal_handle->chunk_data != NULL )
6004
0
    {
6005
0
      libcerror_error_set(
6006
0
       error,
6007
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6008
0
       LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
6009
0
       "%s: invalid handle - chunk data set.",
6010
0
       function );
6011
6012
0
      return( -1 );
6013
0
    }
6014
0
  }
6015
0
  if( internal_handle->write_io_handle == NULL )
6016
0
  {
6017
0
    libcerror_error_set(
6018
0
     error,
6019
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6020
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6021
0
     "%s: invalid handle - missing write IO handle.",
6022
0
     function );
6023
6024
0
    return( -1 );
6025
0
  }
6026
0
  if( internal_handle->media_values == NULL )
6027
0
  {
6028
0
    libcerror_error_set(
6029
0
     error,
6030
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6031
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6032
0
     "%s: invalid handle - missing media values.",
6033
0
     function );
6034
6035
0
    return( -1 );
6036
0
  }
6037
0
  if( internal_handle->media_values->chunk_size == 0 )
6038
0
  {
6039
0
    libcerror_error_set(
6040
0
     error,
6041
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6042
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6043
0
     "%s: invalid handle - invalid media values - missing chunk size.",
6044
0
     function );
6045
6046
0
    return( -1 );
6047
0
  }
6048
0
  if( internal_handle->write_io_handle->write_finalized != 0 )
6049
0
  {
6050
0
    return( 0 );
6051
0
  }
6052
0
  if( ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
6053
0
   && ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_RESUME ) == 0 ) )
6054
0
  {
6055
0
    return( 0 );
6056
0
  }
6057
0
  if( internal_handle->chunk_data != NULL )
6058
0
  {
6059
0
    chunk_index = internal_handle->current_offset / internal_handle->media_values->chunk_size;
6060
6061
0
    if( chunk_index < internal_handle->write_io_handle->number_of_chunks_written )
6062
0
    {
6063
0
      libcerror_error_set(
6064
0
       error,
6065
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6066
0
       LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
6067
0
       "%s: chunk: %" PRIu64 " already exists.",
6068
0
       function,
6069
0
       chunk_index );
6070
6071
0
      return( -1 );
6072
0
    }
6073
0
    input_data_size = internal_handle->chunk_data->data_size;
6074
6075
0
    if( libewf_chunk_data_pack(
6076
0
         internal_handle->chunk_data,
6077
0
         internal_handle->io_handle,
6078
0
         internal_handle->write_io_handle->compressed_zero_byte_empty_block,
6079
0
         internal_handle->write_io_handle->compressed_zero_byte_empty_block_size,
6080
0
         internal_handle->write_io_handle->pack_flags,
6081
0
         error ) != 1 )
6082
0
    {
6083
0
      libcerror_error_set(
6084
0
       error,
6085
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6086
0
       LIBCERROR_RUNTIME_ERROR_GENERIC,
6087
0
       "%s: unable to pack chunk: %" PRIu64 " data.",
6088
0
       function,
6089
0
       chunk_index );
6090
6091
0
      return( -1 );
6092
0
    }
6093
0
    write_count = libewf_write_io_handle_write_new_chunk(
6094
0
             internal_handle->write_io_handle,
6095
0
             internal_handle->io_handle,
6096
0
             file_io_pool,
6097
0
             internal_handle->media_values,
6098
0
             internal_handle->segment_table,
6099
0
             internal_handle->header_values,
6100
0
             internal_handle->hash_values,
6101
0
             internal_handle->hash_sections,
6102
0
             internal_handle->sessions,
6103
0
             internal_handle->tracks,
6104
0
             internal_handle->acquiry_errors,
6105
0
             chunk_index,
6106
0
             internal_handle->chunk_data,
6107
0
             input_data_size,
6108
0
             error );
6109
6110
0
    if( write_count <= 0 )
6111
0
    {
6112
0
      libcerror_error_set(
6113
0
       error,
6114
0
       LIBCERROR_ERROR_DOMAIN_IO,
6115
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
6116
0
       "%s: unable to write new chunk.",
6117
0
       function );
6118
6119
0
      return( -1 );
6120
0
    }
6121
0
    write_finalize_count += write_count;
6122
6123
0
    if( libewf_chunk_data_free(
6124
0
         &( internal_handle->chunk_data ),
6125
0
         error ) != 1 )
6126
0
    {
6127
0
      libcerror_error_set(
6128
0
       error,
6129
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6130
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
6131
0
       "%s: unable to free chunk data.",
6132
0
       function );
6133
6134
0
      return( -1 );
6135
0
    }
6136
0
  }
6137
  /* Check if all media data has been written
6138
   */
6139
0
  if( ( internal_handle->media_values->media_size != 0 )
6140
0
   && ( internal_handle->write_io_handle->input_write_count < (ssize64_t) internal_handle->media_values->media_size ) )
6141
0
  {
6142
0
    return( write_finalize_count );
6143
0
  }
6144
0
  if( libewf_segment_table_get_number_of_segments(
6145
0
       internal_handle->segment_table,
6146
0
       &number_of_segments,
6147
0
       error ) != 1 )
6148
0
  {
6149
0
    libcerror_error_set(
6150
0
     error,
6151
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6152
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6153
0
     "%s: unable to retrieve number of segments.",
6154
0
     function );
6155
6156
0
    return( -1 );
6157
0
  }
6158
0
  if( number_of_segments == 0 )
6159
0
  {
6160
    /* No segment file needs to be created
6161
     */
6162
/* TODO clean up this logic: when is this triggered? */
6163
0
    if( internal_handle->media_values->media_size != 0 )
6164
0
    {
6165
0
      return( write_finalize_count );
6166
0
    }
6167
    /* Create the segment file if required
6168
     */
6169
0
    if( libewf_write_io_handle_create_segment_file(
6170
0
         internal_handle->io_handle,
6171
0
         file_io_pool,
6172
0
         internal_handle->segment_table,
6173
0
         internal_handle->io_handle->segment_file_type,
6174
0
         0,
6175
0
         internal_handle->write_io_handle->maximum_number_of_segments,
6176
0
         internal_handle->media_values->set_identifier,
6177
0
         &file_io_pool_entry,
6178
0
         &segment_file,
6179
0
         error ) != 1 )
6180
0
    {
6181
0
      libcerror_error_set(
6182
0
       error,
6183
0
       LIBCERROR_ERROR_DOMAIN_IO,
6184
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
6185
0
       "%s: unable to create segment file: 0.",
6186
0
       function );
6187
6188
0
      return( -1 );
6189
0
    }
6190
0
    write_count = libewf_segment_file_write_start(
6191
0
                   segment_file,
6192
0
                   file_io_pool,
6193
0
                   file_io_pool_entry,
6194
0
                   &( internal_handle->write_io_handle->case_data ),
6195
0
                   &( internal_handle->write_io_handle->case_data_size ),
6196
0
                   &( internal_handle->write_io_handle->device_information ),
6197
0
                   &( internal_handle->write_io_handle->device_information_size ),
6198
0
                   &( internal_handle->write_io_handle->data_section ),
6199
0
                   internal_handle->media_values,
6200
0
                   internal_handle->header_values,
6201
0
                   internal_handle->write_io_handle->timestamp,
6202
0
                   error );
6203
6204
0
    if( write_count == -1 )
6205
0
    {
6206
0
      libcerror_error_set(
6207
0
       error,
6208
0
       LIBCERROR_ERROR_DOMAIN_IO,
6209
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
6210
0
       "%s: unable to write segment file: 0 start.",
6211
0
       function );
6212
6213
0
      return( -1 );
6214
0
    }
6215
0
    write_finalize_count += write_count;
6216
0
  }
6217
  /* Check if the last segment file is still open for writing
6218
   */
6219
0
  else if( internal_handle->write_io_handle->current_segment_file != NULL )
6220
0
  {
6221
0
    if( libewf_segment_table_get_segment_by_index(
6222
0
         internal_handle->segment_table,
6223
0
         internal_handle->write_io_handle->current_segment_number,
6224
0
         &file_io_pool_entry,
6225
0
         &segment_file_size,
6226
0
         error ) != 1 )
6227
0
    {
6228
0
      libcerror_error_set(
6229
0
       error,
6230
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6231
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6232
0
       "%s: unable to retrieve segment: %" PRIu32 " from segment table.",
6233
0
       function,
6234
0
       internal_handle->write_io_handle->current_segment_number );
6235
6236
0
      return( -1 );
6237
0
    }
6238
    /* Check if chunks section needs to be corrected
6239
     */
6240
0
    if( internal_handle->write_io_handle->chunks_section_offset != 0 )
6241
0
    {
6242
0
      write_count = libewf_write_io_handle_write_chunks_section_end(
6243
0
                     internal_handle->write_io_handle,
6244
0
                     internal_handle->io_handle,
6245
0
               file_io_pool,
6246
0
               file_io_pool_entry,
6247
0
                     internal_handle->write_io_handle->current_segment_file,
6248
0
                     error );
6249
6250
0
      if( write_count == -1 )
6251
0
      {
6252
0
        libcerror_error_set(
6253
0
         error,
6254
0
         LIBCERROR_ERROR_DOMAIN_IO,
6255
0
         LIBCERROR_IO_ERROR_WRITE_FAILED,
6256
0
         "%s: unable to write chunks section end: %" PRIu32 ".",
6257
0
         function,
6258
0
         internal_handle->write_io_handle->current_segment_number );
6259
6260
0
        return( -1 );
6261
0
      }
6262
0
      write_finalize_count += write_count;
6263
0
    }
6264
    /* Close the segment file
6265
     */
6266
#if defined( HAVE_DEBUG_OUTPUT )
6267
    if( libcnotify_verbose != 0 )
6268
    {
6269
      libcnotify_printf(
6270
       "%s: closing last segment file: %" PRIu32 ".\n",
6271
       function,
6272
       internal_handle->write_io_handle->current_segment_number );
6273
    }
6274
#endif
6275
0
    write_count = libewf_segment_file_write_close(
6276
0
                   internal_handle->write_io_handle->current_segment_file,
6277
0
                   file_io_pool,
6278
0
                   file_io_pool_entry,
6279
0
                   internal_handle->write_io_handle->number_of_chunks_written_to_segment_file,
6280
0
                   1,
6281
0
                   internal_handle->hash_sections,
6282
0
                   internal_handle->hash_values,
6283
0
                   internal_handle->media_values,
6284
0
                   internal_handle->sessions,
6285
0
                   internal_handle->tracks,
6286
0
                   internal_handle->acquiry_errors,
6287
0
                   &( internal_handle->write_io_handle->data_section ),
6288
0
                   error );
6289
6290
0
    if( write_count == -1 )
6291
0
    {
6292
0
      libcerror_error_set(
6293
0
       error,
6294
0
       LIBCERROR_ERROR_DOMAIN_IO,
6295
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
6296
0
       "%s: unable to close segment file: %" PRIu32 ".",
6297
0
       function,
6298
0
       internal_handle->write_io_handle->current_segment_number );
6299
6300
0
      return( -1 );
6301
0
    }
6302
0
    write_finalize_count += write_count;
6303
6304
0
    internal_handle->write_io_handle->current_segment_file = NULL;
6305
0
  }
6306
  /* Correct the media values if streamed write was used
6307
   */
6308
0
  if( internal_handle->media_values->media_size == 0 )
6309
0
  {
6310
    /* Determine the media values
6311
     */
6312
0
    internal_handle->media_values->number_of_chunks  = internal_handle->write_io_handle->number_of_chunks_written;
6313
0
    internal_handle->media_values->number_of_sectors = (uint64_t) ( internal_handle->write_io_handle->input_write_count / internal_handle->media_values->bytes_per_sector );
6314
0
    internal_handle->media_values->media_size        = (size64_t) internal_handle->write_io_handle->input_write_count;
6315
6316
    /* Flush the section write caches
6317
     */
6318
0
    if( internal_handle->write_io_handle->case_data != NULL )
6319
0
    {
6320
0
      memory_free(
6321
0
       internal_handle->write_io_handle->case_data );
6322
6323
0
      internal_handle->write_io_handle->case_data      = NULL;
6324
0
      internal_handle->write_io_handle->case_data_size = 0;
6325
0
    }
6326
0
    if( internal_handle->write_io_handle->device_information != NULL )
6327
0
    {
6328
0
      memory_free(
6329
0
       internal_handle->write_io_handle->device_information );
6330
6331
0
      internal_handle->write_io_handle->device_information      = NULL;
6332
0
      internal_handle->write_io_handle->device_information_size = 0;
6333
0
    }
6334
0
    if( internal_handle->write_io_handle->data_section != NULL )
6335
0
    {
6336
0
      memory_free(
6337
0
       internal_handle->write_io_handle->data_section );
6338
6339
0
      internal_handle->write_io_handle->data_section = NULL;
6340
0
    }
6341
    /* Correct the sections in the segment files
6342
     */
6343
0
    if( libewf_write_io_handle_finalize_write_sections_corrections(
6344
0
         internal_handle->write_io_handle,
6345
0
         file_io_pool,
6346
0
         internal_handle->media_values,
6347
0
         internal_handle->segment_table,
6348
0
         internal_handle->header_values,
6349
0
         internal_handle->hash_values,
6350
0
         internal_handle->hash_sections,
6351
0
         internal_handle->sessions,
6352
0
         internal_handle->tracks,
6353
0
         internal_handle->acquiry_errors,
6354
0
         error ) != 1 )
6355
0
    {
6356
0
      libcerror_error_set(
6357
0
       error,
6358
0
       LIBCERROR_ERROR_DOMAIN_IO,
6359
0
       LIBCERROR_IO_ERROR_WRITE_FAILED,
6360
0
       "%s: unable to write sections corrections to segment files.",
6361
0
       function );
6362
6363
0
      return( -1 );
6364
0
    }
6365
0
  }
6366
0
  internal_handle->write_io_handle->write_finalized = 1;
6367
6368
0
  return( write_finalize_count );
6369
0
}
6370
6371
/* Finalizes the write by correcting the EWF the meta data in the segment files
6372
 * This function is required after write from stream
6373
 * Returns the number of bytes written or -1 on error
6374
 */
6375
ssize_t libewf_handle_write_finalize(
6376
         libewf_handle_t *handle,
6377
         libcerror_error_t **error )
6378
0
{
6379
0
  libewf_internal_handle_t *internal_handle = NULL;
6380
0
  static char *function                     = "libewf_handle_write_finalize";
6381
0
  ssize_t write_count                       = 0;
6382
6383
0
  if( handle == NULL )
6384
0
  {
6385
0
    libcerror_error_set(
6386
0
     error,
6387
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6388
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6389
0
     "%s: invalid handle.",
6390
0
     function );
6391
6392
0
    return( -1 );
6393
0
  }
6394
0
  internal_handle = (libewf_internal_handle_t *) handle;
6395
6396
0
  if( internal_handle->file_io_pool == NULL )
6397
0
  {
6398
0
    libcerror_error_set(
6399
0
     error,
6400
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6401
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6402
0
     "%s: invalid handle - missing file IO pool.",
6403
0
     function );
6404
6405
0
    return( -1 );
6406
0
  }
6407
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
6408
0
  if( libcthreads_read_write_lock_grab_for_write(
6409
0
       internal_handle->read_write_lock,
6410
0
       error ) != 1 )
6411
0
  {
6412
0
    libcerror_error_set(
6413
0
     error,
6414
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6415
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6416
0
     "%s: unable to grab read/write lock for writing.",
6417
0
     function );
6418
6419
0
    return( -1 );
6420
0
  }
6421
0
#endif
6422
0
  write_count = libewf_internal_handle_write_finalize_file_io_pool(
6423
0
                 internal_handle,
6424
0
                 internal_handle->file_io_pool,
6425
0
                 error );
6426
6427
0
  if( write_count == -1 )
6428
0
  {
6429
0
    libcerror_error_set(
6430
0
     error,
6431
0
     LIBCERROR_ERROR_DOMAIN_IO,
6432
0
     LIBCERROR_IO_ERROR_READ_FAILED,
6433
0
     "%s: unable to write finalize.",
6434
0
     function );
6435
6436
0
    write_count = -1;
6437
0
  }
6438
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
6439
0
  if( libcthreads_read_write_lock_release_for_write(
6440
0
       internal_handle->read_write_lock,
6441
0
       error ) != 1 )
6442
0
  {
6443
0
    libcerror_error_set(
6444
0
     error,
6445
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6446
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6447
0
     "%s: unable to release read/write lock for writing.",
6448
0
     function );
6449
6450
0
    return( -1 );
6451
0
  }
6452
0
#endif
6453
0
  return( write_count );
6454
0
}
6455
6456
/* Seeks a certain offset of the (media) data
6457
 * This function is not multi-thread safe acquire write lock before call
6458
 * Returns the offset if seek is successful or -1 on error
6459
 */
6460
off64_t libewf_internal_handle_seek_offset(
6461
         libewf_internal_handle_t *internal_handle,
6462
         off64_t offset,
6463
         int whence,
6464
         libcerror_error_t **error )
6465
0
{
6466
0
  static char *function = "libewf_internal_handle_seek_offset";
6467
6468
0
  if( internal_handle == NULL )
6469
0
  {
6470
0
    libcerror_error_set(
6471
0
     error,
6472
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6473
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6474
0
     "%s: invalid handle.",
6475
0
     function );
6476
6477
0
    return( -1 );
6478
0
  }
6479
0
  if( internal_handle->chunk_data != NULL )
6480
0
  {
6481
0
    libcerror_error_set(
6482
0
     error,
6483
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6484
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
6485
0
     "%s: invalid handle - chunk data set.",
6486
0
     function );
6487
6488
0
    return( -1 );
6489
0
  }
6490
0
  if( internal_handle->media_values == NULL )
6491
0
  {
6492
0
    libcerror_error_set(
6493
0
     error,
6494
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6495
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6496
0
     "%s: invalid handle - missing media values.",
6497
0
     function );
6498
6499
0
    return( -1 );
6500
0
  }
6501
0
  if( internal_handle->media_values->chunk_size == 0 )
6502
0
  {
6503
0
    libcerror_error_set(
6504
0
     error,
6505
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6506
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6507
0
     "%s: invalid handle - invalid media values - missing chunk size.",
6508
0
     function );
6509
6510
0
    return( -1 );
6511
0
  }
6512
0
  if( ( whence != SEEK_CUR )
6513
0
   && ( whence != SEEK_END )
6514
0
   && ( whence != SEEK_SET ) )
6515
0
  {
6516
0
    libcerror_error_set(
6517
0
     error,
6518
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6519
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
6520
0
     "%s: unsupported whence.",
6521
0
     function );
6522
6523
0
    return( -1 );
6524
0
  }
6525
0
  if( whence == SEEK_CUR )
6526
0
  {
6527
0
    offset += internal_handle->current_offset;
6528
0
  }
6529
0
  else if( whence == SEEK_END )
6530
0
  {
6531
0
    offset += (off64_t) internal_handle->media_values->media_size;
6532
0
  }
6533
#if defined( HAVE_DEBUG_OUTPUT )
6534
  if( libcnotify_verbose != 0 )
6535
  {
6536
    libcnotify_printf(
6537
     "%s: seeking media data offset: %" PRIi64 ".\n",
6538
     function,
6539
     offset );
6540
  }
6541
#endif
6542
0
  if( offset < 0 )
6543
0
  {
6544
0
    libcerror_error_set(
6545
0
     error,
6546
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6547
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
6548
0
     "%s: invalid offset value out of bounds.",
6549
0
     function );
6550
6551
0
    return( -1 );
6552
0
  }
6553
0
  internal_handle->current_offset = offset;
6554
6555
0
  return( offset );
6556
0
}
6557
6558
/* Seeks a certain offset of the (media) data
6559
 * Returns the offset if seek is successful or -1 on error
6560
 */
6561
off64_t libewf_handle_seek_offset(
6562
         libewf_handle_t *handle,
6563
         off64_t offset,
6564
         int whence,
6565
         libcerror_error_t **error )
6566
0
{
6567
0
  libewf_internal_handle_t *internal_handle = NULL;
6568
0
  static char *function                     = "libewf_handle_seek_offset";
6569
6570
0
  if( handle == NULL )
6571
0
  {
6572
0
    libcerror_error_set(
6573
0
     error,
6574
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6575
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6576
0
     "%s: invalid handle.",
6577
0
     function );
6578
6579
0
    return( -1 );
6580
0
  }
6581
0
  internal_handle = (libewf_internal_handle_t *) handle;
6582
6583
0
  if( internal_handle->file_io_pool == NULL )
6584
0
  {
6585
0
    libcerror_error_set(
6586
0
     error,
6587
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6588
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6589
0
     "%s: invalid handle - missing file IO pool.",
6590
0
     function );
6591
6592
0
    return( -1 );
6593
0
  }
6594
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
6595
0
  if( libcthreads_read_write_lock_grab_for_write(
6596
0
       internal_handle->read_write_lock,
6597
0
       error ) != 1 )
6598
0
  {
6599
0
    libcerror_error_set(
6600
0
     error,
6601
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6602
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6603
0
     "%s: unable to grab read/write lock for writing.",
6604
0
     function );
6605
6606
0
    return( -1 );
6607
0
  }
6608
0
#endif
6609
0
  offset = libewf_internal_handle_seek_offset(
6610
0
            internal_handle,
6611
0
            offset,
6612
0
            whence,
6613
0
            error );
6614
6615
0
  if( offset == -1 )
6616
0
  {
6617
0
    libcerror_error_set(
6618
0
     error,
6619
0
     LIBCERROR_ERROR_DOMAIN_IO,
6620
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
6621
0
     "%s: unable to seek offset.",
6622
0
     function );
6623
0
  }
6624
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
6625
0
  if( libcthreads_read_write_lock_release_for_write(
6626
0
       internal_handle->read_write_lock,
6627
0
       error ) != 1 )
6628
0
  {
6629
0
    libcerror_error_set(
6630
0
     error,
6631
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6632
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6633
0
     "%s: unable to release read/write lock for writing.",
6634
0
     function );
6635
6636
0
    return( -1 );
6637
0
  }
6638
0
#endif
6639
0
  return( offset );
6640
0
}
6641
6642
/* Retrieves the current offset of the (media) data
6643
 * Returns 1 if successful or -1 on error
6644
 */
6645
int libewf_handle_get_offset(
6646
     libewf_handle_t *handle,
6647
     off64_t *offset,
6648
     libcerror_error_t **error )
6649
0
{
6650
0
  libewf_internal_handle_t *internal_handle = NULL;
6651
0
  static char *function                     = "libewf_handle_get_offset";
6652
6653
0
  if( handle == NULL )
6654
0
  {
6655
0
    libcerror_error_set(
6656
0
     error,
6657
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6658
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6659
0
     "%s: invalid handle.",
6660
0
     function );
6661
6662
0
    return( -1 );
6663
0
  }
6664
0
  internal_handle = (libewf_internal_handle_t *) handle;
6665
6666
0
  if( offset == NULL )
6667
0
  {
6668
0
    libcerror_error_set(
6669
0
     error,
6670
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6671
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6672
0
     "%s: invalid offset.",
6673
0
     function );
6674
6675
0
    return( -1 );
6676
0
  }
6677
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
6678
0
  if( libcthreads_read_write_lock_grab_for_read(
6679
0
       internal_handle->read_write_lock,
6680
0
       error ) != 1 )
6681
0
  {
6682
0
    libcerror_error_set(
6683
0
     error,
6684
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6685
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6686
0
     "%s: unable to grab read/write lock for reading.",
6687
0
     function );
6688
6689
0
    return( -1 );
6690
0
  }
6691
0
#endif
6692
0
  *offset = internal_handle->current_offset;
6693
6694
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
6695
0
  if( libcthreads_read_write_lock_release_for_read(
6696
0
       internal_handle->read_write_lock,
6697
0
       error ) != 1 )
6698
0
  {
6699
0
    libcerror_error_set(
6700
0
     error,
6701
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6702
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6703
0
     "%s: unable to release read/write lock for reading.",
6704
0
     function );
6705
6706
0
    return( -1 );
6707
0
  }
6708
0
#endif
6709
0
  return( 1 );
6710
0
}
6711
6712
/* Sets the maximum number of (concurrent) open file handles
6713
 * Returns 1 if successful or -1 on error
6714
 */
6715
int libewf_handle_set_maximum_number_of_open_handles(
6716
     libewf_handle_t *handle,
6717
     int maximum_number_of_open_handles,
6718
     libcerror_error_t **error )
6719
0
{
6720
0
  libewf_internal_handle_t *internal_handle = NULL;
6721
0
  static char *function                     = "libewf_handle_set_maximum_number_of_open_handles";
6722
0
  int result                                = 1;
6723
6724
0
  if( handle == NULL )
6725
0
  {
6726
0
    libcerror_error_set(
6727
0
     error,
6728
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6729
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6730
0
     "%s: invalid handle.",
6731
0
     function );
6732
6733
0
    return( -1 );
6734
0
  }
6735
0
  internal_handle = (libewf_internal_handle_t *) handle;
6736
6737
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
6738
0
  if( libcthreads_read_write_lock_grab_for_write(
6739
0
       internal_handle->read_write_lock,
6740
0
       error ) != 1 )
6741
0
  {
6742
0
    libcerror_error_set(
6743
0
     error,
6744
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6745
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6746
0
     "%s: unable to grab read/write lock for writing.",
6747
0
     function );
6748
6749
0
    return( -1 );
6750
0
  }
6751
0
#endif
6752
0
  if( internal_handle->file_io_pool != NULL )
6753
0
  {
6754
0
    result = libbfio_pool_set_maximum_number_of_open_handles(
6755
0
              internal_handle->file_io_pool,
6756
0
              maximum_number_of_open_handles,
6757
0
              error );
6758
6759
0
    if( result != 1 )
6760
0
    {
6761
0
      libcerror_error_set(
6762
0
       error,
6763
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6764
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6765
0
       "%s: unable to set maximum number of open handles in file IO pool.",
6766
0
       function );
6767
0
    }
6768
0
  }
6769
0
  if( result == 1 )
6770
0
  {
6771
0
    internal_handle->maximum_number_of_open_handles = maximum_number_of_open_handles;
6772
0
  }
6773
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
6774
0
  if( libcthreads_read_write_lock_release_for_write(
6775
0
       internal_handle->read_write_lock,
6776
0
       error ) != 1 )
6777
0
  {
6778
0
    libcerror_error_set(
6779
0
     error,
6780
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6781
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6782
0
     "%s: unable to release read/write lock for writing.",
6783
0
     function );
6784
6785
0
    return( -1 );
6786
0
  }
6787
0
#endif
6788
0
  return( result );
6789
0
}
6790
6791
/* Determine if the segment files are corrupted
6792
 * Returns 1 if corrupted, 0 if not or -1 on error
6793
 */
6794
int libewf_handle_segment_files_corrupted(
6795
     libewf_handle_t *handle,
6796
     libcerror_error_t **error )
6797
1.16k
{
6798
1.16k
  libewf_internal_handle_t *internal_handle = NULL;
6799
1.16k
  static char *function                     = "libewf_handle_segment_files_corrupted";
6800
1.16k
  int result                                = 0;
6801
6802
1.16k
  if( handle == NULL )
6803
0
  {
6804
0
    libcerror_error_set(
6805
0
     error,
6806
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6807
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6808
0
     "%s: invalid handle.",
6809
0
     function );
6810
6811
0
    return( -1 );
6812
0
  }
6813
1.16k
  internal_handle = (libewf_internal_handle_t *) handle;
6814
6815
1.16k
  if( internal_handle->segment_table == NULL )
6816
0
  {
6817
0
    libcerror_error_set(
6818
0
     error,
6819
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6820
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6821
0
     "%s: invalid handle - missing segment table.",
6822
0
     function );
6823
6824
0
    return( -1 );
6825
0
  }
6826
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
6827
1.16k
  if( libcthreads_read_write_lock_grab_for_read(
6828
1.16k
       internal_handle->read_write_lock,
6829
1.16k
       error ) != 1 )
6830
0
  {
6831
0
    libcerror_error_set(
6832
0
     error,
6833
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6834
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6835
0
     "%s: unable to grab read/write lock for reading.",
6836
0
     function );
6837
6838
0
    return( -1 );
6839
0
  }
6840
1.16k
#endif
6841
1.16k
  result = ( internal_handle->segment_table->flags & LIBEWF_SEGMENT_TABLE_FLAG_IS_CORRUPTED ) != 0;
6842
6843
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
6844
1.16k
  if( libcthreads_read_write_lock_release_for_read(
6845
1.16k
       internal_handle->read_write_lock,
6846
1.16k
       error ) != 1 )
6847
0
  {
6848
0
    libcerror_error_set(
6849
0
     error,
6850
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6851
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6852
0
     "%s: unable to release read/write lock for reading.",
6853
0
     function );
6854
6855
0
    return( -1 );
6856
0
  }
6857
1.16k
#endif
6858
1.16k
  return( result );
6859
1.16k
}
6860
6861
/* Determine if the segment files are encrypted
6862
 * Returns 1 if encrypted, 0 if not or -1 on error
6863
 */
6864
int libewf_handle_segment_files_encrypted(
6865
     libewf_handle_t *handle,
6866
     libcerror_error_t **error )
6867
1.16k
{
6868
1.16k
  libewf_internal_handle_t *internal_handle = NULL;
6869
1.16k
  static char *function                     = "libewf_handle_segment_files_encrypted";
6870
1.16k
  int result                                = 0;
6871
6872
1.16k
  if( handle == NULL )
6873
0
  {
6874
0
    libcerror_error_set(
6875
0
     error,
6876
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6877
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6878
0
     "%s: invalid handle.",
6879
0
     function );
6880
6881
0
    return( -1 );
6882
0
  }
6883
1.16k
  internal_handle = (libewf_internal_handle_t *) handle;
6884
6885
1.16k
  if( internal_handle->io_handle == NULL )
6886
0
  {
6887
0
    libcerror_error_set(
6888
0
     error,
6889
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6890
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6891
0
     "%s: invalid handle - missing IO handle.",
6892
0
     function );
6893
6894
0
    return( -1 );
6895
0
  }
6896
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
6897
1.16k
  if( libcthreads_read_write_lock_grab_for_read(
6898
1.16k
       internal_handle->read_write_lock,
6899
1.16k
       error ) != 1 )
6900
0
  {
6901
0
    libcerror_error_set(
6902
0
     error,
6903
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6904
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6905
0
     "%s: unable to grab read/write lock for reading.",
6906
0
     function );
6907
6908
0
    return( -1 );
6909
0
  }
6910
1.16k
#endif
6911
1.16k
  result = (int) internal_handle->io_handle->is_encrypted;
6912
6913
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
6914
1.16k
  if( libcthreads_read_write_lock_release_for_read(
6915
1.16k
       internal_handle->read_write_lock,
6916
1.16k
       error ) != 1 )
6917
0
  {
6918
0
    libcerror_error_set(
6919
0
     error,
6920
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6921
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6922
0
     "%s: unable to release read/write lock for reading.",
6923
0
     function );
6924
6925
0
    return( -1 );
6926
0
  }
6927
1.16k
#endif
6928
1.16k
  return( result );
6929
1.16k
}
6930
6931
/* Retrieves the segment filename size
6932
 * The filename size should include the end of string character
6933
 * Returns 1 if successful, 0 if not set or -1 on error
6934
 */
6935
int libewf_handle_get_segment_filename_size(
6936
     libewf_handle_t *handle,
6937
     size_t *filename_size,
6938
     libcerror_error_t **error )
6939
0
{
6940
0
  libewf_internal_handle_t *internal_handle = NULL;
6941
0
  static char *function                     = "libewf_handle_get_segment_filename_size";
6942
0
  int result                                = 0;
6943
6944
0
  if( handle == NULL )
6945
0
  {
6946
0
    libcerror_error_set(
6947
0
     error,
6948
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6949
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6950
0
     "%s: invalid handle.",
6951
0
     function );
6952
6953
0
    return( -1 );
6954
0
  }
6955
0
  internal_handle = (libewf_internal_handle_t *) handle;
6956
6957
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
6958
0
  if( libcthreads_read_write_lock_grab_for_read(
6959
0
       internal_handle->read_write_lock,
6960
0
       error ) != 1 )
6961
0
  {
6962
0
    libcerror_error_set(
6963
0
     error,
6964
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6965
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6966
0
     "%s: unable to grab read/write lock for reading.",
6967
0
     function );
6968
6969
0
    return( -1 );
6970
0
  }
6971
0
#endif
6972
0
  result = libewf_segment_table_get_basename_size(
6973
0
            internal_handle->segment_table,
6974
0
            filename_size,
6975
0
            error );
6976
6977
0
  if( result == -1 )
6978
0
  {
6979
0
    libcerror_error_set(
6980
0
     error,
6981
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6982
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6983
0
     "%s: unable to retrieve segment table basename size.",
6984
0
     function );
6985
0
  }
6986
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
6987
0
  if( libcthreads_read_write_lock_release_for_read(
6988
0
       internal_handle->read_write_lock,
6989
0
       error ) != 1 )
6990
0
  {
6991
0
    libcerror_error_set(
6992
0
     error,
6993
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6994
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6995
0
     "%s: unable to release read/write lock for reading.",
6996
0
     function );
6997
6998
0
    return( -1 );
6999
0
  }
7000
0
#endif
7001
0
  return( result );
7002
0
}
7003
7004
/* Retrieves the segment filename
7005
 * The filename size should include the end of string character
7006
 * Returns 1 if successful, 0 if not set or -1 on error
7007
 */
7008
int libewf_handle_get_segment_filename(
7009
     libewf_handle_t *handle,
7010
     char *filename,
7011
     size_t filename_size,
7012
     libcerror_error_t **error )
7013
0
{
7014
0
  libewf_internal_handle_t *internal_handle = NULL;
7015
0
  static char *function                     = "libewf_handle_get_segment_filename";
7016
0
  int result                                = 0;
7017
7018
0
  if( handle == NULL )
7019
0
  {
7020
0
    libcerror_error_set(
7021
0
     error,
7022
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7023
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7024
0
     "%s: invalid handle.",
7025
0
     function );
7026
7027
0
    return( -1 );
7028
0
  }
7029
0
  internal_handle = (libewf_internal_handle_t *) handle;
7030
7031
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7032
0
  if( libcthreads_read_write_lock_grab_for_read(
7033
0
       internal_handle->read_write_lock,
7034
0
       error ) != 1 )
7035
0
  {
7036
0
    libcerror_error_set(
7037
0
     error,
7038
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7039
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7040
0
     "%s: unable to grab read/write lock for reading.",
7041
0
     function );
7042
7043
0
    return( -1 );
7044
0
  }
7045
0
#endif
7046
0
  result = libewf_segment_table_get_basename(
7047
0
            internal_handle->segment_table,
7048
0
            filename,
7049
0
            filename_size,
7050
0
            error );
7051
7052
0
  if( result == -1 )
7053
0
  {
7054
0
    libcerror_error_set(
7055
0
     error,
7056
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7057
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7058
0
     "%s: unable to retrieve segment table basename.",
7059
0
     function );
7060
0
  }
7061
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7062
0
  if( libcthreads_read_write_lock_release_for_read(
7063
0
       internal_handle->read_write_lock,
7064
0
       error ) != 1 )
7065
0
  {
7066
0
    libcerror_error_set(
7067
0
     error,
7068
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7069
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7070
0
     "%s: unable to release read/write lock for reading.",
7071
0
     function );
7072
7073
0
    return( -1 );
7074
0
  }
7075
0
#endif
7076
0
  return( result );
7077
0
}
7078
7079
/* Sets the segment file
7080
 * Returns 1 if successful or -1 on error
7081
 */
7082
int libewf_handle_set_segment_filename(
7083
     libewf_handle_t *handle,
7084
     const char *filename,
7085
     size_t filename_length,
7086
     libcerror_error_t **error )
7087
0
{
7088
0
  libewf_internal_handle_t *internal_handle = NULL;
7089
0
  static char *function                     = "libewf_handle_set_segment_filename";
7090
0
  int result                                = 0;
7091
7092
0
  if( handle == NULL )
7093
0
  {
7094
0
    libcerror_error_set(
7095
0
     error,
7096
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7097
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7098
0
     "%s: invalid handle.",
7099
0
     function );
7100
7101
0
    return( -1 );
7102
0
  }
7103
0
  internal_handle = (libewf_internal_handle_t *) handle;
7104
7105
0
  if( internal_handle->write_io_handle == NULL )
7106
0
  {
7107
0
    libcerror_error_set(
7108
0
     error,
7109
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7110
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7111
0
     "%s: segment filename cannot be changed.",
7112
0
     function );
7113
7114
0
    return( -1 );
7115
0
  }
7116
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7117
0
  if( libcthreads_read_write_lock_grab_for_write(
7118
0
       internal_handle->read_write_lock,
7119
0
       error ) != 1 )
7120
0
  {
7121
0
    libcerror_error_set(
7122
0
     error,
7123
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7124
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7125
0
     "%s: unable to grab read/write lock for writing.",
7126
0
     function );
7127
7128
0
    return( -1 );
7129
0
  }
7130
0
#endif
7131
0
  result = libewf_segment_table_set_basename(
7132
0
            internal_handle->segment_table,
7133
0
            filename,
7134
0
            filename_length,
7135
0
            error );
7136
7137
0
  if( result != 1 )
7138
0
  {
7139
0
    libcerror_error_set(
7140
0
     error,
7141
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7142
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7143
0
     "%s: unable to set segment table basename.",
7144
0
     function );
7145
0
  }
7146
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7147
0
  if( libcthreads_read_write_lock_release_for_write(
7148
0
       internal_handle->read_write_lock,
7149
0
       error ) != 1 )
7150
0
  {
7151
0
    libcerror_error_set(
7152
0
     error,
7153
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7154
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7155
0
     "%s: unable to release read/write lock for writing.",
7156
0
     function );
7157
7158
0
    return( -1 );
7159
0
  }
7160
0
#endif
7161
0
  return( result );
7162
0
}
7163
7164
#if defined( HAVE_WIDE_CHARACTER_TYPE )
7165
7166
/* Retrieves the segment filename size
7167
 * The filename size includes the end of string character
7168
 * Returns 1 if successful, 0 if not set or -1 on error
7169
 */
7170
int libewf_handle_get_segment_filename_size_wide(
7171
     libewf_handle_t *handle,
7172
     size_t *filename_size,
7173
     libcerror_error_t **error )
7174
{
7175
  libewf_internal_handle_t *internal_handle = NULL;
7176
  static char *function                     = "libewf_handle_get_segment_filename_size_wide";
7177
  int result                                = 0;
7178
7179
  if( handle == NULL )
7180
  {
7181
    libcerror_error_set(
7182
     error,
7183
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7184
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7185
     "%s: invalid handle.",
7186
     function );
7187
7188
    return( -1 );
7189
  }
7190
  internal_handle = (libewf_internal_handle_t *) handle;
7191
7192
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7193
  if( libcthreads_read_write_lock_grab_for_read(
7194
       internal_handle->read_write_lock,
7195
       error ) != 1 )
7196
  {
7197
    libcerror_error_set(
7198
     error,
7199
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7200
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7201
     "%s: unable to grab read/write lock for reading.",
7202
     function );
7203
7204
    return( -1 );
7205
  }
7206
#endif
7207
  result = libewf_segment_table_get_basename_size_wide(
7208
            internal_handle->segment_table,
7209
            filename_size,
7210
            error );
7211
7212
  if( result == -1 )
7213
  {
7214
    libcerror_error_set(
7215
     error,
7216
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7217
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7218
     "%s: unable to retrieve segment table basename size.",
7219
     function );
7220
  }
7221
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7222
  if( libcthreads_read_write_lock_release_for_read(
7223
       internal_handle->read_write_lock,
7224
       error ) != 1 )
7225
  {
7226
    libcerror_error_set(
7227
     error,
7228
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7229
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7230
     "%s: unable to release read/write lock for reading.",
7231
     function );
7232
7233
    return( -1 );
7234
  }
7235
#endif
7236
  return( result );
7237
}
7238
7239
/* Retrieves the segment filename
7240
 * The filename size should include the end of string character
7241
 * Returns 1 if successful, 0 if not set or -1 on error
7242
 */
7243
int libewf_handle_get_segment_filename_wide(
7244
     libewf_handle_t *handle,
7245
     wchar_t *filename,
7246
     size_t filename_size,
7247
     libcerror_error_t **error )
7248
{
7249
  libewf_internal_handle_t *internal_handle = NULL;
7250
  static char *function                     = "libewf_handle_get_segment_filename_wide";
7251
  int result                                = 0;
7252
7253
  if( handle == NULL )
7254
  {
7255
    libcerror_error_set(
7256
     error,
7257
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7258
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7259
     "%s: invalid handle.",
7260
     function );
7261
7262
    return( -1 );
7263
  }
7264
  internal_handle = (libewf_internal_handle_t *) handle;
7265
7266
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7267
  if( libcthreads_read_write_lock_grab_for_read(
7268
       internal_handle->read_write_lock,
7269
       error ) != 1 )
7270
  {
7271
    libcerror_error_set(
7272
     error,
7273
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7274
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7275
     "%s: unable to grab read/write lock for reading.",
7276
     function );
7277
7278
    return( -1 );
7279
  }
7280
#endif
7281
  result = libewf_segment_table_get_basename_wide(
7282
            internal_handle->segment_table,
7283
            filename,
7284
            filename_size,
7285
            error );
7286
7287
  if( result == -1 )
7288
  {
7289
    libcerror_error_set(
7290
     error,
7291
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7292
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7293
     "%s: unable to retrieve segment table basename.",
7294
     function );
7295
  }
7296
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7297
  if( libcthreads_read_write_lock_release_for_read(
7298
       internal_handle->read_write_lock,
7299
       error ) != 1 )
7300
  {
7301
    libcerror_error_set(
7302
     error,
7303
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7304
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7305
     "%s: unable to release read/write lock for reading.",
7306
     function );
7307
7308
    return( -1 );
7309
  }
7310
#endif
7311
  return( result );
7312
}
7313
7314
/* Sets the segment file
7315
 * Returns 1 if successful or -1 on error
7316
 */
7317
int libewf_handle_set_segment_filename_wide(
7318
     libewf_handle_t *handle,
7319
     const wchar_t *filename,
7320
     size_t filename_length,
7321
     libcerror_error_t **error )
7322
{
7323
  libewf_internal_handle_t *internal_handle = NULL;
7324
  static char *function                     = "libewf_handle_set_segment_filename_wide";
7325
  int result                                = 0;
7326
7327
  if( handle == NULL )
7328
  {
7329
    libcerror_error_set(
7330
     error,
7331
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7332
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7333
     "%s: invalid handle.",
7334
     function );
7335
7336
    return( -1 );
7337
  }
7338
  internal_handle = (libewf_internal_handle_t *) handle;
7339
7340
  if( internal_handle->write_io_handle == NULL )
7341
  {
7342
    libcerror_error_set(
7343
     error,
7344
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7345
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7346
     "%s: segment filename cannot be changed.",
7347
     function );
7348
7349
    return( -1 );
7350
  }
7351
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7352
  if( libcthreads_read_write_lock_grab_for_write(
7353
       internal_handle->read_write_lock,
7354
       error ) != 1 )
7355
  {
7356
    libcerror_error_set(
7357
     error,
7358
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7359
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7360
     "%s: unable to grab read/write lock for writing.",
7361
     function );
7362
7363
    return( -1 );
7364
  }
7365
#endif
7366
  result = libewf_segment_table_set_basename_wide(
7367
            internal_handle->segment_table,
7368
            filename,
7369
            filename_length,
7370
            error );
7371
7372
  if( result != 1 )
7373
  {
7374
    libcerror_error_set(
7375
     error,
7376
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7377
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7378
     "%s: unable to set segment table basename.",
7379
     function );
7380
  }
7381
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7382
  if( libcthreads_read_write_lock_release_for_write(
7383
       internal_handle->read_write_lock,
7384
       error ) != 1 )
7385
  {
7386
    libcerror_error_set(
7387
     error,
7388
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7389
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7390
     "%s: unable to release read/write lock for writing.",
7391
     function );
7392
7393
    return( -1 );
7394
  }
7395
#endif
7396
  return( result );
7397
}
7398
7399
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
7400
7401
/* Retrieves the maximum segment file size
7402
 * Returns 1 if successful or -1 on error
7403
 */
7404
int libewf_handle_get_maximum_segment_size(
7405
     libewf_handle_t *handle,
7406
     size64_t *maximum_segment_size,
7407
     libcerror_error_t **error )
7408
0
{
7409
0
  libewf_internal_handle_t *internal_handle = NULL;
7410
0
  static char *function                     = "libewf_handle_get_maximum_segment_size";
7411
7412
0
  if( handle == NULL )
7413
0
  {
7414
0
    libcerror_error_set(
7415
0
     error,
7416
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7417
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7418
0
     "%s: invalid handle.",
7419
0
     function );
7420
7421
0
    return( -1 );
7422
0
  }
7423
0
  internal_handle = (libewf_internal_handle_t *) handle;
7424
7425
0
  if( internal_handle->segment_table == NULL )
7426
0
  {
7427
0
    libcerror_error_set(
7428
0
     error,
7429
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7430
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7431
0
     "%s: invalid handle - missing segment table.",
7432
0
     function );
7433
7434
0
    return( -1 );
7435
0
  }
7436
0
  if( maximum_segment_size == NULL )
7437
0
  {
7438
0
    libcerror_error_set(
7439
0
     error,
7440
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7441
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7442
0
     "%s: invalid maximum segment size.",
7443
0
     function );
7444
7445
0
    return( -1 );
7446
0
  }
7447
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7448
0
  if( libcthreads_read_write_lock_grab_for_read(
7449
0
       internal_handle->read_write_lock,
7450
0
       error ) != 1 )
7451
0
  {
7452
0
    libcerror_error_set(
7453
0
     error,
7454
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7455
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7456
0
     "%s: unable to grab read/write lock for reading.",
7457
0
     function );
7458
7459
0
    return( -1 );
7460
0
  }
7461
0
#endif
7462
0
  *maximum_segment_size = internal_handle->segment_table->maximum_segment_size;
7463
7464
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7465
0
  if( libcthreads_read_write_lock_release_for_read(
7466
0
       internal_handle->read_write_lock,
7467
0
       error ) != 1 )
7468
0
  {
7469
0
    libcerror_error_set(
7470
0
     error,
7471
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7472
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7473
0
     "%s: unable to release read/write lock for reading.",
7474
0
     function );
7475
7476
0
    return( -1 );
7477
0
  }
7478
0
#endif
7479
0
  return( 1 );
7480
0
}
7481
7482
/* Sets the maximum segment file size
7483
 * A maximum segment file size of 0 represents the maximum possible size for the format
7484
 * If the maximum segment file size is smaller than the size needed to store a single chunk
7485
 * the size off the latter is enforced and not the maximum segment file size
7486
 * Returns 1 if successful or -1 on error
7487
 */
7488
int libewf_handle_set_maximum_segment_size(
7489
     libewf_handle_t *handle,
7490
     size64_t maximum_segment_size,
7491
     libcerror_error_t **error )
7492
0
{
7493
0
  libewf_internal_handle_t *internal_handle = NULL;
7494
0
  static char *function                     = "libewf_handle_set_maximum_segment_size";
7495
0
  int result                                = 1;
7496
7497
0
  if( handle == NULL )
7498
0
  {
7499
0
    libcerror_error_set(
7500
0
     error,
7501
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7502
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7503
0
     "%s: invalid handle.",
7504
0
     function );
7505
7506
0
    return( -1 );
7507
0
  }
7508
0
  internal_handle = (libewf_internal_handle_t *) handle;
7509
7510
0
  if( internal_handle->media_values == NULL )
7511
0
  {
7512
0
    libcerror_error_set(
7513
0
     error,
7514
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7515
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7516
0
     "%s: invalid handle - missing media values.",
7517
0
     function );
7518
7519
0
    return( -1 );
7520
0
  }
7521
0
  if( internal_handle->segment_table == NULL )
7522
0
  {
7523
0
    libcerror_error_set(
7524
0
     error,
7525
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7526
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7527
0
     "%s: invalid handle - missing segment table.",
7528
0
     function );
7529
7530
0
    return( -1 );
7531
0
  }
7532
0
  if( maximum_segment_size > (size64_t) INT64_MAX )
7533
0
  {
7534
0
    libcerror_error_set(
7535
0
     error,
7536
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7537
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
7538
0
     "%s: invalid maximum segment size value exceeds maximum.",
7539
0
     function );
7540
7541
0
    return( -1 );
7542
0
  }
7543
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7544
0
  if( libcthreads_read_write_lock_grab_for_write(
7545
0
       internal_handle->read_write_lock,
7546
0
       error ) != 1 )
7547
0
  {
7548
0
    libcerror_error_set(
7549
0
     error,
7550
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7551
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7552
0
     "%s: unable to grab read/write lock for writing.",
7553
0
     function );
7554
7555
0
    return( -1 );
7556
0
  }
7557
0
#endif
7558
0
  if( ( internal_handle->read_io_handle != NULL )
7559
0
   || ( internal_handle->write_io_handle == NULL )
7560
0
   || ( internal_handle->write_io_handle->values_initialized != 0 ) )
7561
0
  {
7562
0
    libcerror_error_set(
7563
0
     error,
7564
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7565
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7566
0
     "%s: maximum segment size cannot be changed.",
7567
0
     function );
7568
7569
0
    result = -1;
7570
0
  }
7571
0
  else if( maximum_segment_size > internal_handle->write_io_handle->maximum_segment_file_size )
7572
0
  {
7573
0
    libcerror_error_set(
7574
0
     error,
7575
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7576
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
7577
0
     "%s: invalid segment file size value out of bounds.",
7578
0
     function );
7579
7580
0
    result = -1;
7581
0
  }
7582
0
  else
7583
0
  {
7584
0
    internal_handle->segment_table->maximum_segment_size = maximum_segment_size;
7585
0
  }
7586
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7587
0
  if( libcthreads_read_write_lock_release_for_write(
7588
0
       internal_handle->read_write_lock,
7589
0
       error ) != 1 )
7590
0
  {
7591
0
    libcerror_error_set(
7592
0
     error,
7593
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7594
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7595
0
     "%s: unable to release read/write lock for writing.",
7596
0
     function );
7597
7598
0
    return( -1 );
7599
0
  }
7600
0
#endif
7601
0
  return( result );
7602
0
}
7603
7604
/* Retrieves the filename size of the segment file of the current chunk
7605
 * The filename size should include the end of string character
7606
 * Returns 1 if successful, 0 if no such filename or -1 on error
7607
 */
7608
int libewf_handle_get_filename_size(
7609
     libewf_handle_t *handle,
7610
     size_t *filename_size,
7611
     libcerror_error_t **error )
7612
0
{
7613
0
  libewf_internal_handle_t *internal_handle = NULL;
7614
0
  libbfio_handle_t *file_io_handle          = NULL;
7615
0
  static char *function                     = "libewf_handle_get_filename_size";
7616
0
  int result                                = 0;
7617
7618
0
  if( handle == NULL )
7619
0
  {
7620
0
    libcerror_error_set(
7621
0
     error,
7622
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7623
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7624
0
     "%s: invalid handle.",
7625
0
     function );
7626
7627
0
    return( -1 );
7628
0
  }
7629
0
  internal_handle = (libewf_internal_handle_t *) handle;
7630
7631
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7632
0
  if( libcthreads_read_write_lock_grab_for_read(
7633
0
       internal_handle->read_write_lock,
7634
0
       error ) != 1 )
7635
0
  {
7636
0
    libcerror_error_set(
7637
0
     error,
7638
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7639
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7640
0
     "%s: unable to grab read/write lock for reading.",
7641
0
     function );
7642
7643
0
    return( -1 );
7644
0
  }
7645
0
#endif
7646
0
  result = libewf_internal_handle_get_file_io_handle(
7647
0
            internal_handle,
7648
0
            &file_io_handle,
7649
0
            error );
7650
7651
0
  if( result == -1 )
7652
0
  {
7653
0
    libcerror_error_set(
7654
0
     error,
7655
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7656
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7657
0
     "%s: unable to retrieve file IO handle for current chunk.",
7658
0
     function );
7659
0
  }
7660
0
  else if( result != 0 )
7661
0
  {
7662
0
    result = libbfio_file_get_name_size(
7663
0
              file_io_handle,
7664
0
              filename_size,
7665
0
              error );
7666
7667
0
    if( result != 1 )
7668
0
    {
7669
0
      libcerror_error_set(
7670
0
       error,
7671
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7672
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7673
0
       "%s: unable to retrieve filename size.",
7674
0
       function );
7675
0
    }
7676
0
  }
7677
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7678
0
  if( libcthreads_read_write_lock_release_for_read(
7679
0
       internal_handle->read_write_lock,
7680
0
       error ) != 1 )
7681
0
  {
7682
0
    libcerror_error_set(
7683
0
     error,
7684
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7685
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7686
0
     "%s: unable to release read/write lock for reading.",
7687
0
     function );
7688
7689
0
    return( -1 );
7690
0
  }
7691
0
#endif
7692
0
  return( result );
7693
0
}
7694
7695
/* Retrieves the filename of the segment file of the current chunk
7696
 * The filename size should include the end of string character
7697
 * Returns 1 if successful, 0 if no such filename or -1 on error
7698
 */
7699
int libewf_handle_get_filename(
7700
     libewf_handle_t *handle,
7701
     char *filename,
7702
     size_t filename_size,
7703
     libcerror_error_t **error )
7704
0
{
7705
0
  libewf_internal_handle_t *internal_handle = NULL;
7706
0
  libbfio_handle_t *file_io_handle          = NULL;
7707
0
  static char *function                     = "libewf_handle_get_filename";
7708
0
  int result                                = 0;
7709
7710
0
  if( handle == NULL )
7711
0
  {
7712
0
    libcerror_error_set(
7713
0
     error,
7714
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7715
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7716
0
     "%s: invalid handle.",
7717
0
     function );
7718
7719
0
    return( -1 );
7720
0
  }
7721
0
  internal_handle = (libewf_internal_handle_t *) handle;
7722
7723
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7724
0
  if( libcthreads_read_write_lock_grab_for_read(
7725
0
       internal_handle->read_write_lock,
7726
0
       error ) != 1 )
7727
0
  {
7728
0
    libcerror_error_set(
7729
0
     error,
7730
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7731
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7732
0
     "%s: unable to grab read/write lock for reading.",
7733
0
     function );
7734
7735
0
    return( -1 );
7736
0
  }
7737
0
#endif
7738
0
  result = libewf_internal_handle_get_file_io_handle(
7739
0
            internal_handle,
7740
0
            &file_io_handle,
7741
0
            error );
7742
7743
0
  if( result == -1 )
7744
0
  {
7745
0
    libcerror_error_set(
7746
0
     error,
7747
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7748
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7749
0
     "%s: unable to retrieve file IO handle for current chunk.",
7750
0
     function );
7751
0
  }
7752
0
  else if( result != 0 )
7753
0
  {
7754
0
    result = libbfio_file_get_name(
7755
0
              file_io_handle,
7756
0
              filename,
7757
0
              filename_size,
7758
0
              error );
7759
7760
0
    if( result != 1 )
7761
0
    {
7762
0
      libcerror_error_set(
7763
0
       error,
7764
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7765
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7766
0
       "%s: unable to retrieve filename.",
7767
0
       function );
7768
0
    }
7769
0
  }
7770
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7771
0
  if( libcthreads_read_write_lock_release_for_read(
7772
0
       internal_handle->read_write_lock,
7773
0
       error ) != 1 )
7774
0
  {
7775
0
    libcerror_error_set(
7776
0
     error,
7777
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7778
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7779
0
     "%s: unable to release read/write lock for reading.",
7780
0
     function );
7781
7782
0
    return( -1 );
7783
0
  }
7784
0
#endif
7785
0
  return( result );
7786
0
}
7787
7788
#if defined( HAVE_WIDE_CHARACTER_TYPE )
7789
7790
/* Retrieves the filename size of the segment file of the current chunk
7791
 * The filename size includes the end of string character
7792
 * Returns 1 if successful, 0 if no such filename or -1 on error
7793
 */
7794
int libewf_handle_get_filename_size_wide(
7795
     libewf_handle_t *handle,
7796
     size_t *filename_size,
7797
     libcerror_error_t **error )
7798
{
7799
  libewf_internal_handle_t *internal_handle = NULL;
7800
  libbfio_handle_t *file_io_handle          = NULL;
7801
  static char *function                     = "libewf_handle_get_filename_size_wide";
7802
  int result                                = 0;
7803
7804
  if( handle == NULL )
7805
  {
7806
    libcerror_error_set(
7807
     error,
7808
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7809
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7810
     "%s: invalid handle.",
7811
     function );
7812
7813
    return( -1 );
7814
  }
7815
  internal_handle = (libewf_internal_handle_t *) handle;
7816
7817
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7818
  if( libcthreads_read_write_lock_grab_for_read(
7819
       internal_handle->read_write_lock,
7820
       error ) != 1 )
7821
  {
7822
    libcerror_error_set(
7823
     error,
7824
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7825
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7826
     "%s: unable to grab read/write lock for reading.",
7827
     function );
7828
7829
    return( -1 );
7830
  }
7831
#endif
7832
  result = libewf_internal_handle_get_file_io_handle(
7833
            internal_handle,
7834
            &file_io_handle,
7835
            error );
7836
7837
  if( result == -1 )
7838
  {
7839
    libcerror_error_set(
7840
     error,
7841
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7842
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7843
     "%s: unable to retrieve file IO handle for current chunk.",
7844
     function );
7845
  }
7846
  else if( result != 0 )
7847
  {
7848
    result = libbfio_file_get_name_size_wide(
7849
              file_io_handle,
7850
              filename_size,
7851
              error );
7852
7853
    if( result != 1 )
7854
    {
7855
      libcerror_error_set(
7856
       error,
7857
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7858
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7859
       "%s: unable to retrieve filename size.",
7860
       function );
7861
    }
7862
  }
7863
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7864
  if( libcthreads_read_write_lock_release_for_read(
7865
       internal_handle->read_write_lock,
7866
       error ) != 1 )
7867
  {
7868
    libcerror_error_set(
7869
     error,
7870
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7871
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7872
     "%s: unable to release read/write lock for reading.",
7873
     function );
7874
7875
    return( -1 );
7876
  }
7877
#endif
7878
  return( result );
7879
}
7880
7881
/* Retrieves the filename of the segment file of the current chunk
7882
 * The filename size should include the end of string character
7883
 * Returns 1 if successful, 0 if no such filename or -1 on error
7884
 */
7885
int libewf_handle_get_filename_wide(
7886
     libewf_handle_t *handle,
7887
     wchar_t *filename,
7888
     size_t filename_size,
7889
     libcerror_error_t **error )
7890
{
7891
  libewf_internal_handle_t *internal_handle = NULL;
7892
  libbfio_handle_t *file_io_handle          = NULL;
7893
  static char *function                     = "libewf_handle_get_filename_wide";
7894
  int result                                = 0;
7895
7896
  if( handle == NULL )
7897
  {
7898
    libcerror_error_set(
7899
     error,
7900
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7901
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7902
     "%s: invalid handle.",
7903
     function );
7904
7905
    return( -1 );
7906
  }
7907
  internal_handle = (libewf_internal_handle_t *) handle;
7908
7909
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7910
  if( libcthreads_read_write_lock_grab_for_read(
7911
       internal_handle->read_write_lock,
7912
       error ) != 1 )
7913
  {
7914
    libcerror_error_set(
7915
     error,
7916
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7917
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7918
     "%s: unable to grab read/write lock for reading.",
7919
     function );
7920
7921
    return( -1 );
7922
  }
7923
#endif
7924
  result = libewf_internal_handle_get_file_io_handle(
7925
            internal_handle,
7926
            &file_io_handle,
7927
            error );
7928
7929
  if( result == -1 )
7930
  {
7931
    libcerror_error_set(
7932
     error,
7933
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7934
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7935
     "%s: unable to retrieve file IO handle for current chunk.",
7936
     function );
7937
  }
7938
  else if( result != 0 )
7939
  {
7940
    result = libbfio_file_get_name_wide(
7941
              file_io_handle,
7942
              filename,
7943
              filename_size,
7944
              error );
7945
7946
    if( result != 1 )
7947
    {
7948
      libcerror_error_set(
7949
       error,
7950
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7951
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7952
       "%s: unable to retrieve filename.",
7953
       function );
7954
    }
7955
  }
7956
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
7957
  if( libcthreads_read_write_lock_release_for_read(
7958
       internal_handle->read_write_lock,
7959
       error ) != 1 )
7960
  {
7961
    libcerror_error_set(
7962
     error,
7963
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7964
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7965
     "%s: unable to release read/write lock for reading.",
7966
     function );
7967
7968
    return( -1 );
7969
  }
7970
#endif
7971
  return( result );
7972
}
7973
7974
#endif
7975
7976
/* Retrieves the file IO handle of the segment file of the current chunk
7977
 * This function is not multi-thread safe acquire write lock before call
7978
 * Returns 1 if successful, 0 if no such file IO handle or -1 on error
7979
 */
7980
int libewf_internal_handle_get_file_io_handle(
7981
     libewf_internal_handle_t *internal_handle,
7982
     libbfio_handle_t **file_io_handle,
7983
     libcerror_error_t **error )
7984
0
{
7985
0
  static char *function      = "libewf_internal_handle_get_file_io_handle";
7986
0
  size64_t segment_file_size = 0;
7987
0
  uint64_t chunk_index       = 0;
7988
0
  int file_io_pool_entry     = 0;
7989
0
  int result                 = 0;
7990
7991
0
  if( internal_handle == NULL )
7992
0
  {
7993
0
    libcerror_error_set(
7994
0
     error,
7995
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7996
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7997
0
     "%s: invalid handle.",
7998
0
     function );
7999
8000
0
    return( -1 );
8001
0
  }
8002
0
  if( internal_handle->io_handle == NULL )
8003
0
  {
8004
0
    libcerror_error_set(
8005
0
     error,
8006
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8007
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8008
0
     "%s: invalid handle - missing IO handle.",
8009
0
     function );
8010
8011
0
    return( -1 );
8012
0
  }
8013
0
  if( internal_handle->current_offset < 0 )
8014
0
  {
8015
0
    libcerror_error_set(
8016
0
     error,
8017
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8018
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
8019
0
     "%s: invalid handle - invalid IO handle - current offset value out of bounds.",
8020
0
     function );
8021
8022
0
    return( -1 );
8023
0
  }
8024
0
  if( internal_handle->media_values == NULL )
8025
0
  {
8026
0
    libcerror_error_set(
8027
0
     error,
8028
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8029
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8030
0
     "%s: invalid handle - missing media values.",
8031
0
     function );
8032
8033
0
    return( -1 );
8034
0
  }
8035
0
  if( internal_handle->media_values->chunk_size == 0 )
8036
0
  {
8037
0
    libcerror_error_set(
8038
0
     error,
8039
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8040
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8041
0
     "%s: invalid handle - invalid media values - missing chunk size.",
8042
0
     function );
8043
8044
0
    return( -1 );
8045
0
  }
8046
0
  chunk_index = internal_handle->current_offset / internal_handle->media_values->chunk_size;
8047
8048
0
  result = libewf_segment_table_get_segment_at_offset(
8049
0
            internal_handle->segment_table,
8050
0
            internal_handle->current_offset,
8051
0
            &file_io_pool_entry,
8052
0
            &segment_file_size,
8053
0
            error );
8054
8055
0
  if( result == -1 )
8056
0
  {
8057
0
    libcerror_error_set(
8058
0
     error,
8059
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8060
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8061
0
     "%s: unable to retrieve segment at offset: %" PRIi64 " (0x%08" PRIx64 ") from segment table.",
8062
0
     function,
8063
0
     internal_handle->current_offset,
8064
0
     internal_handle->current_offset );
8065
8066
0
    return( -1 );
8067
0
  }
8068
0
  else if( result != 0 )
8069
0
  {
8070
0
    if( file_io_pool_entry == -1 )
8071
0
    {
8072
0
      return( 0 );
8073
0
    }
8074
0
    if( libbfio_pool_get_handle(
8075
0
         internal_handle->file_io_pool,
8076
0
         file_io_pool_entry,
8077
0
         file_io_handle,
8078
0
         error ) != 1 )
8079
0
    {
8080
0
      libcerror_error_set(
8081
0
       error,
8082
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8083
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8084
0
       "%s: unable to retrieve file IO handle: %d from pool (chunk: %" PRIu64 ").",
8085
0
       function,
8086
0
       file_io_pool_entry,
8087
0
       chunk_index );
8088
8089
0
      return( -1 );
8090
0
    }
8091
0
  }
8092
0
  return( result );
8093
0
}
8094
8095
/* Retrieves the file IO handle of the segment file of the current chunk
8096
 * Returns 1 if successful, 0 if no such file IO handle or -1 on error
8097
 */
8098
int libewf_handle_get_file_io_handle(
8099
     libewf_handle_t *handle,
8100
     libbfio_handle_t **file_io_handle,
8101
     libcerror_error_t **error )
8102
0
{
8103
0
  libewf_internal_handle_t *internal_handle = NULL;
8104
0
  static char *function                     = "libewf_handle_get_file_io_handle";
8105
0
  int result                                = 0;
8106
8107
0
  if( handle == NULL )
8108
0
  {
8109
0
    libcerror_error_set(
8110
0
     error,
8111
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8112
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8113
0
     "%s: invalid handle.",
8114
0
     function );
8115
8116
0
    return( -1 );
8117
0
  }
8118
0
  internal_handle = (libewf_internal_handle_t *) handle;
8119
8120
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
8121
0
  if( libcthreads_read_write_lock_grab_for_read(
8122
0
       internal_handle->read_write_lock,
8123
0
       error ) != 1 )
8124
0
  {
8125
0
    libcerror_error_set(
8126
0
     error,
8127
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8128
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
8129
0
     "%s: unable to grab read/write lock for reading.",
8130
0
     function );
8131
8132
0
    return( -1 );
8133
0
  }
8134
0
#endif
8135
0
  result = libewf_internal_handle_get_file_io_handle(
8136
0
            internal_handle,
8137
0
            file_io_handle,
8138
0
            error );
8139
8140
0
  if( result == -1 )
8141
0
  {
8142
0
    libcerror_error_set(
8143
0
     error,
8144
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8145
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8146
0
     "%s: unable to retrieve file IO handle for current chunk.",
8147
0
     function );
8148
0
  }
8149
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
8150
0
  if( libcthreads_read_write_lock_release_for_read(
8151
0
       internal_handle->read_write_lock,
8152
0
       error ) != 1 )
8153
0
  {
8154
0
    libcerror_error_set(
8155
0
     error,
8156
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8157
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
8158
0
     "%s: unable to release read/write lock for reading.",
8159
0
     function );
8160
8161
0
    return( -1 );
8162
0
  }
8163
0
#endif
8164
0
  return( result );
8165
0
}
8166
8167
/* Retrieves the media values
8168
 * Returns 1 if successful or -1 on error
8169
 */
8170
int libewf_internal_handle_get_media_values(
8171
     libewf_internal_handle_t *internal_handle,
8172
     size64_t *media_size,
8173
     libcerror_error_t **error )
8174
1.16k
{
8175
1.16k
  libewf_chunk_data_t *chunk_data = NULL;
8176
1.16k
  static char *function           = "libewf_internal_handle_get_media_values";
8177
1.16k
  size64_t chunks_data_size       = 0;
8178
1.16k
  size64_t sector_data_size       = 0;
8179
1.16k
  size32_t chunk_size             = 0;
8180
1.16k
  off64_t chunk_data_offset       = 0;
8181
1.16k
  uint64_t chunk_index            = 0;
8182
8183
1.16k
  if( internal_handle == NULL )
8184
0
  {
8185
0
    libcerror_error_set(
8186
0
     error,
8187
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8188
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8189
0
     "%s: invalid handle.",
8190
0
     function );
8191
8192
0
    return( -1 );
8193
0
  }
8194
1.16k
  if( internal_handle->media_values == NULL )
8195
0
  {
8196
0
    libcerror_error_set(
8197
0
     error,
8198
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8199
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8200
0
     "%s: invalid handle - missing media values.",
8201
0
     function );
8202
8203
0
    return( -1 );
8204
0
  }
8205
1.16k
  if( media_size == NULL )
8206
0
  {
8207
0
    libcerror_error_set(
8208
0
     error,
8209
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8210
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8211
0
     "%s: invalid media size.",
8212
0
     function );
8213
8214
0
    return( -1 );
8215
0
  }
8216
1.16k
  sector_data_size = (size64_t) internal_handle->media_values->number_of_sectors * internal_handle->media_values->bytes_per_sector;
8217
8218
1.16k
  if( ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
8219
0
   && ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_RESUME ) == 0 ) )
8220
0
  {
8221
0
    chunk_size = (size32_t) internal_handle->media_values->sectors_per_chunk * internal_handle->media_values->bytes_per_sector;
8222
8223
0
    if( internal_handle->media_values->number_of_chunks > 0 )
8224
0
    {
8225
0
      internal_handle->current_offset = ( (off64_t) internal_handle->media_values->number_of_chunks - 1 ) * chunk_size;
8226
8227
0
      if( libewf_chunk_table_get_chunk_data_by_offset(
8228
0
           internal_handle->chunk_table,
8229
0
           internal_handle->io_handle,
8230
0
           internal_handle->file_io_pool,
8231
0
           internal_handle->media_values,
8232
0
           internal_handle->segment_table,
8233
0
           internal_handle->current_offset,
8234
0
           &chunk_data_offset,
8235
0
           &chunk_data,
8236
0
           error ) != 1 )
8237
0
      {
8238
0
        libcerror_error_set(
8239
0
         error,
8240
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
8241
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8242
0
         "%s: unable to retrieve chunk data for offset: %" PRIi64 " (0x%08" PRIx64 ").",
8243
0
         function,
8244
0
         internal_handle->current_offset,
8245
0
         internal_handle->current_offset );
8246
8247
0
        return( -1 );
8248
0
      }
8249
0
      if( chunk_data == NULL )
8250
0
      {
8251
0
        libcerror_error_set(
8252
0
         error,
8253
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
8254
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8255
0
         "%s: missing chunk data for offset: %" PRIi64 " (0x%08" PRIx64 ").",
8256
0
         function,
8257
0
         internal_handle->current_offset,
8258
0
         internal_handle->current_offset );
8259
8260
0
        return( -1 );
8261
0
      }
8262
      /* The only way to determine the size of the last compressed chunk is to unpack it
8263
       */
8264
0
      if( libewf_chunk_data_unpack(
8265
0
           chunk_data,
8266
0
           internal_handle->io_handle,
8267
0
           error ) != 1 )
8268
0
      {
8269
0
        libcerror_error_set(
8270
0
         error,
8271
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
8272
0
         LIBCERROR_RUNTIME_ERROR_GENERIC,
8273
0
         "%s: unable to unpack chunk: %" PRIu64 " data.",
8274
0
         function,
8275
0
         chunk_index );
8276
8277
0
        return( -1 );
8278
0
      }
8279
0
      chunks_data_size = chunk_index * chunk_size;
8280
8281
0
      if( ( chunk_data->range_flags & LIBEWF_RANGE_FLAG_IS_CORRUPTED ) == 0 )
8282
0
      {
8283
0
        chunks_data_size += chunk_data->data_size;
8284
0
      }
8285
0
      if( sector_data_size != chunks_data_size )
8286
0
      {
8287
#if defined( HAVE_VERBOSE_OUTPUT )
8288
        if( libcnotify_verbose != 0 )
8289
        {
8290
          libcnotify_printf(
8291
           "%s: mismatch of media data size in volume: %" PRIu64 " and chunk table: %" PRIu64 "\n",
8292
           function,
8293
           sector_data_size,
8294
           chunks_data_size );
8295
        }
8296
#endif
8297
0
        if( sector_data_size < chunks_data_size )
8298
0
        {
8299
0
          sector_data_size = chunks_data_size;
8300
0
        }
8301
0
      }
8302
0
    }
8303
0
  }
8304
1.16k
  *media_size = sector_data_size;
8305
8306
1.16k
  return( 1 );
8307
1.16k
}
8308
8309
/* Sets the media values
8310
 * Returns 1 if successful or -1 on error
8311
 */
8312
int libewf_internal_handle_set_media_values(
8313
     libewf_internal_handle_t *internal_handle,
8314
     uint32_t sectors_per_chunk,
8315
     uint32_t bytes_per_sector,
8316
     size64_t media_size,
8317
     libcerror_error_t **error )
8318
0
{
8319
0
  static char *function            = "libewf_internal_handle_set_media_values";
8320
0
  size32_t chunk_size              = 0;
8321
0
  size64_t maximum_input_file_size = 0;
8322
0
  uint64_t number_of_chunks        = 0;
8323
0
  uint64_t number_of_sectors       = 0;
8324
8325
0
  if( internal_handle == NULL )
8326
0
  {
8327
0
    libcerror_error_set(
8328
0
     error,
8329
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8330
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8331
0
     "%s: invalid handle.",
8332
0
     function );
8333
8334
0
    return( -1 );
8335
0
  }
8336
0
  if( internal_handle->media_values == NULL )
8337
0
  {
8338
0
    libcerror_error_set(
8339
0
     error,
8340
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8341
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8342
0
     "%s: invalid handle - missing media values.",
8343
0
     function );
8344
8345
0
    return( -1 );
8346
0
  }
8347
0
  if( ( sectors_per_chunk == 0 )
8348
0
   || ( sectors_per_chunk > (uint32_t) INT32_MAX ) )
8349
0
  {
8350
0
    libcerror_error_set(
8351
0
     error,
8352
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8353
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
8354
0
     "%s: invalid sectors per chunk.",
8355
0
     function );
8356
8357
0
    return( -1 );
8358
0
  }
8359
0
  if( ( bytes_per_sector == 0 )
8360
0
   || ( bytes_per_sector > (uint32_t) INT32_MAX ) )
8361
0
  {
8362
0
    libcerror_error_set(
8363
0
     error,
8364
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8365
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
8366
0
     "%s: invalid bytes per sector.",
8367
0
     function );
8368
8369
0
    return( -1 );
8370
0
  }
8371
0
  if( media_size > (size64_t) INT64_MAX )
8372
0
  {
8373
0
    libcerror_error_set(
8374
0
     error,
8375
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8376
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
8377
0
     "%s: invalid media size value exceeds maximum.",
8378
0
     function );
8379
8380
0
    return( -1 );
8381
0
  }
8382
  /* Determine the chunk size
8383
   */
8384
0
  chunk_size = sectors_per_chunk * bytes_per_sector;
8385
8386
0
  if( ( chunk_size == 0 )
8387
0
   || ( chunk_size > (size32_t) INT32_MAX ) )
8388
0
  {
8389
0
    libcerror_error_set(
8390
0
     error,
8391
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8392
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
8393
0
     "%s: invalid chunk size.",
8394
0
     function );
8395
8396
0
    return( -1 );
8397
0
  }
8398
  /* Check if the input file size does not exceed the maximum possible input file size
8399
   * for the chunk size
8400
   */
8401
0
  maximum_input_file_size = (size64_t) chunk_size * (size64_t) UINT32_MAX;
8402
8403
0
  if( media_size > maximum_input_file_size )
8404
0
  {
8405
0
    libcerror_error_set(
8406
0
     error,
8407
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8408
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
8409
0
     "%s: media size cannot be larger than size: %" PRIu64 " with a chunk size of: %" PRIu32 ".",
8410
0
     function,
8411
0
     maximum_input_file_size,
8412
0
     chunk_size );
8413
8414
0
    return( -1 );
8415
0
  }
8416
0
  internal_handle->media_values->sectors_per_chunk = sectors_per_chunk;
8417
0
  internal_handle->media_values->bytes_per_sector  = bytes_per_sector;
8418
0
  internal_handle->media_values->chunk_size        = chunk_size;
8419
0
  internal_handle->media_values->media_size        = media_size;
8420
8421
  /* If a media size was provided
8422
   */
8423
0
  if( media_size > 0 )
8424
0
  {
8425
    /* Determine the number of chunks to write
8426
     */
8427
0
    number_of_chunks = (uint64_t) media_size / (uint64_t) chunk_size;
8428
8429
0
    if( ( (uint64_t) media_size % (uint64_t) chunk_size ) != 0 )
8430
0
    {
8431
0
      number_of_chunks += 1;
8432
0
    }
8433
0
    if( number_of_chunks > (uint64_t) UINT32_MAX )
8434
0
    {
8435
0
      libcerror_error_set(
8436
0
       error,
8437
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8438
0
       LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
8439
0
       "%s: invalid number of chunks value exceeds maximum.",
8440
0
       function );
8441
8442
0
      return( -1 );
8443
0
    }
8444
0
    internal_handle->media_values->number_of_chunks = (uint64_t) number_of_chunks;
8445
8446
    /* Determine the number of sectors to write
8447
     */
8448
0
    number_of_sectors = (uint64_t) media_size / (uint64_t) bytes_per_sector;
8449
8450
0
    if( number_of_sectors > (uint64_t) INT64_MAX )
8451
0
    {
8452
0
      libcerror_error_set(
8453
0
       error,
8454
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8455
0
       LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
8456
0
       "%s: invalid number of sectors value exceeds maximum.",
8457
0
       function );
8458
8459
0
      return( -1 );
8460
0
    }
8461
0
    internal_handle->media_values->number_of_sectors = number_of_sectors;
8462
0
  }
8463
0
  return( 1 );
8464
0
}
8465
8466
/* Retrieves the root (single) file entry
8467
 * Returns 1 if successful, 0 if no file entries are present or -1 on error
8468
 */
8469
int libewf_handle_get_root_file_entry(
8470
     libewf_handle_t *handle,
8471
     libewf_file_entry_t **root_file_entry,
8472
     libcerror_error_t **error )
8473
0
{
8474
0
  libcdata_tree_node_t *root_node           = NULL;
8475
0
  libewf_internal_handle_t *internal_handle = NULL;
8476
0
  static char *function                     = "libewf_handle_get_root_file_entry";
8477
0
  int result                                = 0;
8478
8479
0
  if( handle == NULL )
8480
0
  {
8481
0
    libcerror_error_set(
8482
0
     error,
8483
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8484
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8485
0
     "%s: invalid handle.",
8486
0
     function );
8487
8488
0
    return( -1 );
8489
0
  }
8490
0
  internal_handle = (libewf_internal_handle_t *) handle;
8491
8492
0
  if( internal_handle->single_files == NULL )
8493
0
  {
8494
0
    libcerror_error_set(
8495
0
     error,
8496
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8497
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8498
0
     "%s: invalid handle - missing single files.",
8499
0
     function );
8500
8501
0
    return( -1 );
8502
0
  }
8503
0
  if( root_file_entry == NULL )
8504
0
  {
8505
0
    libcerror_error_set(
8506
0
     error,
8507
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8508
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8509
0
     "%s: invalid root file entry.",
8510
0
     function );
8511
8512
0
    return( -1 );
8513
0
  }
8514
0
  if( *root_file_entry != NULL )
8515
0
  {
8516
0
    libcerror_error_set(
8517
0
     error,
8518
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8519
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
8520
0
     "%s: root file entry value already set.",
8521
0
     function );
8522
8523
0
    return( -1 );
8524
0
  }
8525
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
8526
0
  if( libcthreads_read_write_lock_grab_for_read(
8527
0
       internal_handle->read_write_lock,
8528
0
       error ) != 1 )
8529
0
  {
8530
0
    libcerror_error_set(
8531
0
     error,
8532
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8533
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
8534
0
     "%s: unable to grab read/write lock for reading.",
8535
0
     function );
8536
8537
0
    return( -1 );
8538
0
  }
8539
0
#endif
8540
0
  if( libewf_single_files_get_file_entry_tree_root_node(
8541
0
       internal_handle->single_files,
8542
0
       &root_node,
8543
0
       error ) != 1 )
8544
0
  {
8545
0
    libcerror_error_set(
8546
0
     error,
8547
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8548
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8549
0
     "%s: unable to retrieve file entry tree root node.",
8550
0
     function );
8551
8552
0
    result = -1;
8553
0
  }
8554
0
  else if( root_node != NULL )
8555
0
  {
8556
0
    result = libewf_file_entry_initialize(
8557
0
              root_file_entry,
8558
0
              handle,
8559
0
              internal_handle->single_files,
8560
0
              root_node,
8561
0
              error );
8562
8563
0
    if( result != 1 )
8564
0
    {
8565
0
      libcerror_error_set(
8566
0
       error,
8567
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8568
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
8569
0
       "%s: unable to create root file entry.",
8570
0
       function );
8571
8572
0
      result = -1;
8573
0
    }
8574
0
  }
8575
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
8576
0
  if( libcthreads_read_write_lock_release_for_read(
8577
0
       internal_handle->read_write_lock,
8578
0
       error ) != 1 )
8579
0
  {
8580
0
    libcerror_error_set(
8581
0
     error,
8582
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8583
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
8584
0
     "%s: unable to release read/write lock for reading.",
8585
0
     function );
8586
8587
0
    return( -1 );
8588
0
  }
8589
0
#endif
8590
0
  return( result );
8591
0
}
8592
8593
/* Retrieves the (single) file entry for the specific UTF-8 encoded path
8594
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
8595
 * The path separator is defined by LIBEWF_SEPARATOR
8596
 * This function is not multi-thread safe acquire write lock before call
8597
 * Returns 1 if successful, 0 if no such file entry or -1 on error
8598
 */
8599
int libewf_internal_handle_get_file_entry_by_utf8_path(
8600
     libewf_internal_handle_t *internal_handle,
8601
     const uint8_t *utf8_string,
8602
     size_t utf8_string_length,
8603
     libewf_file_entry_t **file_entry,
8604
     libcerror_error_t **error )
8605
0
{
8606
0
  libcdata_tree_node_t *node                  = NULL;
8607
0
  libcdata_tree_node_t *root_node             = NULL;
8608
0
  libcdata_tree_node_t *sub_node              = NULL;
8609
0
  libewf_lef_file_entry_t *lef_file_entry     = NULL;
8610
0
  libewf_lef_file_entry_t *sub_lef_file_entry = NULL;
8611
0
  uint8_t *utf8_string_segment                = NULL;
8612
0
  static char *function                       = "libewf_internal_handle_get_file_entry_by_utf8_path";
8613
0
  size_t utf8_string_index                    = 0;
8614
0
  size_t utf8_string_segment_length           = 0;
8615
0
  int result                                  = 0;
8616
8617
0
  if( internal_handle == NULL )
8618
0
  {
8619
0
    libcerror_error_set(
8620
0
     error,
8621
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8622
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8623
0
     "%s: invalid handle.",
8624
0
     function );
8625
8626
0
    return( -1 );
8627
0
  }
8628
0
  if( internal_handle->single_files == NULL )
8629
0
  {
8630
0
    libcerror_error_set(
8631
0
     error,
8632
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8633
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8634
0
     "%s: invalid handle - missing single files.",
8635
0
     function );
8636
8637
0
    return( -1 );
8638
0
  }
8639
0
  if( utf8_string == NULL )
8640
0
  {
8641
0
    libcerror_error_set(
8642
0
     error,
8643
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8644
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8645
0
     "%s: invalid UTF-8 string.",
8646
0
     function );
8647
8648
0
    return( -1 );
8649
0
  }
8650
0
  if( utf8_string_length > (size_t) SSIZE_MAX )
8651
0
  {
8652
0
    libcerror_error_set(
8653
0
     error,
8654
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8655
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
8656
0
     "%s: invalid UTF-8 string length value exceeds maximum.",
8657
0
     function );
8658
8659
0
    return( -1 );
8660
0
  }
8661
0
  if( file_entry == NULL )
8662
0
  {
8663
0
    libcerror_error_set(
8664
0
     error,
8665
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8666
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8667
0
     "%s: invalid file entry.",
8668
0
     function );
8669
8670
0
    return( -1 );
8671
0
  }
8672
0
  if( *file_entry != NULL )
8673
0
  {
8674
0
    libcerror_error_set(
8675
0
     error,
8676
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8677
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
8678
0
     "%s: file entry value already set.",
8679
0
     function );
8680
8681
0
    return( -1 );
8682
0
  }
8683
0
  if( libewf_single_files_get_file_entry_tree_root_node(
8684
0
       internal_handle->single_files,
8685
0
       &root_node,
8686
0
       error ) != 1 )
8687
0
  {
8688
0
    libcerror_error_set(
8689
0
     error,
8690
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8691
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8692
0
     "%s: unable to retrieve file entry tree root node.",
8693
0
     function );
8694
8695
0
    result = -1;
8696
0
  }
8697
0
  else if( root_node == NULL )
8698
0
  {
8699
0
    return( 0 );
8700
0
  }
8701
0
  if( libcdata_tree_node_get_value(
8702
0
       root_node,
8703
0
       (intptr_t **) &lef_file_entry,
8704
0
       error ) != 1 )
8705
0
  {
8706
0
    libcerror_error_set(
8707
0
     error,
8708
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8709
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8710
0
     "%s: unable to retrieve value from root file entry node.",
8711
0
     function );
8712
8713
0
    return( -1 );
8714
0
  }
8715
0
  if( lef_file_entry == NULL )
8716
0
  {
8717
0
    libcerror_error_set(
8718
0
     error,
8719
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8720
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8721
0
     "%s: missing root file entry values.",
8722
0
     function );
8723
8724
0
    return( -1 );
8725
0
  }
8726
0
  if( utf8_string_length > 0 )
8727
0
  {
8728
    /* Ignore a leading separator
8729
     */
8730
0
    if( utf8_string[ utf8_string_index ] == (uint8_t) LIBEWF_SEPARATOR )
8731
0
    {
8732
0
      utf8_string_index++;
8733
0
    }
8734
0
  }
8735
0
  node = root_node;
8736
8737
0
  if( ( utf8_string_length == 0 )
8738
0
   || ( utf8_string_length == 1 ) )
8739
0
  {
8740
0
    result = 1;
8741
0
  }
8742
0
  else while( utf8_string_index < utf8_string_length )
8743
0
  {
8744
0
    utf8_string_segment        = (uint8_t *) &( utf8_string[ utf8_string_index ] );
8745
0
    utf8_string_segment_length = 0;
8746
8747
0
    while( utf8_string_index < utf8_string_length )
8748
0
    {
8749
0
      if( ( utf8_string[ utf8_string_index ] == (uint8_t) LIBEWF_SEPARATOR )
8750
0
       || ( utf8_string[ utf8_string_index ] == (uint8_t) 0 ) )
8751
0
      {
8752
0
        utf8_string_index++;
8753
8754
0
        break;
8755
0
      }
8756
0
      utf8_string_index++;
8757
8758
0
      utf8_string_segment_length++;
8759
0
    }
8760
0
    if( utf8_string_segment_length == 0 )
8761
0
    {
8762
0
      libcerror_error_set(
8763
0
       error,
8764
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8765
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8766
0
       "%s: missing sub file entry name.",
8767
0
       function );
8768
8769
0
      return( -1 );
8770
0
    }
8771
0
    result = libewf_single_file_tree_get_sub_node_by_utf8_name(
8772
0
        node,
8773
0
        utf8_string_segment,
8774
0
        utf8_string_segment_length,
8775
0
        &sub_node,
8776
0
        &sub_lef_file_entry,
8777
0
        error );
8778
8779
0
    if( result == -1 )
8780
0
    {
8781
0
      libcerror_error_set(
8782
0
       error,
8783
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8784
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8785
0
       "%s: unable to retrieve file entry sub node by name.",
8786
0
       function );
8787
8788
0
      return( -1 );
8789
0
    }
8790
0
    else if( result == 0 )
8791
0
    {
8792
0
      break;
8793
0
    }
8794
0
    node = sub_node;
8795
0
  }
8796
0
  if( result != 0 )
8797
0
  {
8798
0
    if( libewf_file_entry_initialize(
8799
0
         file_entry,
8800
0
         (libewf_handle_t *) internal_handle,
8801
0
         internal_handle->single_files,
8802
0
         node,
8803
0
         error ) != 1 )
8804
0
    {
8805
0
      libcerror_error_set(
8806
0
       error,
8807
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
8808
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
8809
0
       "%s: unable to create file entry.",
8810
0
       function );
8811
8812
0
      return( -1 );
8813
0
    }
8814
0
  }
8815
0
  return( result );
8816
0
}
8817
8818
/* Retrieves the (single) file entry for the specific UTF-8 encoded path
8819
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
8820
 * The path separator is defined by LIBEWF_SEPARATOR
8821
 * Returns 1 if successful, 0 if no such file entry or -1 on error
8822
 */
8823
int libewf_handle_get_file_entry_by_utf8_path(
8824
     libewf_handle_t *handle,
8825
     const uint8_t *utf8_string,
8826
     size_t utf8_string_length,
8827
     libewf_file_entry_t **file_entry,
8828
     libcerror_error_t **error )
8829
0
{
8830
0
  libewf_internal_handle_t *internal_handle = NULL;
8831
0
  static char *function                     = "libewf_handle_get_file_entry_by_utf8_path";
8832
0
  int result                                = 0;
8833
8834
0
  if( handle == NULL )
8835
0
  {
8836
0
    libcerror_error_set(
8837
0
     error,
8838
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8839
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8840
0
     "%s: invalid handle.",
8841
0
     function );
8842
8843
0
    return( -1 );
8844
0
  }
8845
0
  internal_handle = (libewf_internal_handle_t *) handle;
8846
8847
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
8848
0
  if( libcthreads_read_write_lock_grab_for_read(
8849
0
       internal_handle->read_write_lock,
8850
0
       error ) != 1 )
8851
0
  {
8852
0
    libcerror_error_set(
8853
0
     error,
8854
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8855
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
8856
0
     "%s: unable to grab read/write lock for reading.",
8857
0
     function );
8858
8859
0
    return( -1 );
8860
0
  }
8861
0
#endif
8862
0
  result = libewf_internal_handle_get_file_entry_by_utf8_path(
8863
0
            internal_handle,
8864
0
            utf8_string,
8865
0
            utf8_string_length,
8866
0
            file_entry,
8867
0
            error );
8868
8869
0
  if( result == -1 )
8870
0
  {
8871
0
    libcerror_error_set(
8872
0
     error,
8873
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8874
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8875
0
     "%s: unable to retrieve file entry by UTF-8 path.",
8876
0
     function );
8877
0
  }
8878
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
8879
0
  if( libcthreads_read_write_lock_release_for_read(
8880
0
       internal_handle->read_write_lock,
8881
0
       error ) != 1 )
8882
0
  {
8883
0
    libcerror_error_set(
8884
0
     error,
8885
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8886
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
8887
0
     "%s: unable to release read/write lock for reading.",
8888
0
     function );
8889
8890
0
    return( -1 );
8891
0
  }
8892
0
#endif
8893
0
  return( result );
8894
0
}
8895
8896
/* Retrieves the (single) file entry for the specific UTF-16 encoded path
8897
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
8898
 * The path separator is defined by LIBEWF_SEPARATOR
8899
 * This function is not multi-thread safe acquire write lock before call
8900
 * Returns 1 if successful, 0 if no such file entry or -1 on error
8901
 */
8902
int libewf_internal_handle_get_file_entry_by_utf16_path(
8903
     libewf_internal_handle_t *internal_handle,
8904
     const uint16_t *utf16_string,
8905
     size_t utf16_string_length,
8906
     libewf_file_entry_t **file_entry,
8907
     libcerror_error_t **error )
8908
0
{
8909
0
  libcdata_tree_node_t *node                  = NULL;
8910
0
  libcdata_tree_node_t *root_node             = NULL;
8911
0
  libcdata_tree_node_t *sub_node              = NULL;
8912
0
  libewf_lef_file_entry_t *lef_file_entry     = NULL;
8913
0
  libewf_lef_file_entry_t *sub_lef_file_entry = NULL;
8914
0
  uint16_t *utf16_string_segment              = NULL;
8915
0
  static char *function                       = "libewf_internal_handle_get_file_entry_by_utf16_path";
8916
0
  size_t utf16_string_index                   = 0;
8917
0
  size_t utf16_string_segment_length          = 0;
8918
0
  int result                                  = 0;
8919
8920
0
  if( internal_handle == NULL )
8921
0
  {
8922
0
    libcerror_error_set(
8923
0
     error,
8924
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8925
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8926
0
     "%s: invalid handle.",
8927
0
     function );
8928
8929
0
    return( -1 );
8930
0
  }
8931
0
  if( internal_handle->single_files == NULL )
8932
0
  {
8933
0
    libcerror_error_set(
8934
0
     error,
8935
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8936
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8937
0
     "%s: invalid handle - missing single files.",
8938
0
     function );
8939
8940
0
    return( -1 );
8941
0
  }
8942
0
  if( utf16_string == NULL )
8943
0
  {
8944
0
    libcerror_error_set(
8945
0
     error,
8946
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8947
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8948
0
     "%s: invalid UTF-16 string.",
8949
0
     function );
8950
8951
0
    return( -1 );
8952
0
  }
8953
0
  if( utf16_string_length > (size_t) SSIZE_MAX )
8954
0
  {
8955
0
    libcerror_error_set(
8956
0
     error,
8957
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8958
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
8959
0
     "%s: invalid UTF-16 string length value exceeds maximum.",
8960
0
     function );
8961
8962
0
    return( -1 );
8963
0
  }
8964
0
  if( file_entry == NULL )
8965
0
  {
8966
0
    libcerror_error_set(
8967
0
     error,
8968
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8969
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8970
0
     "%s: invalid file entry.",
8971
0
     function );
8972
8973
0
    return( -1 );
8974
0
  }
8975
0
  if( *file_entry != NULL )
8976
0
  {
8977
0
    libcerror_error_set(
8978
0
     error,
8979
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8980
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
8981
0
     "%s: file entry value already set.",
8982
0
     function );
8983
8984
0
    return( -1 );
8985
0
  }
8986
0
  if( libewf_single_files_get_file_entry_tree_root_node(
8987
0
       internal_handle->single_files,
8988
0
       &root_node,
8989
0
       error ) != 1 )
8990
0
  {
8991
0
    libcerror_error_set(
8992
0
     error,
8993
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
8994
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8995
0
     "%s: unable to retrieve file entry tree root node.",
8996
0
     function );
8997
8998
0
    result = -1;
8999
0
  }
9000
0
  else if( root_node == NULL )
9001
0
  {
9002
0
    return( 0 );
9003
0
  }
9004
0
  if( libcdata_tree_node_get_value(
9005
0
       root_node,
9006
0
       (intptr_t **) &lef_file_entry,
9007
0
       error ) != 1 )
9008
0
  {
9009
0
    libcerror_error_set(
9010
0
     error,
9011
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9012
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
9013
0
     "%s: unable to retrieve value from root file entry node.",
9014
0
     function );
9015
9016
0
    return( -1 );
9017
0
  }
9018
0
  if( lef_file_entry == NULL )
9019
0
  {
9020
0
    libcerror_error_set(
9021
0
     error,
9022
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9023
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9024
0
     "%s: missing root file entry values.",
9025
0
     function );
9026
9027
0
    return( -1 );
9028
0
  }
9029
0
  if( utf16_string_length > 0 )
9030
0
  {
9031
    /* Ignore a leading separator
9032
     */
9033
0
    if( utf16_string[ utf16_string_index ] == (uint16_t) LIBEWF_SEPARATOR )
9034
0
    {
9035
0
      utf16_string_index++;
9036
0
    }
9037
0
  }
9038
0
  node = root_node;
9039
9040
0
  if( ( utf16_string_length == 0 )
9041
0
   || ( utf16_string_length == 1 ) )
9042
0
  {
9043
0
    result = 1;
9044
0
  }
9045
0
  else while( utf16_string_index < utf16_string_length )
9046
0
  {
9047
0
    utf16_string_segment        = (uint16_t *) &( utf16_string[ utf16_string_index ] );
9048
0
    utf16_string_segment_length = 0;
9049
9050
0
    while( utf16_string_index < utf16_string_length )
9051
0
    {
9052
0
      if( ( utf16_string[ utf16_string_index ] == (uint16_t) LIBEWF_SEPARATOR )
9053
0
       || ( utf16_string[ utf16_string_index ] == (uint16_t) 0 ) )
9054
0
      {
9055
0
        utf16_string_index++;
9056
9057
0
        break;
9058
0
      }
9059
0
      utf16_string_index++;
9060
9061
0
      utf16_string_segment_length++;
9062
0
    }
9063
0
    if( utf16_string_segment_length == 0 )
9064
0
    {
9065
0
      libcerror_error_set(
9066
0
       error,
9067
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
9068
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9069
0
       "%s: missing sub file entry name.",
9070
0
       function );
9071
9072
0
      return( -1 );
9073
0
    }
9074
0
    result = libewf_single_file_tree_get_sub_node_by_utf16_name(
9075
0
        node,
9076
0
        utf16_string_segment,
9077
0
        utf16_string_segment_length,
9078
0
        &sub_node,
9079
0
        &sub_lef_file_entry,
9080
0
        error );
9081
9082
0
    if( result == -1 )
9083
0
    {
9084
0
      libcerror_error_set(
9085
0
       error,
9086
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
9087
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
9088
0
       "%s: unable to retrieve file entry sub node by name.",
9089
0
       function );
9090
9091
0
      return( -1 );
9092
0
    }
9093
0
    else if( result == 0 )
9094
0
    {
9095
0
      break;
9096
0
    }
9097
0
    node = sub_node;
9098
0
  }
9099
0
  if( result != 0 )
9100
0
  {
9101
0
    if( libewf_file_entry_initialize(
9102
0
         file_entry,
9103
0
         (libewf_handle_t *) internal_handle,
9104
0
         internal_handle->single_files,
9105
0
         node,
9106
0
         error ) != 1 )
9107
0
    {
9108
0
      libcerror_error_set(
9109
0
       error,
9110
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
9111
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
9112
0
       "%s: unable to create file entry.",
9113
0
       function );
9114
9115
0
      return( -1 );
9116
0
    }
9117
0
  }
9118
0
  return( result );
9119
0
}
9120
9121
/* Retrieves the (single) file entry for the specific UTF-16 encoded path
9122
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
9123
 * The path separator is defined by LIBEWF_SEPARATOR
9124
 * Returns 1 if successful, 0 if no such file entry or -1 on error
9125
 */
9126
int libewf_handle_get_file_entry_by_utf16_path(
9127
     libewf_handle_t *handle,
9128
     const uint16_t *utf16_string,
9129
     size_t utf16_string_length,
9130
     libewf_file_entry_t **file_entry,
9131
     libcerror_error_t **error )
9132
0
{
9133
0
  libewf_internal_handle_t *internal_handle = NULL;
9134
0
  static char *function                     = "libewf_handle_get_file_entry_by_utf16_path";
9135
0
  int result                                = 0;
9136
9137
0
  if( handle == NULL )
9138
0
  {
9139
0
    libcerror_error_set(
9140
0
     error,
9141
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9142
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9143
0
     "%s: invalid handle.",
9144
0
     function );
9145
9146
0
    return( -1 );
9147
0
  }
9148
0
  internal_handle = (libewf_internal_handle_t *) handle;
9149
9150
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9151
0
  if( libcthreads_read_write_lock_grab_for_read(
9152
0
       internal_handle->read_write_lock,
9153
0
       error ) != 1 )
9154
0
  {
9155
0
    libcerror_error_set(
9156
0
     error,
9157
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9158
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9159
0
     "%s: unable to grab read/write lock for reading.",
9160
0
     function );
9161
9162
0
    return( -1 );
9163
0
  }
9164
0
#endif
9165
0
  result = libewf_internal_handle_get_file_entry_by_utf16_path(
9166
0
            internal_handle,
9167
0
            utf16_string,
9168
0
            utf16_string_length,
9169
0
            file_entry,
9170
0
            error );
9171
9172
0
  if( result == -1 )
9173
0
  {
9174
0
    libcerror_error_set(
9175
0
     error,
9176
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9177
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
9178
0
     "%s: unable to retrieve file entry by UTF-16 path.",
9179
0
     function );
9180
0
  }
9181
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9182
0
  if( libcthreads_read_write_lock_release_for_read(
9183
0
       internal_handle->read_write_lock,
9184
0
       error ) != 1 )
9185
0
  {
9186
0
    libcerror_error_set(
9187
0
     error,
9188
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9189
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9190
0
     "%s: unable to release read/write lock for reading.",
9191
0
     function );
9192
9193
0
    return( -1 );
9194
0
  }
9195
0
#endif
9196
0
  return( result );
9197
0
}
9198
9199
/* Retrieves the number of sectors per chunk
9200
 * Returns 1 if successful or -1 on error
9201
 */
9202
int libewf_handle_get_sectors_per_chunk(
9203
     libewf_handle_t *handle,
9204
     uint32_t *sectors_per_chunk,
9205
     libcerror_error_t **error )
9206
1.16k
{
9207
1.16k
  libewf_internal_handle_t *internal_handle = NULL;
9208
1.16k
  static char *function                     = "libewf_handle_get_sectors_per_chunk";
9209
9210
1.16k
  if( handle == NULL )
9211
0
  {
9212
0
    libcerror_error_set(
9213
0
     error,
9214
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9215
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9216
0
     "%s: invalid handle.",
9217
0
     function );
9218
9219
0
    return( -1 );
9220
0
  }
9221
1.16k
  internal_handle = (libewf_internal_handle_t *) handle;
9222
9223
1.16k
  if( internal_handle->media_values == NULL )
9224
0
  {
9225
0
    libcerror_error_set(
9226
0
     error,
9227
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9228
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9229
0
     "%s: invalid handle - missing media values.",
9230
0
     function );
9231
9232
0
    return( -1 );
9233
0
  }
9234
1.16k
  if( sectors_per_chunk == NULL )
9235
0
  {
9236
0
    libcerror_error_set(
9237
0
     error,
9238
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9239
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9240
0
     "%s: invalid sectors per chunk.",
9241
0
     function );
9242
9243
0
    return( -1 );
9244
0
  }
9245
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9246
1.16k
  if( libcthreads_read_write_lock_grab_for_read(
9247
1.16k
       internal_handle->read_write_lock,
9248
1.16k
       error ) != 1 )
9249
0
  {
9250
0
    libcerror_error_set(
9251
0
     error,
9252
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9253
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9254
0
     "%s: unable to grab read/write lock for reading.",
9255
0
     function );
9256
9257
0
    return( -1 );
9258
0
  }
9259
1.16k
#endif
9260
1.16k
  if( internal_handle->media_values->sectors_per_chunk > (uint32_t) INT32_MAX )
9261
0
  {
9262
0
    libcerror_error_set(
9263
0
     error,
9264
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9265
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
9266
0
     "%s: invalid sectors per chunk value exceeds maximum.",
9267
0
     function );
9268
9269
0
    goto on_error;
9270
0
  }
9271
1.16k
  *sectors_per_chunk = internal_handle->media_values->sectors_per_chunk;
9272
9273
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9274
1.16k
  if( libcthreads_read_write_lock_release_for_read(
9275
1.16k
       internal_handle->read_write_lock,
9276
1.16k
       error ) != 1 )
9277
0
  {
9278
0
    libcerror_error_set(
9279
0
     error,
9280
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9281
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9282
0
     "%s: unable to release read/write lock for reading.",
9283
0
     function );
9284
9285
0
    return( -1 );
9286
0
  }
9287
1.16k
#endif
9288
1.16k
  return( 1 );
9289
9290
0
on_error:
9291
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9292
0
  libcthreads_read_write_lock_release_for_read(
9293
0
   internal_handle->read_write_lock,
9294
0
   NULL );
9295
0
#endif
9296
0
  return( -1 );
9297
1.16k
}
9298
9299
/* Sets the number of sectors per chunk
9300
 * Returns 1 if successful or -1 on error
9301
 */
9302
int libewf_handle_set_sectors_per_chunk(
9303
     libewf_handle_t *handle,
9304
     uint32_t sectors_per_chunk,
9305
     libcerror_error_t **error )
9306
0
{
9307
0
  libewf_internal_handle_t *internal_handle = NULL;
9308
0
  static char *function                     = "libewf_handle_set_sectors_per_chunk";
9309
9310
0
  if( handle == NULL )
9311
0
  {
9312
0
    libcerror_error_set(
9313
0
     error,
9314
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9315
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9316
0
     "%s: invalid handle.",
9317
0
     function );
9318
9319
0
    return( -1 );
9320
0
  }
9321
0
  internal_handle = (libewf_internal_handle_t *) handle;
9322
9323
0
  if( internal_handle->media_values == NULL )
9324
0
  {
9325
0
    libcerror_error_set(
9326
0
     error,
9327
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9328
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9329
0
     "%s: invalid handle - missing media values.",
9330
0
     function );
9331
9332
0
    return( -1 );
9333
0
  }
9334
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9335
0
  if( libcthreads_read_write_lock_grab_for_write(
9336
0
       internal_handle->read_write_lock,
9337
0
       error ) != 1 )
9338
0
  {
9339
0
    libcerror_error_set(
9340
0
     error,
9341
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9342
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9343
0
     "%s: unable to grab read/write lock for writing.",
9344
0
     function );
9345
9346
0
    return( -1 );
9347
0
  }
9348
0
#endif
9349
0
  if( ( internal_handle->read_io_handle != NULL )
9350
0
   || ( internal_handle->write_io_handle == NULL )
9351
0
   || ( internal_handle->write_io_handle->values_initialized != 0 ) )
9352
0
  {
9353
0
    libcerror_error_set(
9354
0
     error,
9355
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9356
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9357
0
     "%s: sectors per chunk cannot be changed.",
9358
0
     function );
9359
9360
0
    goto on_error;
9361
0
  }
9362
0
  if( libewf_internal_handle_set_media_values(
9363
0
       internal_handle,
9364
0
       sectors_per_chunk,
9365
0
       internal_handle->media_values->bytes_per_sector,
9366
0
       internal_handle->media_values->media_size,
9367
0
       error ) != 1 )
9368
0
  {
9369
0
    libcerror_error_set(
9370
0
     error,
9371
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9372
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9373
0
     "%s: unable to set media values.",
9374
0
     function );
9375
9376
0
    goto on_error;
9377
0
  }
9378
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9379
0
  if( libcthreads_read_write_lock_release_for_write(
9380
0
       internal_handle->read_write_lock,
9381
0
       error ) != 1 )
9382
0
  {
9383
0
    libcerror_error_set(
9384
0
     error,
9385
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9386
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9387
0
     "%s: unable to release read/write lock for writing.",
9388
0
     function );
9389
9390
0
    return( -1 );
9391
0
  }
9392
0
#endif
9393
0
  return( 1 );
9394
9395
0
on_error:
9396
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9397
0
  libcthreads_read_write_lock_release_for_write(
9398
0
   internal_handle->read_write_lock,
9399
0
   NULL );
9400
0
#endif
9401
0
  return( -1 );
9402
0
}
9403
9404
/* Retrieves the number of bytes per sector
9405
 * Returns 1 if successful or -1 on error
9406
 */
9407
int libewf_handle_get_bytes_per_sector(
9408
     libewf_handle_t *handle,
9409
     uint32_t *bytes_per_sector,
9410
     libcerror_error_t **error )
9411
1.16k
{
9412
1.16k
  libewf_internal_handle_t *internal_handle = NULL;
9413
1.16k
  static char *function                     = "libewf_handle_get_bytes_per_sector";
9414
9415
1.16k
  if( handle == NULL )
9416
0
  {
9417
0
    libcerror_error_set(
9418
0
     error,
9419
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9420
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9421
0
     "%s: invalid handle.",
9422
0
     function );
9423
9424
0
    return( -1 );
9425
0
  }
9426
1.16k
  internal_handle = (libewf_internal_handle_t *) handle;
9427
9428
1.16k
  if( internal_handle->media_values == NULL )
9429
0
  {
9430
0
    libcerror_error_set(
9431
0
     error,
9432
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9433
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9434
0
     "%s: invalid handle - missing media values.",
9435
0
     function );
9436
9437
0
    return( -1 );
9438
0
  }
9439
1.16k
  if( bytes_per_sector == NULL )
9440
0
  {
9441
0
    libcerror_error_set(
9442
0
     error,
9443
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9444
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9445
0
     "%s: invalid bytes per sector.",
9446
0
     function );
9447
9448
0
    return( -1 );
9449
0
  }
9450
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9451
1.16k
  if( libcthreads_read_write_lock_grab_for_read(
9452
1.16k
       internal_handle->read_write_lock,
9453
1.16k
       error ) != 1 )
9454
0
  {
9455
0
    libcerror_error_set(
9456
0
     error,
9457
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9458
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9459
0
     "%s: unable to grab read/write lock for reading.",
9460
0
     function );
9461
9462
0
    return( -1 );
9463
0
  }
9464
1.16k
#endif
9465
1.16k
  if( internal_handle->media_values->bytes_per_sector > (uint32_t) INT32_MAX )
9466
0
  {
9467
0
    libcerror_error_set(
9468
0
     error,
9469
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9470
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
9471
0
     "%s: invalid bytes per sector value exceeds maximum.",
9472
0
     function );
9473
9474
0
    goto on_error;
9475
0
  }
9476
1.16k
  *bytes_per_sector = internal_handle->media_values->bytes_per_sector;
9477
9478
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9479
1.16k
  if( libcthreads_read_write_lock_release_for_read(
9480
1.16k
       internal_handle->read_write_lock,
9481
1.16k
       error ) != 1 )
9482
0
  {
9483
0
    libcerror_error_set(
9484
0
     error,
9485
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9486
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9487
0
     "%s: unable to release read/write lock for reading.",
9488
0
     function );
9489
9490
0
    return( -1 );
9491
0
  }
9492
1.16k
#endif
9493
1.16k
  return( 1 );
9494
9495
0
on_error:
9496
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9497
0
  libcthreads_read_write_lock_release_for_read(
9498
0
   internal_handle->read_write_lock,
9499
0
   NULL );
9500
0
#endif
9501
0
  return( -1 );
9502
1.16k
}
9503
9504
/* Sets the number of bytes per sector
9505
 * Returns 1 if successful or -1 on error
9506
 */
9507
int libewf_handle_set_bytes_per_sector(
9508
     libewf_handle_t *handle,
9509
     uint32_t bytes_per_sector,
9510
     libcerror_error_t **error )
9511
0
{
9512
0
  libewf_internal_handle_t *internal_handle = NULL;
9513
0
  static char *function                     = "libewf_handle_set_bytes_per_sector";
9514
9515
0
  if( handle == NULL )
9516
0
  {
9517
0
    libcerror_error_set(
9518
0
     error,
9519
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9520
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9521
0
     "%s: invalid handle.",
9522
0
     function );
9523
9524
0
    return( -1 );
9525
0
  }
9526
0
  internal_handle = (libewf_internal_handle_t *) handle;
9527
9528
0
  if( internal_handle->media_values == NULL )
9529
0
  {
9530
0
    libcerror_error_set(
9531
0
     error,
9532
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9533
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9534
0
     "%s: invalid handle - missing media values.",
9535
0
     function );
9536
9537
0
    return( -1 );
9538
0
  }
9539
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9540
0
  if( libcthreads_read_write_lock_grab_for_write(
9541
0
       internal_handle->read_write_lock,
9542
0
       error ) != 1 )
9543
0
  {
9544
0
    libcerror_error_set(
9545
0
     error,
9546
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9547
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9548
0
     "%s: unable to grab read/write lock for writing.",
9549
0
     function );
9550
9551
0
    return( -1 );
9552
0
  }
9553
0
#endif
9554
0
  if( ( internal_handle->read_io_handle != NULL )
9555
0
   || ( internal_handle->write_io_handle == NULL )
9556
0
   || ( internal_handle->write_io_handle->values_initialized != 0 ) )
9557
0
  {
9558
0
    libcerror_error_set(
9559
0
     error,
9560
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9561
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9562
0
     "%s: bytes per sector cannot be changed.",
9563
0
     function );
9564
9565
0
    goto on_error;
9566
0
  }
9567
0
  if( libewf_internal_handle_set_media_values(
9568
0
       internal_handle,
9569
0
       internal_handle->media_values->sectors_per_chunk,
9570
0
       bytes_per_sector,
9571
0
       internal_handle->media_values->media_size,
9572
0
       error ) != 1 )
9573
0
  {
9574
0
    libcerror_error_set(
9575
0
     error,
9576
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9577
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9578
0
     "%s: unable to set media values.",
9579
0
     function );
9580
9581
0
    goto on_error;
9582
0
  }
9583
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9584
0
  if( libcthreads_read_write_lock_release_for_write(
9585
0
       internal_handle->read_write_lock,
9586
0
       error ) != 1 )
9587
0
  {
9588
0
    libcerror_error_set(
9589
0
     error,
9590
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9591
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9592
0
     "%s: unable to release read/write lock for writing.",
9593
0
     function );
9594
9595
0
    return( -1 );
9596
0
  }
9597
0
#endif
9598
0
  return( 1 );
9599
9600
0
on_error:
9601
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9602
0
  libcthreads_read_write_lock_release_for_write(
9603
0
   internal_handle->read_write_lock,
9604
0
   NULL );
9605
0
#endif
9606
0
  return( -1 );
9607
0
}
9608
9609
/* Retrieves the number of sectors
9610
 * Returns 1 if successful or -1 on error
9611
 */
9612
int libewf_handle_get_number_of_sectors(
9613
     libewf_handle_t *handle,
9614
     uint64_t *number_of_sectors,
9615
     libcerror_error_t **error )
9616
1.16k
{
9617
1.16k
  libewf_internal_handle_t *internal_handle = NULL;
9618
1.16k
  static char *function                     = "libewf_handle_get_number_of_sectors";
9619
9620
1.16k
  if( handle == NULL )
9621
0
  {
9622
0
    libcerror_error_set(
9623
0
     error,
9624
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9625
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9626
0
     "%s: invalid handle.",
9627
0
     function );
9628
9629
0
    return( -1 );
9630
0
  }
9631
1.16k
  internal_handle = (libewf_internal_handle_t *) handle;
9632
9633
1.16k
  if( internal_handle->media_values == NULL )
9634
0
  {
9635
0
    libcerror_error_set(
9636
0
     error,
9637
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9638
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9639
0
     "%s: invalid handle - missing media values.",
9640
0
     function );
9641
9642
0
    return( -1 );
9643
0
  }
9644
1.16k
  if( number_of_sectors == NULL )
9645
0
  {
9646
0
    libcerror_error_set(
9647
0
     error,
9648
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9649
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9650
0
     "%s: invalid bytes per sector.",
9651
0
     function );
9652
9653
0
    return( -1 );
9654
0
  }
9655
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9656
1.16k
  if( libcthreads_read_write_lock_grab_for_read(
9657
1.16k
       internal_handle->read_write_lock,
9658
1.16k
       error ) != 1 )
9659
0
  {
9660
0
    libcerror_error_set(
9661
0
     error,
9662
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9663
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9664
0
     "%s: unable to grab read/write lock for reading.",
9665
0
     function );
9666
9667
0
    return( -1 );
9668
0
  }
9669
1.16k
#endif
9670
1.16k
  if( internal_handle->media_values->number_of_sectors > (uint64_t) INT64_MAX )
9671
1
  {
9672
1
    libcerror_error_set(
9673
1
     error,
9674
1
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9675
1
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
9676
1
     "%s: invalid number of sectors value exceeds maximum.",
9677
1
     function );
9678
9679
1
    goto on_error;
9680
1
  }
9681
1.16k
  *number_of_sectors = internal_handle->media_values->number_of_sectors;
9682
9683
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9684
1.16k
  if( libcthreads_read_write_lock_release_for_read(
9685
1.16k
       internal_handle->read_write_lock,
9686
1.16k
       error ) != 1 )
9687
0
  {
9688
0
    libcerror_error_set(
9689
0
     error,
9690
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9691
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9692
0
     "%s: unable to release read/write lock for reading.",
9693
0
     function );
9694
9695
0
    return( -1 );
9696
0
  }
9697
1.16k
#endif
9698
1.16k
  return( 1 );
9699
9700
1
on_error:
9701
1
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9702
1
  libcthreads_read_write_lock_release_for_read(
9703
1
   internal_handle->read_write_lock,
9704
1
   NULL );
9705
1
#endif
9706
1
  return( -1 );
9707
1.16k
}
9708
9709
/* Retrieves the chunk size
9710
 * Returns 1 if successful or -1 on error
9711
 */
9712
int libewf_handle_get_chunk_size(
9713
     libewf_handle_t *handle,
9714
     size32_t *chunk_size,
9715
     libcerror_error_t **error )
9716
1.16k
{
9717
1.16k
  libewf_internal_handle_t *internal_handle = NULL;
9718
1.16k
  static char *function                     = "libewf_handle_get_chunk_size";
9719
9720
1.16k
  if( handle == NULL )
9721
0
  {
9722
0
    libcerror_error_set(
9723
0
     error,
9724
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9725
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9726
0
     "%s: invalid handle.",
9727
0
     function );
9728
9729
0
    return( -1 );
9730
0
  }
9731
1.16k
  internal_handle = (libewf_internal_handle_t *) handle;
9732
9733
1.16k
  if( internal_handle->media_values == NULL )
9734
0
  {
9735
0
    libcerror_error_set(
9736
0
     error,
9737
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9738
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9739
0
     "%s: invalid handle - missing media values.",
9740
0
     function );
9741
9742
0
    return( -1 );
9743
0
  }
9744
1.16k
  if( chunk_size == NULL )
9745
0
  {
9746
0
    libcerror_error_set(
9747
0
     error,
9748
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9749
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9750
0
     "%s: invalid chunk size.",
9751
0
     function );
9752
9753
0
    return( -1 );
9754
0
  }
9755
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9756
1.16k
  if( libcthreads_read_write_lock_grab_for_read(
9757
1.16k
       internal_handle->read_write_lock,
9758
1.16k
       error ) != 1 )
9759
0
  {
9760
0
    libcerror_error_set(
9761
0
     error,
9762
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9763
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9764
0
     "%s: unable to grab read/write lock for reading.",
9765
0
     function );
9766
9767
0
    return( -1 );
9768
0
  }
9769
1.16k
#endif
9770
1.16k
  if( internal_handle->media_values->chunk_size > (size32_t) INT32_MAX )
9771
0
  {
9772
0
    libcerror_error_set(
9773
0
     error,
9774
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9775
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
9776
0
     "%s: invalid chunk size value exceeds maximum.",
9777
0
     function );
9778
9779
0
    goto on_error;
9780
0
  }
9781
1.16k
  *chunk_size = internal_handle->media_values->chunk_size;
9782
9783
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9784
1.16k
  if( libcthreads_read_write_lock_release_for_read(
9785
1.16k
       internal_handle->read_write_lock,
9786
1.16k
       error ) != 1 )
9787
0
  {
9788
0
    libcerror_error_set(
9789
0
     error,
9790
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9791
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9792
0
     "%s: unable to release read/write lock for reading.",
9793
0
     function );
9794
9795
0
    return( -1 );
9796
0
  }
9797
1.16k
#endif
9798
1.16k
  return( 1 );
9799
9800
0
on_error:
9801
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9802
0
  libcthreads_read_write_lock_release_for_read(
9803
0
   internal_handle->read_write_lock,
9804
0
   NULL );
9805
0
#endif
9806
0
  return( -1 );
9807
1.16k
}
9808
9809
/* Retrieves the error granularity
9810
 * Returns 1 if successful or -1 on error
9811
 */
9812
int libewf_handle_get_error_granularity(
9813
     libewf_handle_t *handle,
9814
     uint32_t *error_granularity,
9815
     libcerror_error_t **error )
9816
1.16k
{
9817
1.16k
  libewf_internal_handle_t *internal_handle = NULL;
9818
1.16k
  static char *function                     = "libewf_handle_get_error_granularity";
9819
9820
1.16k
  if( handle == NULL )
9821
0
  {
9822
0
    libcerror_error_set(
9823
0
     error,
9824
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9825
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9826
0
     "%s: invalid handle.",
9827
0
     function );
9828
9829
0
    return( -1 );
9830
0
  }
9831
1.16k
  internal_handle = (libewf_internal_handle_t *) handle;
9832
9833
1.16k
  if( internal_handle->media_values == NULL )
9834
0
  {
9835
0
    libcerror_error_set(
9836
0
     error,
9837
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9838
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9839
0
     "%s: invalid handle - missing media values.",
9840
0
     function );
9841
9842
0
    return( -1 );
9843
0
  }
9844
1.16k
  if( error_granularity == NULL )
9845
0
  {
9846
0
    libcerror_error_set(
9847
0
     error,
9848
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9849
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9850
0
     "%s: invalid error granularity.",
9851
0
     function );
9852
9853
0
    return( -1 );
9854
0
  }
9855
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9856
1.16k
  if( libcthreads_read_write_lock_grab_for_read(
9857
1.16k
       internal_handle->read_write_lock,
9858
1.16k
       error ) != 1 )
9859
0
  {
9860
0
    libcerror_error_set(
9861
0
     error,
9862
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9863
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9864
0
     "%s: unable to grab read/write lock for reading.",
9865
0
     function );
9866
9867
0
    return( -1 );
9868
0
  }
9869
1.16k
#endif
9870
1.16k
  if( internal_handle->media_values->error_granularity > (uint32_t) INT32_MAX )
9871
0
  {
9872
0
    libcerror_error_set(
9873
0
     error,
9874
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9875
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
9876
0
     "%s: invalid error granularity value exceeds maximum.",
9877
0
     function );
9878
9879
0
    goto on_error;
9880
0
  }
9881
1.16k
  *error_granularity = internal_handle->media_values->error_granularity;
9882
9883
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9884
1.16k
  if( libcthreads_read_write_lock_release_for_read(
9885
1.16k
       internal_handle->read_write_lock,
9886
1.16k
       error ) != 1 )
9887
0
  {
9888
0
    libcerror_error_set(
9889
0
     error,
9890
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9891
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9892
0
     "%s: unable to release read/write lock for reading.",
9893
0
     function );
9894
9895
0
    return( -1 );
9896
0
  }
9897
1.16k
#endif
9898
1.16k
  return( 1 );
9899
9900
0
on_error:
9901
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9902
0
  libcthreads_read_write_lock_release_for_read(
9903
0
   internal_handle->read_write_lock,
9904
0
   NULL );
9905
0
#endif
9906
0
  return( -1 );
9907
1.16k
}
9908
9909
/* Sets the error granularity
9910
 * Returns 1 if successful or -1 on error
9911
 */
9912
int libewf_handle_set_error_granularity(
9913
     libewf_handle_t *handle,
9914
     uint32_t error_granularity,
9915
     libcerror_error_t **error )
9916
0
{
9917
0
  libewf_internal_handle_t *internal_handle = NULL;
9918
0
  static char *function                     = "libewf_handle_set_error_granularity";
9919
9920
0
  if( handle == NULL )
9921
0
  {
9922
0
    libcerror_error_set(
9923
0
     error,
9924
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9925
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9926
0
     "%s: invalid handle.",
9927
0
     function );
9928
9929
0
    return( -1 );
9930
0
  }
9931
0
  internal_handle = (libewf_internal_handle_t *) handle;
9932
9933
0
  if( internal_handle->media_values == NULL )
9934
0
  {
9935
0
    libcerror_error_set(
9936
0
     error,
9937
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9938
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9939
0
     "%s: invalid handle - missing media values.",
9940
0
     function );
9941
9942
0
    return( -1 );
9943
0
  }
9944
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9945
0
  if( libcthreads_read_write_lock_grab_for_write(
9946
0
       internal_handle->read_write_lock,
9947
0
       error ) != 1 )
9948
0
  {
9949
0
    libcerror_error_set(
9950
0
     error,
9951
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9952
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9953
0
     "%s: unable to grab read/write lock for writing.",
9954
0
     function );
9955
9956
0
    return( -1 );
9957
0
  }
9958
0
#endif
9959
0
  if( ( internal_handle->write_io_handle == NULL )
9960
0
   || ( internal_handle->write_io_handle->values_initialized != 0 ) )
9961
0
  {
9962
0
    libcerror_error_set(
9963
0
     error,
9964
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9965
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9966
0
     "%s: error granularity cannot be changed.",
9967
0
     function );
9968
9969
0
    goto on_error;
9970
0
  }
9971
0
  internal_handle->media_values->error_granularity = error_granularity;
9972
9973
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9974
0
  if( libcthreads_read_write_lock_release_for_write(
9975
0
       internal_handle->read_write_lock,
9976
0
       error ) != 1 )
9977
0
  {
9978
0
    libcerror_error_set(
9979
0
     error,
9980
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
9981
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9982
0
     "%s: unable to release read/write lock for writing.",
9983
0
     function );
9984
9985
0
    return( -1 );
9986
0
  }
9987
0
#endif
9988
0
  return( 1 );
9989
9990
0
on_error:
9991
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
9992
0
  libcthreads_read_write_lock_release_for_write(
9993
0
   internal_handle->read_write_lock,
9994
0
   NULL );
9995
0
#endif
9996
0
  return( -1 );
9997
0
}
9998
9999
/* Retrieves the compression method
10000
 * Returns 1 if successful or -1 on error
10001
 */
10002
int libewf_handle_get_compression_method(
10003
     libewf_handle_t *handle,
10004
     uint16_t *compression_method,
10005
     libcerror_error_t **error )
10006
1.16k
{
10007
1.16k
  libewf_internal_handle_t *internal_handle = NULL;
10008
1.16k
  static char *function                     = "libewf_handle_get_compression_method";
10009
10010
1.16k
  if( handle == NULL )
10011
0
  {
10012
0
    libcerror_error_set(
10013
0
     error,
10014
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10015
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
10016
0
     "%s: invalid handle.",
10017
0
     function );
10018
10019
0
    return( -1 );
10020
0
  }
10021
1.16k
  internal_handle = (libewf_internal_handle_t *) handle;
10022
10023
1.16k
  if( internal_handle->io_handle == NULL )
10024
0
  {
10025
0
    libcerror_error_set(
10026
0
     error,
10027
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10028
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
10029
0
     "%s: invalid handle - missing IO handle.",
10030
0
     function );
10031
10032
0
    return( -1 );
10033
0
  }
10034
1.16k
  if( compression_method == NULL )
10035
0
  {
10036
0
    libcerror_error_set(
10037
0
     error,
10038
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10039
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
10040
0
     "%s: invalid compression method.",
10041
0
     function );
10042
10043
0
    return( -1 );
10044
0
  }
10045
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10046
1.16k
  if( libcthreads_read_write_lock_grab_for_read(
10047
1.16k
       internal_handle->read_write_lock,
10048
1.16k
       error ) != 1 )
10049
0
  {
10050
0
    libcerror_error_set(
10051
0
     error,
10052
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10053
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10054
0
     "%s: unable to grab read/write lock for reading.",
10055
0
     function );
10056
10057
0
    return( -1 );
10058
0
  }
10059
1.16k
#endif
10060
1.16k
  *compression_method = internal_handle->io_handle->compression_method;
10061
10062
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10063
1.16k
  if( libcthreads_read_write_lock_release_for_read(
10064
1.16k
       internal_handle->read_write_lock,
10065
1.16k
       error ) != 1 )
10066
0
  {
10067
0
    libcerror_error_set(
10068
0
     error,
10069
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10070
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10071
0
     "%s: unable to release read/write lock for reading.",
10072
0
     function );
10073
10074
0
    return( -1 );
10075
0
  }
10076
1.16k
#endif
10077
1.16k
  return( 1 );
10078
1.16k
}
10079
10080
/* Sets the compression method
10081
 * Returns 1 if successful or -1 on error
10082
 */
10083
int libewf_handle_set_compression_method(
10084
     libewf_handle_t *handle,
10085
     uint16_t compression_method,
10086
     libcerror_error_t **error )
10087
0
{
10088
0
  libewf_internal_handle_t *internal_handle = NULL;
10089
0
  static char *function                     = "libewf_handle_set_compression_method";
10090
10091
0
  if( handle == NULL )
10092
0
  {
10093
0
    libcerror_error_set(
10094
0
     error,
10095
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10096
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
10097
0
     "%s: invalid handle.",
10098
0
     function );
10099
10100
0
    return( -1 );
10101
0
  }
10102
0
  internal_handle = (libewf_internal_handle_t *) handle;
10103
10104
0
  if( internal_handle->io_handle == NULL )
10105
0
  {
10106
0
    libcerror_error_set(
10107
0
     error,
10108
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10109
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
10110
0
     "%s: invalid handle - missing IO handle.",
10111
0
     function );
10112
10113
0
    return( -1 );
10114
0
  }
10115
0
  if( ( compression_method != LIBEWF_COMPRESSION_METHOD_DEFLATE )
10116
0
   && ( compression_method != LIBEWF_COMPRESSION_METHOD_BZIP2 ) )
10117
0
  {
10118
0
    libcerror_error_set(
10119
0
     error,
10120
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10121
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
10122
0
     "%s: unsupported compression method.",
10123
0
     function );
10124
10125
0
    return( -1 );
10126
0
  }
10127
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10128
0
  if( libcthreads_read_write_lock_grab_for_write(
10129
0
       internal_handle->read_write_lock,
10130
0
       error ) != 1 )
10131
0
  {
10132
0
    libcerror_error_set(
10133
0
     error,
10134
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10135
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10136
0
     "%s: unable to grab read/write lock for writing.",
10137
0
     function );
10138
10139
0
    return( -1 );
10140
0
  }
10141
0
#endif
10142
0
  if( ( internal_handle->write_io_handle == NULL )
10143
0
   || ( internal_handle->write_io_handle->values_initialized != 0 ) )
10144
0
  {
10145
0
    libcerror_error_set(
10146
0
     error,
10147
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10148
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10149
0
     "%s: compression values cannot be changed.",
10150
0
     function );
10151
10152
0
    goto on_error;
10153
0
  }
10154
0
  if( ( compression_method == LIBEWF_COMPRESSION_METHOD_BZIP2 )
10155
0
   && ( internal_handle->io_handle->segment_file_type != LIBEWF_SEGMENT_FILE_TYPE_EWF2 )
10156
0
   && ( internal_handle->io_handle->segment_file_type != LIBEWF_SEGMENT_FILE_TYPE_EWF2_LOGICAL ) )
10157
0
  {
10158
0
    libcerror_error_set(
10159
0
     error,
10160
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10161
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
10162
0
     "%s: compression method not supported by format.",
10163
0
     function );
10164
10165
0
    goto on_error;
10166
0
  }
10167
0
  internal_handle->io_handle->compression_method = compression_method;
10168
10169
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10170
0
  if( libcthreads_read_write_lock_release_for_write(
10171
0
       internal_handle->read_write_lock,
10172
0
       error ) != 1 )
10173
0
  {
10174
0
    libcerror_error_set(
10175
0
     error,
10176
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10177
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10178
0
     "%s: unable to release read/write lock for writing.",
10179
0
     function );
10180
10181
0
    return( -1 );
10182
0
  }
10183
0
#endif
10184
0
  return( 1 );
10185
10186
0
on_error:
10187
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10188
0
  libcthreads_read_write_lock_release_for_write(
10189
0
   internal_handle->read_write_lock,
10190
0
   NULL );
10191
0
#endif
10192
0
  return( -1 );
10193
0
}
10194
10195
/* Retrieves the compression values
10196
 * Returns 1 if successful or -1 on error
10197
 */
10198
int libewf_handle_get_compression_values(
10199
     libewf_handle_t *handle,
10200
     int8_t *compression_level,
10201
     uint8_t *compression_flags,
10202
     libcerror_error_t **error )
10203
1.16k
{
10204
1.16k
  libewf_internal_handle_t *internal_handle = NULL;
10205
1.16k
  static char *function                     = "libewf_handle_get_compression_values";
10206
10207
1.16k
  if( handle == NULL )
10208
0
  {
10209
0
    libcerror_error_set(
10210
0
     error,
10211
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10212
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
10213
0
     "%s: invalid handle.",
10214
0
     function );
10215
10216
0
    return( -1 );
10217
0
  }
10218
1.16k
  internal_handle = (libewf_internal_handle_t *) handle;
10219
10220
1.16k
  if( internal_handle->io_handle == NULL )
10221
0
  {
10222
0
    libcerror_error_set(
10223
0
     error,
10224
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10225
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
10226
0
     "%s: invalid handle - missing IO handle.",
10227
0
     function );
10228
10229
0
    return( -1 );
10230
0
  }
10231
1.16k
  if( compression_level == NULL )
10232
0
  {
10233
0
    libcerror_error_set(
10234
0
     error,
10235
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10236
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
10237
0
     "%s: invalid compression level.",
10238
0
     function );
10239
10240
0
    return( -1 );
10241
0
  }
10242
1.16k
  if( compression_flags == NULL )
10243
0
  {
10244
0
    libcerror_error_set(
10245
0
     error,
10246
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10247
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
10248
0
     "%s: invalid compression flags.",
10249
0
     function );
10250
10251
0
    return( -1 );
10252
0
  }
10253
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10254
1.16k
  if( libcthreads_read_write_lock_grab_for_read(
10255
1.16k
       internal_handle->read_write_lock,
10256
1.16k
       error ) != 1 )
10257
0
  {
10258
0
    libcerror_error_set(
10259
0
     error,
10260
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10261
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10262
0
     "%s: unable to grab read/write lock for reading.",
10263
0
     function );
10264
10265
0
    return( -1 );
10266
0
  }
10267
1.16k
#endif
10268
1.16k
  *compression_level = internal_handle->io_handle->compression_level;
10269
1.16k
  *compression_flags = internal_handle->io_handle->compression_flags;
10270
10271
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10272
1.16k
  if( libcthreads_read_write_lock_release_for_read(
10273
1.16k
       internal_handle->read_write_lock,
10274
1.16k
       error ) != 1 )
10275
0
  {
10276
0
    libcerror_error_set(
10277
0
     error,
10278
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10279
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10280
0
     "%s: unable to release read/write lock for reading.",
10281
0
     function );
10282
10283
0
    return( -1 );
10284
0
  }
10285
1.16k
#endif
10286
1.16k
  return( 1 );
10287
1.16k
}
10288
10289
/* Sets the compression values
10290
 * Returns 1 if successful or -1 on error
10291
 */
10292
int libewf_handle_set_compression_values(
10293
     libewf_handle_t *handle,
10294
     int8_t compression_level,
10295
     uint8_t compression_flags,
10296
     libcerror_error_t **error )
10297
0
{
10298
0
  libewf_internal_handle_t *internal_handle = NULL;
10299
0
  static char *function                     = "libewf_handle_set_compression_values";
10300
10301
0
  if( handle == NULL )
10302
0
  {
10303
0
    libcerror_error_set(
10304
0
     error,
10305
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10306
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
10307
0
     "%s: invalid handle.",
10308
0
     function );
10309
10310
0
    return( -1 );
10311
0
  }
10312
0
  internal_handle = (libewf_internal_handle_t *) handle;
10313
10314
0
  if( internal_handle->io_handle == NULL )
10315
0
  {
10316
0
    libcerror_error_set(
10317
0
     error,
10318
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10319
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
10320
0
     "%s: invalid handle - missing IO handle.",
10321
0
     function );
10322
10323
0
    return( -1 );
10324
0
  }
10325
0
  if( ( compression_level != LIBEWF_COMPRESSION_LEVEL_NONE )
10326
0
   && ( compression_level != LIBEWF_COMPRESSION_LEVEL_FAST )
10327
0
   && ( compression_level != LIBEWF_COMPRESSION_LEVEL_BEST ) )
10328
0
  {
10329
0
    libcerror_error_set(
10330
0
     error,
10331
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10332
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
10333
0
     "%s: unsupported compression level.",
10334
0
     function );
10335
10336
0
    return( -1 );
10337
0
  }
10338
0
  if( ( compression_flags & ~( LIBEWF_COMPRESS_FLAG_USE_EMPTY_BLOCK_COMPRESSION ) ) != 0 )
10339
0
  {
10340
0
    libcerror_error_set(
10341
0
     error,
10342
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10343
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
10344
0
     "%s: unsupported compression flags.",
10345
0
     function );
10346
10347
0
    return( -1 );
10348
0
  }
10349
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10350
0
  if( libcthreads_read_write_lock_grab_for_write(
10351
0
       internal_handle->read_write_lock,
10352
0
       error ) != 1 )
10353
0
  {
10354
0
    libcerror_error_set(
10355
0
     error,
10356
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10357
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10358
0
     "%s: unable to grab read/write lock for writing.",
10359
0
     function );
10360
10361
0
    return( -1 );
10362
0
  }
10363
0
#endif
10364
0
  if( ( internal_handle->write_io_handle == NULL )
10365
0
   || ( internal_handle->write_io_handle->values_initialized != 0 ) )
10366
0
  {
10367
0
    libcerror_error_set(
10368
0
     error,
10369
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10370
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10371
0
     "%s: compression values cannot be changed.",
10372
0
     function );
10373
10374
0
    goto on_error;
10375
0
  }
10376
0
  if( ( internal_handle->io_handle->segment_file_type == LIBEWF_SEGMENT_FILE_TYPE_EWF2 )
10377
0
   || ( internal_handle->io_handle->segment_file_type == LIBEWF_SEGMENT_FILE_TYPE_EWF2_LOGICAL ) )
10378
0
  {
10379
0
    compression_flags |= LIBEWF_COMPRESS_FLAG_USE_PATTERN_FILL_COMPRESSION;
10380
0
  }
10381
0
  internal_handle->io_handle->compression_level = compression_level;
10382
0
  internal_handle->io_handle->compression_flags = compression_flags;
10383
10384
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10385
0
  if( libcthreads_read_write_lock_release_for_write(
10386
0
       internal_handle->read_write_lock,
10387
0
       error ) != 1 )
10388
0
  {
10389
0
    libcerror_error_set(
10390
0
     error,
10391
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10392
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10393
0
     "%s: unable to release read/write lock for writing.",
10394
0
     function );
10395
10396
0
    return( -1 );
10397
0
  }
10398
0
#endif
10399
0
  return( 1 );
10400
10401
0
on_error:
10402
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10403
0
  libcthreads_read_write_lock_release_for_write(
10404
0
   internal_handle->read_write_lock,
10405
0
   NULL );
10406
0
#endif
10407
0
  return( -1 );
10408
0
}
10409
10410
/* Retrieves the size of the contained media data
10411
 * Returns 1 if successful or -1 on error
10412
 */
10413
int libewf_handle_get_media_size(
10414
     libewf_handle_t *handle,
10415
     size64_t *media_size,
10416
     libcerror_error_t **error )
10417
0
{
10418
0
  libewf_internal_handle_t *internal_handle = NULL;
10419
0
  static char *function                     = "libewf_handle_get_media_size";
10420
10421
0
  if( handle == NULL )
10422
0
  {
10423
0
    libcerror_error_set(
10424
0
     error,
10425
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10426
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
10427
0
     "%s: invalid handle.",
10428
0
     function );
10429
10430
0
    return( -1 );
10431
0
  }
10432
0
  internal_handle = (libewf_internal_handle_t *) handle;
10433
10434
0
  if( internal_handle->media_values == NULL )
10435
0
  {
10436
0
    libcerror_error_set(
10437
0
     error,
10438
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10439
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
10440
0
     "%s: invalid handle - missing media values.",
10441
0
     function );
10442
10443
0
    return( -1 );
10444
0
  }
10445
0
  if( media_size == NULL )
10446
0
  {
10447
0
    libcerror_error_set(
10448
0
     error,
10449
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10450
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
10451
0
     "%s: invalid media size.",
10452
0
     function );
10453
10454
0
    return( -1 );
10455
0
  }
10456
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10457
0
  if( libcthreads_read_write_lock_grab_for_read(
10458
0
       internal_handle->read_write_lock,
10459
0
       error ) != 1 )
10460
0
  {
10461
0
    libcerror_error_set(
10462
0
     error,
10463
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10464
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10465
0
     "%s: unable to grab read/write lock for reading.",
10466
0
     function );
10467
10468
0
    return( -1 );
10469
0
  }
10470
0
#endif
10471
0
  *media_size = internal_handle->media_values->media_size;
10472
10473
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10474
0
  if( libcthreads_read_write_lock_release_for_read(
10475
0
       internal_handle->read_write_lock,
10476
0
       error ) != 1 )
10477
0
  {
10478
0
    libcerror_error_set(
10479
0
     error,
10480
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10481
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10482
0
     "%s: unable to release read/write lock for reading.",
10483
0
     function );
10484
10485
0
    return( -1 );
10486
0
  }
10487
0
#endif
10488
0
  return( 1 );
10489
0
}
10490
10491
/* Sets the media size
10492
 * Returns 1 if successful or -1 on error
10493
 */
10494
int libewf_handle_set_media_size(
10495
     libewf_handle_t *handle,
10496
     size64_t media_size,
10497
     libcerror_error_t **error )
10498
0
{
10499
0
  libewf_internal_handle_t *internal_handle = NULL;
10500
0
  static char *function                     = "libewf_handle_set_media_size";
10501
10502
0
  if( handle == NULL )
10503
0
  {
10504
0
    libcerror_error_set(
10505
0
     error,
10506
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10507
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
10508
0
     "%s: invalid handle.",
10509
0
     function );
10510
10511
0
    return( -1 );
10512
0
  }
10513
0
  internal_handle = (libewf_internal_handle_t *) handle;
10514
10515
0
  if( internal_handle->media_values == NULL )
10516
0
  {
10517
0
    libcerror_error_set(
10518
0
     error,
10519
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10520
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
10521
0
     "%s: invalid handle - missing media values.",
10522
0
     function );
10523
10524
0
    return( -1 );
10525
0
  }
10526
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10527
0
  if( libcthreads_read_write_lock_grab_for_write(
10528
0
       internal_handle->read_write_lock,
10529
0
       error ) != 1 )
10530
0
  {
10531
0
    libcerror_error_set(
10532
0
     error,
10533
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10534
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10535
0
     "%s: unable to grab read/write lock for writing.",
10536
0
     function );
10537
10538
0
    return( -1 );
10539
0
  }
10540
0
#endif
10541
0
  if( ( internal_handle->read_io_handle != NULL )
10542
0
   || ( internal_handle->write_io_handle == NULL )
10543
0
   || ( internal_handle->write_io_handle->values_initialized != 0 ) )
10544
0
  {
10545
0
    libcerror_error_set(
10546
0
     error,
10547
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10548
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10549
0
     "%s: media size cannot be changed.",
10550
0
     function );
10551
10552
0
    goto on_error;
10553
0
  }
10554
0
  if( libewf_internal_handle_set_media_values(
10555
0
       internal_handle,
10556
0
       internal_handle->media_values->sectors_per_chunk,
10557
0
       internal_handle->media_values->bytes_per_sector,
10558
0
       media_size,
10559
0
       error ) != 1 )
10560
0
  {
10561
0
    libcerror_error_set(
10562
0
     error,
10563
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10564
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10565
0
     "%s: unable to set media values.",
10566
0
     function );
10567
10568
0
    goto on_error;
10569
0
  }
10570
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10571
0
  if( libcthreads_read_write_lock_release_for_write(
10572
0
       internal_handle->read_write_lock,
10573
0
       error ) != 1 )
10574
0
  {
10575
0
    libcerror_error_set(
10576
0
     error,
10577
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10578
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10579
0
     "%s: unable to release read/write lock for writing.",
10580
0
     function );
10581
10582
0
    return( -1 );
10583
0
  }
10584
0
#endif
10585
0
  return( 1 );
10586
10587
0
on_error:
10588
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10589
0
  libcthreads_read_write_lock_release_for_write(
10590
0
   internal_handle->read_write_lock,
10591
0
   NULL );
10592
0
#endif
10593
0
  return( -1 );
10594
0
}
10595
10596
/* Retrieves the media type value
10597
 * Returns 1 if successful or -1 on error
10598
 */
10599
int libewf_handle_get_media_type(
10600
     libewf_handle_t *handle,
10601
     uint8_t *media_type,
10602
     libcerror_error_t **error )
10603
1.16k
{
10604
1.16k
  libewf_internal_handle_t *internal_handle = NULL;
10605
1.16k
  static char *function                     = "libewf_handle_get_media_type";
10606
10607
1.16k
  if( handle == NULL )
10608
0
  {
10609
0
    libcerror_error_set(
10610
0
     error,
10611
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10612
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
10613
0
     "%s: invalid handle.",
10614
0
     function );
10615
10616
0
    return( -1 );
10617
0
  }
10618
1.16k
  internal_handle = (libewf_internal_handle_t *) handle;
10619
10620
1.16k
  if( internal_handle->media_values == NULL )
10621
0
  {
10622
0
    libcerror_error_set(
10623
0
     error,
10624
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10625
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
10626
0
     "%s: invalid handle - missing media values.",
10627
0
     function );
10628
10629
0
    return( -1 );
10630
0
  }
10631
1.16k
  if( internal_handle->media_values->media_type > (uint8_t) INT8_MAX )
10632
0
  {
10633
0
    libcerror_error_set(
10634
0
     error,
10635
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10636
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
10637
0
     "%s: invalid media type value exceeds maximum.",
10638
0
     function );
10639
10640
0
    return( -1 );
10641
0
  }
10642
1.16k
  if( media_type == NULL )
10643
0
  {
10644
0
    libcerror_error_set(
10645
0
     error,
10646
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10647
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
10648
0
     "%s: invalid media type.",
10649
0
     function );
10650
10651
0
    return( -1 );
10652
0
  }
10653
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10654
1.16k
  if( libcthreads_read_write_lock_grab_for_read(
10655
1.16k
       internal_handle->read_write_lock,
10656
1.16k
       error ) != 1 )
10657
0
  {
10658
0
    libcerror_error_set(
10659
0
     error,
10660
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10661
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10662
0
     "%s: unable to grab read/write lock for reading.",
10663
0
     function );
10664
10665
0
    return( -1 );
10666
0
  }
10667
1.16k
#endif
10668
1.16k
  *media_type = internal_handle->media_values->media_type;
10669
10670
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10671
1.16k
  if( libcthreads_read_write_lock_release_for_read(
10672
1.16k
       internal_handle->read_write_lock,
10673
1.16k
       error ) != 1 )
10674
0
  {
10675
0
    libcerror_error_set(
10676
0
     error,
10677
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10678
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10679
0
     "%s: unable to release read/write lock for reading.",
10680
0
     function );
10681
10682
0
    return( -1 );
10683
0
  }
10684
1.16k
#endif
10685
1.16k
  return( 1 );
10686
1.16k
}
10687
10688
/* Sets the media type
10689
 * Returns 1 if successful or -1 on error
10690
 */
10691
int libewf_handle_set_media_type(
10692
     libewf_handle_t *handle,
10693
     uint8_t media_type,
10694
     libcerror_error_t **error )
10695
0
{
10696
0
  libewf_internal_handle_t *internal_handle = NULL;
10697
0
  static char *function                     = "libewf_handle_set_media_type";
10698
10699
0
  if( handle == NULL )
10700
0
  {
10701
0
    libcerror_error_set(
10702
0
     error,
10703
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10704
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
10705
0
     "%s: invalid handle.",
10706
0
     function );
10707
10708
0
    return( -1 );
10709
0
  }
10710
0
  internal_handle = (libewf_internal_handle_t *) handle;
10711
10712
0
  if( internal_handle->media_values == NULL )
10713
0
  {
10714
0
    libcerror_error_set(
10715
0
     error,
10716
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10717
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
10718
0
     "%s: invalid handle - missing media values.",
10719
0
     function );
10720
10721
0
    return( -1 );
10722
0
  }
10723
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10724
0
  if( libcthreads_read_write_lock_grab_for_write(
10725
0
       internal_handle->read_write_lock,
10726
0
       error ) != 1 )
10727
0
  {
10728
0
    libcerror_error_set(
10729
0
     error,
10730
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10731
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10732
0
     "%s: unable to grab read/write lock for writing.",
10733
0
     function );
10734
10735
0
    return( -1 );
10736
0
  }
10737
0
#endif
10738
0
  if( ( internal_handle->read_io_handle != NULL )
10739
0
   || ( internal_handle->write_io_handle == NULL )
10740
0
   || ( internal_handle->write_io_handle->values_initialized != 0 ) )
10741
0
  {
10742
0
    libcerror_error_set(
10743
0
     error,
10744
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10745
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10746
0
     "%s: media type cannot be changed.",
10747
0
     function );
10748
10749
0
    goto on_error;
10750
0
  }
10751
0
  internal_handle->media_values->media_type = media_type;
10752
10753
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10754
0
  if( libcthreads_read_write_lock_release_for_write(
10755
0
       internal_handle->read_write_lock,
10756
0
       error ) != 1 )
10757
0
  {
10758
0
    libcerror_error_set(
10759
0
     error,
10760
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10761
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10762
0
     "%s: unable to release read/write lock for writing.",
10763
0
     function );
10764
10765
0
    return( -1 );
10766
0
  }
10767
0
#endif
10768
0
  return( 1 );
10769
10770
0
on_error:
10771
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10772
0
  libcthreads_read_write_lock_release_for_write(
10773
0
   internal_handle->read_write_lock,
10774
0
   NULL );
10775
0
#endif
10776
0
  return( -1 );
10777
0
}
10778
10779
/* Retrieves the media flags
10780
 * Returns 1 if successful or -1 on error
10781
 */
10782
int libewf_handle_get_media_flags(
10783
     libewf_handle_t *handle,
10784
     uint8_t *media_flags,
10785
     libcerror_error_t **error )
10786
1.16k
{
10787
1.16k
  libewf_internal_handle_t *internal_handle = NULL;
10788
1.16k
  static char *function                     = "libewf_handle_get_media_flags";
10789
10790
1.16k
  if( handle == NULL )
10791
0
  {
10792
0
    libcerror_error_set(
10793
0
     error,
10794
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10795
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
10796
0
     "%s: invalid handle.",
10797
0
     function );
10798
10799
0
    return( -1 );
10800
0
  }
10801
1.16k
  internal_handle = (libewf_internal_handle_t *) handle;
10802
10803
1.16k
  if( internal_handle->media_values == NULL )
10804
0
  {
10805
0
    libcerror_error_set(
10806
0
     error,
10807
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10808
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
10809
0
     "%s: invalid handle - missing media values.",
10810
0
     function );
10811
10812
0
    return( -1 );
10813
0
  }
10814
1.16k
  if( media_flags == NULL )
10815
0
  {
10816
0
    libcerror_error_set(
10817
0
     error,
10818
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10819
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
10820
0
     "%s: invalid media flags.",
10821
0
     function );
10822
10823
0
    return( -1 );
10824
0
  }
10825
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10826
1.16k
  if( libcthreads_read_write_lock_grab_for_read(
10827
1.16k
       internal_handle->read_write_lock,
10828
1.16k
       error ) != 1 )
10829
0
  {
10830
0
    libcerror_error_set(
10831
0
     error,
10832
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10833
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10834
0
     "%s: unable to grab read/write lock for reading.",
10835
0
     function );
10836
10837
0
    return( -1 );
10838
0
  }
10839
1.16k
#endif
10840
1.16k
  if( internal_handle->media_values->media_flags > (uint8_t) INT8_MAX )
10841
1
  {
10842
1
    libcerror_error_set(
10843
1
     error,
10844
1
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10845
1
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
10846
1
     "%s: invalid media flags value exceeds maximum.",
10847
1
     function );
10848
10849
1
    goto on_error;
10850
1
  }
10851
1.16k
  *media_flags = internal_handle->media_values->media_flags;
10852
10853
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10854
1.16k
  if( libcthreads_read_write_lock_release_for_read(
10855
1.16k
       internal_handle->read_write_lock,
10856
1.16k
       error ) != 1 )
10857
0
  {
10858
0
    libcerror_error_set(
10859
0
     error,
10860
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10861
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10862
0
     "%s: unable to release read/write lock for reading.",
10863
0
     function );
10864
10865
0
    return( -1 );
10866
0
  }
10867
1.16k
#endif
10868
1.16k
  return( 1 );
10869
10870
1
on_error:
10871
1
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10872
1
  libcthreads_read_write_lock_release_for_read(
10873
1
   internal_handle->read_write_lock,
10874
1
   NULL );
10875
1
#endif
10876
1
  return( -1 );
10877
1.16k
}
10878
10879
/* Sets the media flags
10880
 * Returns 1 if successful or -1 on error
10881
 */
10882
int libewf_handle_set_media_flags(
10883
     libewf_handle_t *handle,
10884
     uint8_t media_flags,
10885
     libcerror_error_t **error )
10886
0
{
10887
0
  libewf_internal_handle_t *internal_handle = NULL;
10888
0
  static char *function                     = "libewf_handle_set_media_flags";
10889
10890
0
  if( handle == NULL )
10891
0
  {
10892
0
    libcerror_error_set(
10893
0
     error,
10894
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10895
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
10896
0
     "%s: invalid handle.",
10897
0
     function );
10898
10899
0
    return( -1 );
10900
0
  }
10901
0
  internal_handle = (libewf_internal_handle_t *) handle;
10902
10903
0
  if( internal_handle->media_values == NULL )
10904
0
  {
10905
0
    libcerror_error_set(
10906
0
     error,
10907
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10908
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
10909
0
     "%s: invalid handle - missing media values.",
10910
0
     function );
10911
10912
0
    return( -1 );
10913
0
  }
10914
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10915
0
  if( libcthreads_read_write_lock_grab_for_write(
10916
0
       internal_handle->read_write_lock,
10917
0
       error ) != 1 )
10918
0
  {
10919
0
    libcerror_error_set(
10920
0
     error,
10921
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10922
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10923
0
     "%s: unable to grab read/write lock for writing.",
10924
0
     function );
10925
10926
0
    return( -1 );
10927
0
  }
10928
0
#endif
10929
0
  if( ( internal_handle->read_io_handle != NULL )
10930
0
   || ( internal_handle->write_io_handle == NULL )
10931
0
   || ( internal_handle->write_io_handle->values_initialized != 0 ) )
10932
0
  {
10933
0
    libcerror_error_set(
10934
0
     error,
10935
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10936
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10937
0
     "%s: media flags cannot be changed.",
10938
0
     function );
10939
10940
0
    goto on_error;
10941
0
  }
10942
0
  internal_handle->media_values->media_flags = media_flags;
10943
10944
  /* Make sure the lowest bit is always set
10945
   */
10946
0
  internal_handle->media_values->media_flags |= 0x01;
10947
10948
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10949
0
  if( libcthreads_read_write_lock_release_for_write(
10950
0
       internal_handle->read_write_lock,
10951
0
       error ) != 1 )
10952
0
  {
10953
0
    libcerror_error_set(
10954
0
     error,
10955
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
10956
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
10957
0
     "%s: unable to release read/write lock for writing.",
10958
0
     function );
10959
10960
0
    return( -1 );
10961
0
  }
10962
0
#endif
10963
0
  return( 1 );
10964
10965
0
on_error:
10966
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
10967
0
  libcthreads_read_write_lock_release_for_write(
10968
0
   internal_handle->read_write_lock,
10969
0
   NULL );
10970
0
#endif
10971
0
  return( -1 );
10972
0
}
10973
10974
/* Retrieves the format type value
10975
 * Returns 1 if successful or -1 on error
10976
 */
10977
int libewf_handle_get_format(
10978
     libewf_handle_t *handle,
10979
     uint8_t *format,
10980
     libcerror_error_t **error )
10981
1.16k
{
10982
1.16k
  libewf_internal_handle_t *internal_handle = NULL;
10983
1.16k
  static char *function                     = "libewf_handle_get_format";
10984
1.16k
  int result                                = 1;
10985
10986
1.16k
  if( handle == NULL )
10987
0
  {
10988
0
    libcerror_error_set(
10989
0
     error,
10990
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
10991
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
10992
0
     "%s: invalid handle.",
10993
0
     function );
10994
10995
0
    return( -1 );
10996
0
  }
10997
1.16k
  internal_handle = (libewf_internal_handle_t *) handle;
10998
10999
1.16k
  if( internal_handle->io_handle == NULL )
11000
0
  {
11001
0
    libcerror_error_set(
11002
0
     error,
11003
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11004
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
11005
0
     "%s: invalid handle - missing IO handle.",
11006
0
     function );
11007
11008
0
    return( -1 );
11009
0
  }
11010
1.16k
  if( internal_handle->media_values == NULL )
11011
0
  {
11012
0
    libcerror_error_set(
11013
0
     error,
11014
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11015
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
11016
0
     "%s: invalid handle - missing media values.",
11017
0
     function );
11018
11019
0
    return( -1 );
11020
0
  }
11021
1.16k
  if( format == NULL )
11022
0
  {
11023
0
    libcerror_error_set(
11024
0
     error,
11025
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11026
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
11027
0
     "%s: invalid format.",
11028
0
     function );
11029
11030
0
    return( -1 );
11031
0
  }
11032
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11033
1.16k
  if( libcthreads_read_write_lock_grab_for_read(
11034
1.16k
       internal_handle->read_write_lock,
11035
1.16k
       error ) != 1 )
11036
0
  {
11037
0
    libcerror_error_set(
11038
0
     error,
11039
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11040
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11041
0
     "%s: unable to grab read/write lock for reading.",
11042
0
     function );
11043
11044
0
    return( -1 );
11045
0
  }
11046
1.16k
#endif
11047
1.16k
  if( internal_handle->io_handle->format > (uint8_t) INT8_MAX )
11048
0
  {
11049
0
    libcerror_error_set(
11050
0
     error,
11051
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11052
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
11053
0
     "%s: invalid format value exceeds maximum.",
11054
0
     function );
11055
11056
0
    result = -1;
11057
0
  }
11058
1.16k
  else
11059
1.16k
  {
11060
1.16k
    *format = internal_handle->io_handle->format;
11061
1.16k
  }
11062
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11063
1.16k
  if( libcthreads_read_write_lock_release_for_read(
11064
1.16k
       internal_handle->read_write_lock,
11065
1.16k
       error ) != 1 )
11066
0
  {
11067
0
    libcerror_error_set(
11068
0
     error,
11069
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11070
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11071
0
     "%s: unable to release read/write lock for reading.",
11072
0
     function );
11073
11074
0
    return( -1 );
11075
0
  }
11076
1.16k
#endif
11077
1.16k
  return( result );
11078
1.16k
}
11079
11080
/* Sets the output format
11081
 * Returns 1 if successful or -1 on error
11082
 */
11083
int libewf_handle_set_format(
11084
     libewf_handle_t *handle,
11085
     uint8_t format,
11086
     libcerror_error_t **error )
11087
0
{
11088
0
  libewf_internal_handle_t *internal_handle = NULL;
11089
0
  static char *function                     = "libewf_handle_set_format";
11090
11091
0
  if( handle == NULL )
11092
0
  {
11093
0
    libcerror_error_set(
11094
0
     error,
11095
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11096
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
11097
0
     "%s: invalid handle.",
11098
0
     function );
11099
11100
0
    return( -1 );
11101
0
  }
11102
0
  internal_handle = (libewf_internal_handle_t *) handle;
11103
11104
0
  if( internal_handle->io_handle == NULL )
11105
0
  {
11106
0
    libcerror_error_set(
11107
0
     error,
11108
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11109
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
11110
0
     "%s: invalid handle - missing IO handle.",
11111
0
     function );
11112
11113
0
    return( -1 );
11114
0
  }
11115
0
  if( ( format != LIBEWF_FORMAT_ENCASE1 )
11116
0
   && ( format != LIBEWF_FORMAT_ENCASE2 )
11117
0
   && ( format != LIBEWF_FORMAT_ENCASE3 )
11118
0
   && ( format != LIBEWF_FORMAT_ENCASE4 )
11119
0
   && ( format != LIBEWF_FORMAT_ENCASE5 )
11120
0
   && ( format != LIBEWF_FORMAT_ENCASE6 )
11121
0
   && ( format != LIBEWF_FORMAT_ENCASE7 )
11122
0
   && ( format != LIBEWF_FORMAT_SMART )
11123
0
   && ( format != LIBEWF_FORMAT_FTK_IMAGER )
11124
0
   && ( format != LIBEWF_FORMAT_LINEN5 )
11125
0
   && ( format != LIBEWF_FORMAT_LINEN6 )
11126
0
   && ( format != LIBEWF_FORMAT_LINEN7 )
11127
0
   && ( format != LIBEWF_FORMAT_V2_ENCASE7 )
11128
/* TODO add support for: L01, Lx01:
11129
   && ( format != LIBEWF_FORMAT_LOGICAL_ENCASE5 )
11130
   && ( format != LIBEWF_FORMAT_LOGICAL_ENCASE6 )
11131
   && ( format != LIBEWF_FORMAT_LOGICAL_ENCASE7 )
11132
   && ( format != LIBEWF_FORMAT_V2_LOGICAL_ENCASE7 )
11133
*/
11134
0
   && ( format != LIBEWF_FORMAT_EWF )
11135
0
   && ( format != LIBEWF_FORMAT_EWFX ) )
11136
0
  {
11137
0
    libcerror_error_set(
11138
0
     error,
11139
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11140
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
11141
0
     "%s: unsupported format: %d.",
11142
0
     function,
11143
0
           format );
11144
11145
0
    return( -1 );
11146
0
  }
11147
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11148
0
  if( libcthreads_read_write_lock_grab_for_write(
11149
0
       internal_handle->read_write_lock,
11150
0
       error ) != 1 )
11151
0
  {
11152
0
    libcerror_error_set(
11153
0
     error,
11154
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11155
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11156
0
     "%s: unable to grab read/write lock for writing.",
11157
0
     function );
11158
11159
0
    return( -1 );
11160
0
  }
11161
0
#endif
11162
0
  if( ( internal_handle->read_io_handle != NULL )
11163
0
   || ( internal_handle->write_io_handle == NULL )
11164
0
   || ( internal_handle->write_io_handle->values_initialized != 0 ) )
11165
0
  {
11166
0
    libcerror_error_set(
11167
0
     error,
11168
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11169
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11170
0
     "%s: format cannot be changed.",
11171
0
     function );
11172
11173
0
    goto on_error;
11174
0
  }
11175
/* TODO refactor into separate function */
11176
0
  internal_handle->io_handle->format = format;
11177
11178
0
  if( format == LIBEWF_FORMAT_V2_ENCASE7 )
11179
0
  {
11180
0
    internal_handle->io_handle->major_version = 2;
11181
0
    internal_handle->io_handle->minor_version = 1;
11182
0
  }
11183
0
  else
11184
0
  {
11185
0
    internal_handle->io_handle->major_version = 1;
11186
0
    internal_handle->io_handle->minor_version = 0;
11187
0
  }
11188
0
  if( ( format == LIBEWF_FORMAT_EWF )
11189
0
   || ( format == LIBEWF_FORMAT_SMART ) )
11190
0
  {
11191
    /* Wraps .s01 to .s99 and then to .saa up to .zzz
11192
     * ( ( ( 's' to 'z' = 8 ) * 26 * 26 ) + 99 ) = 5507
11193
     */
11194
0
    internal_handle->write_io_handle->maximum_number_of_segments = (uint32_t) 5507;
11195
0
    internal_handle->io_handle->segment_file_type                = LIBEWF_SEGMENT_FILE_TYPE_EWF1_SMART;
11196
0
  }
11197
0
  else if( format == LIBEWF_FORMAT_V2_ENCASE7 )
11198
0
  {
11199
    /* Wraps .Ex01 to .Ex99 and then to .ExAA up to .EzZZ
11200
     * ( ( ( 'x' to 'z' = 3 ) * 26 * 26 ) + 99 ) = 2127
11201
     */
11202
0
    internal_handle->write_io_handle->maximum_number_of_segments = (uint32_t) 2127;
11203
0
    internal_handle->io_handle->segment_file_type                = LIBEWF_SEGMENT_FILE_TYPE_EWF2;
11204
0
  }
11205
0
  else
11206
0
  {
11207
    /* Wraps .E01 to .E99 and then to .EAA up to .ZZZ
11208
     * ( ( ( 'E' to 'Z' or 'e' to 'z' = 22 ) * 26 * 26 ) + 99 ) = 14971
11209
     */
11210
0
    internal_handle->write_io_handle->maximum_number_of_segments = (uint32_t) 14971;
11211
0
    internal_handle->io_handle->segment_file_type                = LIBEWF_SEGMENT_FILE_TYPE_EWF1;
11212
0
  }
11213
  /* Determine the maximum number of table entries
11214
   */
11215
0
  if( ( format == LIBEWF_FORMAT_ENCASE6 )
11216
0
   || ( format == LIBEWF_FORMAT_ENCASE7 ) )
11217
0
  {
11218
0
    internal_handle->write_io_handle->maximum_segment_file_size  = INT64_MAX;
11219
0
    internal_handle->write_io_handle->maximum_chunks_per_section = LIBEWF_MAXIMUM_TABLE_ENTRIES_ENCASE6;
11220
0
  }
11221
0
  else if( format == LIBEWF_FORMAT_V2_ENCASE7 )
11222
0
  {
11223
0
    internal_handle->write_io_handle->maximum_segment_file_size  = INT64_MAX;
11224
0
    internal_handle->write_io_handle->maximum_chunks_per_section = LIBEWF_MAXIMUM_TABLE_ENTRIES;
11225
0
  }
11226
0
  else if( format == LIBEWF_FORMAT_EWFX )
11227
0
  {
11228
0
    internal_handle->write_io_handle->maximum_segment_file_size  = INT32_MAX;
11229
0
    internal_handle->write_io_handle->maximum_chunks_per_section = LIBEWF_MAXIMUM_TABLE_ENTRIES;
11230
0
  }
11231
0
  else
11232
0
  {
11233
0
    internal_handle->write_io_handle->maximum_segment_file_size  = INT32_MAX;
11234
0
    internal_handle->write_io_handle->maximum_chunks_per_section = LIBEWF_MAXIMUM_TABLE_ENTRIES_EWF;
11235
0
  }
11236
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11237
0
  if( libcthreads_read_write_lock_release_for_write(
11238
0
       internal_handle->read_write_lock,
11239
0
       error ) != 1 )
11240
0
  {
11241
0
    libcerror_error_set(
11242
0
     error,
11243
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11244
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11245
0
     "%s: unable to release read/write lock for writing.",
11246
0
     function );
11247
11248
0
    return( -1 );
11249
0
  }
11250
0
#endif
11251
0
  return( 1 );
11252
11253
0
on_error:
11254
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11255
0
  libcthreads_read_write_lock_release_for_write(
11256
0
   internal_handle->read_write_lock,
11257
0
   NULL );
11258
0
#endif
11259
0
  return( -1 );
11260
0
}
11261
11262
/* Retrieves the segment file version
11263
 * Returns 1 if successful or -1 on error
11264
 */
11265
int libewf_handle_get_segment_file_version(
11266
     libewf_handle_t *handle,
11267
     uint8_t *major_version,
11268
     uint8_t *minor_version,
11269
     libcerror_error_t **error )
11270
1.16k
{
11271
1.16k
  libewf_internal_handle_t *internal_handle = NULL;
11272
1.16k
  static char *function                     = "libewf_handle_get_segment_file_version";
11273
11274
1.16k
  if( handle == NULL )
11275
0
  {
11276
0
    libcerror_error_set(
11277
0
     error,
11278
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11279
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
11280
0
     "%s: invalid handle.",
11281
0
     function );
11282
11283
0
    return( -1 );
11284
0
  }
11285
1.16k
  internal_handle = (libewf_internal_handle_t *) handle;
11286
11287
1.16k
  if( internal_handle->io_handle == NULL )
11288
0
  {
11289
0
    libcerror_error_set(
11290
0
     error,
11291
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11292
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
11293
0
     "%s: invalid handle - missing IO handle.",
11294
0
     function );
11295
11296
0
    return( -1 );
11297
0
  }
11298
1.16k
  if( major_version == NULL )
11299
0
  {
11300
0
    libcerror_error_set(
11301
0
     error,
11302
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11303
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
11304
0
     "%s: invalid major version.",
11305
0
     function );
11306
11307
0
    return( -1 );
11308
0
  }
11309
1.16k
  if( minor_version == NULL )
11310
0
  {
11311
0
    libcerror_error_set(
11312
0
     error,
11313
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11314
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
11315
0
     "%s: invalid minor version.",
11316
0
     function );
11317
11318
0
    return( -1 );
11319
0
  }
11320
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11321
1.16k
  if( libcthreads_read_write_lock_grab_for_read(
11322
1.16k
       internal_handle->read_write_lock,
11323
1.16k
       error ) != 1 )
11324
0
  {
11325
0
    libcerror_error_set(
11326
0
     error,
11327
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11328
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11329
0
     "%s: unable to grab read/write lock for reading.",
11330
0
     function );
11331
11332
0
    return( -1 );
11333
0
  }
11334
1.16k
#endif
11335
1.16k
  *major_version = internal_handle->io_handle->major_version;
11336
1.16k
  *minor_version = internal_handle->io_handle->minor_version;
11337
11338
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11339
1.16k
  if( libcthreads_read_write_lock_release_for_read(
11340
1.16k
       internal_handle->read_write_lock,
11341
1.16k
       error ) != 1 )
11342
0
  {
11343
0
    libcerror_error_set(
11344
0
     error,
11345
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11346
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11347
0
     "%s: unable to release read/write lock for reading.",
11348
0
     function );
11349
11350
0
    return( -1 );
11351
0
  }
11352
1.16k
#endif
11353
1.16k
  return( 1 );
11354
1.16k
}
11355
11356
/* Retrieves the segment file set identifier
11357
 * The identifier is a GUID and is 16 bytes of size
11358
 * Returns 1 if successful or -1 on error
11359
 */
11360
int libewf_handle_get_segment_file_set_identifier(
11361
     libewf_handle_t *handle,
11362
     uint8_t *set_identifier,
11363
     size_t size,
11364
     libcerror_error_t **error )
11365
1.16k
{
11366
1.16k
  libewf_internal_handle_t *internal_handle = NULL;
11367
1.16k
  static char *function                     = "libewf_handle_get_segment_file_set_identifier";
11368
11369
1.16k
  if( handle == NULL )
11370
0
  {
11371
0
    libcerror_error_set(
11372
0
     error,
11373
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11374
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
11375
0
     "%s: invalid handle.",
11376
0
     function );
11377
11378
0
    return( -1 );
11379
0
  }
11380
1.16k
  internal_handle = (libewf_internal_handle_t *) handle;
11381
11382
1.16k
  if( internal_handle->media_values == NULL )
11383
0
  {
11384
0
    libcerror_error_set(
11385
0
     error,
11386
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11387
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
11388
0
     "%s: invalid handle - missing media values.",
11389
0
     function );
11390
11391
0
    return( -1 );
11392
0
  }
11393
1.16k
  if( set_identifier == NULL )
11394
0
  {
11395
0
    libcerror_error_set(
11396
0
     error,
11397
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11398
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
11399
0
     "%s: invalid set identifier.",
11400
0
     function );
11401
11402
0
    return( -1 );
11403
0
  }
11404
1.16k
  if( size < 16 )
11405
0
  {
11406
0
    libcerror_error_set(
11407
0
     error,
11408
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11409
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
11410
0
     "%s: set identifier too small.",
11411
0
     function );
11412
11413
0
    return( -1 );
11414
0
  }
11415
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11416
1.16k
  if( libcthreads_read_write_lock_grab_for_read(
11417
1.16k
       internal_handle->read_write_lock,
11418
1.16k
       error ) != 1 )
11419
0
  {
11420
0
    libcerror_error_set(
11421
0
     error,
11422
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11423
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11424
0
     "%s: unable to grab read/write lock for reading.",
11425
0
     function );
11426
11427
0
    return( -1 );
11428
0
  }
11429
1.16k
#endif
11430
1.16k
  if( memory_copy(
11431
1.16k
       set_identifier,
11432
1.16k
       internal_handle->media_values->set_identifier,
11433
1.16k
       16 ) == NULL )
11434
0
  {
11435
0
    libcerror_error_set(
11436
0
     error,
11437
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
11438
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
11439
0
     "%s: unable to set set identifier.",
11440
0
     function );
11441
11442
0
    goto on_error;
11443
0
  }
11444
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11445
1.16k
  if( libcthreads_read_write_lock_release_for_read(
11446
1.16k
       internal_handle->read_write_lock,
11447
1.16k
       error ) != 1 )
11448
0
  {
11449
0
    libcerror_error_set(
11450
0
     error,
11451
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11452
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11453
0
     "%s: unable to release read/write lock for reading.",
11454
0
     function );
11455
11456
0
    return( -1 );
11457
0
  }
11458
1.16k
#endif
11459
1.16k
  return( 1 );
11460
11461
0
on_error:
11462
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11463
0
  libcthreads_read_write_lock_release_for_read(
11464
0
   internal_handle->read_write_lock,
11465
0
   NULL );
11466
0
#endif
11467
0
  return( -1 );
11468
1.16k
}
11469
11470
/* Sets the segment file set identifier
11471
 * The identifier is a GUID and is 16 bytes of size
11472
 * Returns 1 if successful or -1 on error
11473
 */
11474
int libewf_handle_set_segment_file_set_identifier(
11475
     libewf_handle_t *handle,
11476
     const uint8_t *set_identifier,
11477
     size_t size,
11478
     libcerror_error_t **error )
11479
0
{
11480
0
  libewf_internal_handle_t *internal_handle = NULL;
11481
0
  static char *function                     = "libewf_handle_set_segment_file_set_identifier";
11482
11483
0
  if( handle == NULL )
11484
0
  {
11485
0
    libcerror_error_set(
11486
0
     error,
11487
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11488
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
11489
0
     "%s: invalid handle.",
11490
0
     function );
11491
11492
0
    return( -1 );
11493
0
  }
11494
0
  internal_handle = (libewf_internal_handle_t *) handle;
11495
11496
0
  if( internal_handle->media_values == NULL )
11497
0
  {
11498
0
    libcerror_error_set(
11499
0
     error,
11500
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11501
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
11502
0
     "%s: invalid handle - missing media values.",
11503
0
     function );
11504
11505
0
    return( -1 );
11506
0
  }
11507
0
  if( set_identifier == NULL )
11508
0
  {
11509
0
    libcerror_error_set(
11510
0
     error,
11511
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11512
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
11513
0
     "%s: invalid set identifier.",
11514
0
     function );
11515
11516
0
    return( -1 );
11517
0
  }
11518
0
  if( size < 16 )
11519
0
  {
11520
0
    libcerror_error_set(
11521
0
     error,
11522
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11523
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
11524
0
     "%s: set identifier too small.",
11525
0
     function );
11526
11527
0
    return( -1 );
11528
0
  }
11529
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11530
0
  if( libcthreads_read_write_lock_grab_for_write(
11531
0
       internal_handle->read_write_lock,
11532
0
       error ) != 1 )
11533
0
  {
11534
0
    libcerror_error_set(
11535
0
     error,
11536
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11537
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11538
0
     "%s: unable to grab read/write lock for writing.",
11539
0
     function );
11540
11541
0
    return( -1 );
11542
0
  }
11543
0
#endif
11544
0
  if( ( internal_handle->read_io_handle != NULL )
11545
0
   || ( internal_handle->write_io_handle == NULL )
11546
0
   || ( internal_handle->write_io_handle->values_initialized != 0 ) )
11547
0
  {
11548
0
    libcerror_error_set(
11549
0
     error,
11550
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11551
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11552
0
     "%s: set identifier cannot be changed.",
11553
0
     function );
11554
11555
0
    goto on_error;
11556
0
  }
11557
0
  if( memory_copy(
11558
0
       internal_handle->media_values->set_identifier,
11559
0
       set_identifier,
11560
0
       16 ) == NULL )
11561
0
  {
11562
0
    libcerror_error_set(
11563
0
     error,
11564
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
11565
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
11566
0
     "%s: unable to copy set indentifier.",
11567
0
     function );
11568
11569
0
    goto on_error;
11570
0
  }
11571
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11572
0
  if( libcthreads_read_write_lock_release_for_write(
11573
0
       internal_handle->read_write_lock,
11574
0
       error ) != 1 )
11575
0
  {
11576
0
    libcerror_error_set(
11577
0
     error,
11578
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11579
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11580
0
     "%s: unable to release read/write lock for writing.",
11581
0
     function );
11582
11583
0
    return( -1 );
11584
0
  }
11585
0
#endif
11586
0
  return( 1 );
11587
11588
0
on_error:
11589
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11590
0
  libcthreads_read_write_lock_release_for_write(
11591
0
   internal_handle->read_write_lock,
11592
0
   NULL );
11593
0
#endif
11594
0
  return( -1 );
11595
0
}
11596
11597
/* Retrieves the MD5 hash
11598
 * Returns 1 if successful, 0 if not set or -1 on error
11599
 */
11600
int libewf_handle_get_md5_hash(
11601
     libewf_handle_t *handle,
11602
     uint8_t *md5_hash,
11603
     size_t size,
11604
     libcerror_error_t **error )
11605
1.16k
{
11606
1.16k
  libewf_internal_handle_t *internal_handle = NULL;
11607
1.16k
  static char *function                     = "libewf_handle_get_md5_hash";
11608
1.16k
  int result                                = 0;
11609
11610
1.16k
  if( handle == NULL )
11611
0
  {
11612
0
    libcerror_error_set(
11613
0
     error,
11614
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11615
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
11616
0
     "%s: invalid handle.",
11617
0
     function );
11618
11619
0
    return( -1 );
11620
0
  }
11621
1.16k
  internal_handle = (libewf_internal_handle_t *) handle;
11622
11623
1.16k
  if( internal_handle->hash_sections == NULL )
11624
0
  {
11625
0
    libcerror_error_set(
11626
0
     error,
11627
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11628
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
11629
0
     "%s: invalid handle - missing hash sections.",
11630
0
     function );
11631
11632
0
    return( -1 );
11633
0
  }
11634
1.16k
  if( md5_hash == NULL )
11635
0
  {
11636
0
    libcerror_error_set(
11637
0
     error,
11638
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11639
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
11640
0
     "%s: invalid MD5 hash.",
11641
0
     function );
11642
11643
0
    return( -1 );
11644
0
  }
11645
1.16k
  if( size < 16 )
11646
0
  {
11647
0
    libcerror_error_set(
11648
0
     error,
11649
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11650
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
11651
0
     "%s: MD5 hash too small.",
11652
0
     function );
11653
11654
0
    return( -1 );
11655
0
  }
11656
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11657
1.16k
  if( libcthreads_read_write_lock_grab_for_write(
11658
1.16k
       internal_handle->read_write_lock,
11659
1.16k
       error ) != 1 )
11660
0
  {
11661
0
    libcerror_error_set(
11662
0
     error,
11663
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11664
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11665
0
     "%s: unable to grab read/write lock for writing.",
11666
0
     function );
11667
11668
0
    return( -1 );
11669
0
  }
11670
1.16k
#endif
11671
1.16k
  if( ( internal_handle->hash_sections->md5_hash_set == 0 )
11672
1.15k
   && ( internal_handle->hash_values != NULL ) )
11673
0
  {
11674
0
    if( libewf_hash_values_generate_md5_hash(
11675
0
         internal_handle->hash_values,
11676
0
         internal_handle->hash_sections->md5_hash,
11677
0
         16,
11678
0
         &( internal_handle->hash_sections->md5_hash_set ),
11679
0
         error ) != 1 )
11680
0
    {
11681
0
      libcerror_error_set(
11682
0
       error,
11683
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
11684
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11685
0
       "%s: unable to parse MD5 hash value for its value.",
11686
0
       function );
11687
11688
0
      goto on_error;
11689
0
    }
11690
0
  }
11691
1.16k
  if( internal_handle->hash_sections->md5_digest_set != 0 )
11692
0
  {
11693
0
    if( memory_copy(
11694
0
         md5_hash,
11695
0
         internal_handle->hash_sections->md5_digest,
11696
0
         16 ) == NULL )
11697
0
    {
11698
0
      libcerror_error_set(
11699
0
       error,
11700
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
11701
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
11702
0
       "%s: unable to copy MD5 digest.",
11703
0
       function );
11704
11705
0
      goto on_error;
11706
0
    }
11707
0
    result = 1;
11708
0
  }
11709
1.16k
  else if( internal_handle->hash_sections->md5_hash_set != 0 )
11710
3
  {
11711
3
    if( memory_copy(
11712
3
         md5_hash,
11713
3
         internal_handle->hash_sections->md5_hash,
11714
3
         16 ) == NULL )
11715
0
    {
11716
0
      libcerror_error_set(
11717
0
       error,
11718
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
11719
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
11720
0
       "%s: unable to copy MD5 hash.",
11721
0
       function );
11722
11723
0
      goto on_error;
11724
0
    }
11725
3
    result = 1;
11726
3
  }
11727
1.16k
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11728
1.16k
  if( libcthreads_read_write_lock_release_for_write(
11729
1.16k
       internal_handle->read_write_lock,
11730
1.16k
       error ) != 1 )
11731
0
  {
11732
0
    libcerror_error_set(
11733
0
     error,
11734
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11735
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11736
0
     "%s: unable to release read/write lock for writing.",
11737
0
     function );
11738
11739
0
    return( -1 );
11740
0
  }
11741
1.16k
#endif
11742
1.16k
  return( result );
11743
11744
0
on_error:
11745
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11746
0
  libcthreads_read_write_lock_release_for_write(
11747
0
   internal_handle->read_write_lock,
11748
0
   NULL );
11749
0
#endif
11750
0
  return( -1 );
11751
1.16k
}
11752
11753
/* Sets the MD5 hash
11754
 * Returns 1 if successful or -1 on error
11755
 */
11756
int libewf_handle_set_md5_hash(
11757
     libewf_handle_t *handle,
11758
     const uint8_t *md5_hash,
11759
     size_t size,
11760
     libcerror_error_t **error )
11761
0
{
11762
0
  libewf_internal_handle_t *internal_handle = NULL;
11763
0
  static char *function                     = "libewf_handle_set_md5_hash";
11764
11765
0
  if( handle == NULL )
11766
0
  {
11767
0
    libcerror_error_set(
11768
0
     error,
11769
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11770
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
11771
0
     "%s: invalid handle.",
11772
0
     function );
11773
11774
0
    return( -1 );
11775
0
  }
11776
0
  internal_handle = (libewf_internal_handle_t *) handle;
11777
11778
0
  if( internal_handle->hash_sections == NULL )
11779
0
  {
11780
0
    libcerror_error_set(
11781
0
     error,
11782
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11783
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
11784
0
     "%s: invalid handle - missing hash sections.",
11785
0
     function );
11786
11787
0
    return( -1 );
11788
0
  }
11789
0
  if( md5_hash == NULL )
11790
0
  {
11791
0
    libcerror_error_set(
11792
0
     error,
11793
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11794
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
11795
0
     "%s: invalid MD5 hash.",
11796
0
     function );
11797
11798
0
    return( -1 );
11799
0
  }
11800
0
  if( size < 16 )
11801
0
  {
11802
0
    libcerror_error_set(
11803
0
     error,
11804
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11805
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
11806
0
     "%s: MD5 hash too small.",
11807
0
     function );
11808
11809
0
    return( -1 );
11810
0
  }
11811
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11812
0
  if( libcthreads_read_write_lock_grab_for_write(
11813
0
       internal_handle->read_write_lock,
11814
0
       error ) != 1 )
11815
0
  {
11816
0
    libcerror_error_set(
11817
0
     error,
11818
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11819
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11820
0
     "%s: unable to grab read/write lock for writing.",
11821
0
     function );
11822
11823
0
    return( -1 );
11824
0
  }
11825
0
#endif
11826
0
  if( ( internal_handle->read_io_handle != NULL )
11827
0
   || ( internal_handle->hash_sections->md5_hash_set != 0 )
11828
0
   || ( internal_handle->hash_sections->md5_digest_set != 0 ) )
11829
0
  {
11830
0
    libcerror_error_set(
11831
0
     error,
11832
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11833
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11834
0
     "%s: MD5 hash cannot be changed.",
11835
0
     function );
11836
11837
0
    goto on_error;
11838
0
  }
11839
0
  if( internal_handle->hash_values == NULL )
11840
0
  {
11841
0
    if( libewf_hash_values_initialize(
11842
0
         &( internal_handle->hash_values ),
11843
0
         error ) != 1 )
11844
0
    {
11845
0
      libcerror_error_set(
11846
0
       error,
11847
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
11848
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
11849
0
       "%s: unable to create hash values.",
11850
0
       function );
11851
11852
0
      goto on_error;
11853
0
    }
11854
0
    internal_handle->hash_values_parsed = 1;
11855
0
  }
11856
0
  if( memory_copy(
11857
0
       internal_handle->hash_sections->md5_hash,
11858
0
       md5_hash,
11859
0
       16 ) == NULL )
11860
0
  {
11861
0
    libcerror_error_set(
11862
0
     error,
11863
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
11864
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
11865
0
     "%s: unable to set MD5 hash.",
11866
0
     function );
11867
11868
0
    goto on_error;
11869
0
  }
11870
0
  internal_handle->hash_sections->md5_hash_set = 1;
11871
11872
0
  if( memory_copy(
11873
0
       internal_handle->hash_sections->md5_digest,
11874
0
       md5_hash,
11875
0
       16 ) == NULL )
11876
0
  {
11877
0
    libcerror_error_set(
11878
0
     error,
11879
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
11880
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
11881
0
     "%s: unable to set MD5 hash.",
11882
0
     function );
11883
11884
0
    goto on_error;
11885
0
  }
11886
0
  internal_handle->hash_sections->md5_digest_set = 1;
11887
11888
0
  if( libewf_hash_values_parse_md5_hash(
11889
0
       internal_handle->hash_values,
11890
0
       md5_hash,
11891
0
       16,
11892
0
       error ) != 1 )
11893
0
  {
11894
0
    libcerror_error_set(
11895
0
     error,
11896
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11897
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11898
0
     "%s: unable to parse MD5 hash for its value.",
11899
0
     function );
11900
11901
0
    goto on_error;
11902
0
  }
11903
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11904
0
  if( libcthreads_read_write_lock_release_for_write(
11905
0
       internal_handle->read_write_lock,
11906
0
       error ) != 1 )
11907
0
  {
11908
0
    libcerror_error_set(
11909
0
     error,
11910
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11911
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11912
0
     "%s: unable to release read/write lock for writing.",
11913
0
     function );
11914
11915
0
    return( -1 );
11916
0
  }
11917
0
#endif
11918
0
  return( 1 );
11919
11920
0
on_error:
11921
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11922
0
  libcthreads_read_write_lock_release_for_write(
11923
0
   internal_handle->read_write_lock,
11924
0
   NULL );
11925
0
#endif
11926
0
  return( -1 );
11927
0
}
11928
11929
/* Retrieves the SHA1 hash
11930
 * Returns 1 if successful, 0 if not set or -1 on error
11931
 */
11932
int libewf_handle_get_sha1_hash(
11933
     libewf_handle_t *handle,
11934
     uint8_t *sha1_hash,
11935
     size_t size,
11936
     libcerror_error_t **error )
11937
3
{
11938
3
  libewf_internal_handle_t *internal_handle = NULL;
11939
3
  static char *function                     = "libewf_handle_get_sha1_hash";
11940
3
  int result                                = 0;
11941
11942
3
  if( handle == NULL )
11943
0
  {
11944
0
    libcerror_error_set(
11945
0
     error,
11946
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11947
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
11948
0
     "%s: invalid handle.",
11949
0
     function );
11950
11951
0
    return( -1 );
11952
0
  }
11953
3
  internal_handle = (libewf_internal_handle_t *) handle;
11954
11955
3
  if( internal_handle->hash_sections == NULL )
11956
0
  {
11957
0
    libcerror_error_set(
11958
0
     error,
11959
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11960
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
11961
0
     "%s: invalid handle - missing hash sections.",
11962
0
     function );
11963
11964
0
    return( -1 );
11965
0
  }
11966
3
  if( sha1_hash == NULL )
11967
0
  {
11968
0
    libcerror_error_set(
11969
0
     error,
11970
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11971
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
11972
0
     "%s: invalid SHA1 hash.",
11973
0
     function );
11974
11975
0
    return( -1 );
11976
0
  }
11977
3
  if( size < 20 )
11978
0
  {
11979
0
    libcerror_error_set(
11980
0
     error,
11981
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
11982
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
11983
0
     "%s: SHA1 hash too small.",
11984
0
     function );
11985
11986
0
    return( -1 );
11987
0
  }
11988
3
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
11989
3
  if( libcthreads_read_write_lock_grab_for_write(
11990
3
       internal_handle->read_write_lock,
11991
3
       error ) != 1 )
11992
0
  {
11993
0
    libcerror_error_set(
11994
0
     error,
11995
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
11996
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
11997
0
     "%s: unable to grab read/write lock for writing.",
11998
0
     function );
11999
12000
0
    return( -1 );
12001
0
  }
12002
3
#endif
12003
3
  if( ( internal_handle->hash_sections->sha1_digest_set == 0 )
12004
3
   && ( internal_handle->hash_values != NULL ) )
12005
0
  {
12006
0
    if( libewf_hash_values_generate_sha1_hash(
12007
0
         internal_handle->hash_values,
12008
0
         internal_handle->hash_sections->sha1_digest,
12009
0
         20,
12010
0
         &( internal_handle->hash_sections->sha1_digest_set ),
12011
0
         error ) != 1 )
12012
0
    {
12013
0
      libcerror_error_set(
12014
0
       error,
12015
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
12016
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12017
0
       "%s: unable to parse MD5 hash value for its value.",
12018
0
       function );
12019
12020
0
      goto on_error;
12021
0
    }
12022
0
  }
12023
3
  if( internal_handle->hash_sections->sha1_digest_set != 0 )
12024
0
  {
12025
0
    if( memory_copy(
12026
0
         sha1_hash,
12027
0
         internal_handle->hash_sections->sha1_digest,
12028
0
         20 ) == NULL )
12029
0
    {
12030
0
      libcerror_error_set(
12031
0
       error,
12032
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
12033
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
12034
0
       "%s: unable to copy SHA1 digest.",
12035
0
       function );
12036
12037
0
      goto on_error;
12038
0
    }
12039
0
    result = 1;
12040
0
  }
12041
3
  else if( internal_handle->hash_sections->sha1_hash_set != 0 )
12042
0
  {
12043
0
    if( memory_copy(
12044
0
         sha1_hash,
12045
0
         internal_handle->hash_sections->sha1_hash,
12046
0
         20 ) == NULL )
12047
0
    {
12048
0
      libcerror_error_set(
12049
0
       error,
12050
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
12051
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
12052
0
       "%s: unable to copy SHA1 hash.",
12053
0
       function );
12054
12055
0
      goto on_error;
12056
0
    }
12057
0
    result = 1;
12058
0
  }
12059
3
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12060
3
  if( libcthreads_read_write_lock_release_for_write(
12061
3
       internal_handle->read_write_lock,
12062
3
       error ) != 1 )
12063
0
  {
12064
0
    libcerror_error_set(
12065
0
     error,
12066
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12067
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12068
0
     "%s: unable to release read/write lock for writing.",
12069
0
     function );
12070
12071
0
    return( -1 );
12072
0
  }
12073
3
#endif
12074
3
  return( result );
12075
12076
0
on_error:
12077
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12078
0
  libcthreads_read_write_lock_release_for_write(
12079
0
   internal_handle->read_write_lock,
12080
0
   NULL );
12081
0
#endif
12082
0
  return( -1 );
12083
3
}
12084
12085
/* Sets the SHA1 hash
12086
 * Returns 1 if successful or -1 on error
12087
 */
12088
int libewf_handle_set_sha1_hash(
12089
     libewf_handle_t *handle,
12090
     const uint8_t *sha1_hash,
12091
     size_t size,
12092
     libcerror_error_t **error )
12093
0
{
12094
0
  libewf_internal_handle_t *internal_handle = NULL;
12095
0
  static char *function                     = "libewf_handle_set_sha1_hash";
12096
12097
0
  if( handle == NULL )
12098
0
  {
12099
0
    libcerror_error_set(
12100
0
     error,
12101
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
12102
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
12103
0
     "%s: invalid handle.",
12104
0
     function );
12105
12106
0
    return( -1 );
12107
0
  }
12108
0
  internal_handle = (libewf_internal_handle_t *) handle;
12109
12110
0
  if( internal_handle->hash_sections == NULL )
12111
0
  {
12112
0
    libcerror_error_set(
12113
0
     error,
12114
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12115
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
12116
0
     "%s: invalid handle - missing hash sections.",
12117
0
     function );
12118
12119
0
    return( -1 );
12120
0
  }
12121
0
  if( sha1_hash == NULL )
12122
0
  {
12123
0
    libcerror_error_set(
12124
0
     error,
12125
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
12126
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
12127
0
     "%s: invalid SHA1 hash.",
12128
0
     function );
12129
12130
0
    return( -1 );
12131
0
  }
12132
0
  if( size < 20 )
12133
0
  {
12134
0
    libcerror_error_set(
12135
0
     error,
12136
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
12137
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
12138
0
     "%s: SHA1 hash too small.",
12139
0
     function );
12140
12141
0
    return( -1 );
12142
0
  }
12143
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12144
0
  if( libcthreads_read_write_lock_grab_for_write(
12145
0
       internal_handle->read_write_lock,
12146
0
       error ) != 1 )
12147
0
  {
12148
0
    libcerror_error_set(
12149
0
     error,
12150
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12151
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12152
0
     "%s: unable to grab read/write lock for writing.",
12153
0
     function );
12154
12155
0
    return( -1 );
12156
0
  }
12157
0
#endif
12158
0
  if( ( internal_handle->read_io_handle != NULL )
12159
0
   || ( internal_handle->hash_sections->sha1_hash_set != 0 )
12160
0
   || ( internal_handle->hash_sections->sha1_digest_set != 0 ) )
12161
0
  {
12162
0
    libcerror_error_set(
12163
0
     error,
12164
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12165
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12166
0
     "%s: SHA1 hash cannot be changed.",
12167
0
     function );
12168
12169
0
    goto on_error;
12170
0
  }
12171
0
  if( internal_handle->hash_values == NULL )
12172
0
  {
12173
0
    if( libewf_hash_values_initialize(
12174
0
         &( internal_handle->hash_values ),
12175
0
         error ) != 1 )
12176
0
    {
12177
0
      libcerror_error_set(
12178
0
       error,
12179
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
12180
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
12181
0
       "%s: unable to create hash values.",
12182
0
       function );
12183
12184
0
      goto on_error;
12185
0
    }
12186
0
    internal_handle->hash_values_parsed = 1;
12187
0
  }
12188
0
  if( memory_copy(
12189
0
       internal_handle->hash_sections->sha1_hash,
12190
0
       sha1_hash,
12191
0
       20 ) == NULL )
12192
0
  {
12193
0
    libcerror_error_set(
12194
0
     error,
12195
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
12196
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
12197
0
     "%s: unable to set SHA1 hash.",
12198
0
     function );
12199
12200
0
    goto on_error;
12201
0
  }
12202
0
  internal_handle->hash_sections->sha1_hash_set = 1;
12203
12204
0
  if( memory_copy(
12205
0
       internal_handle->hash_sections->sha1_digest,
12206
0
       sha1_hash,
12207
0
       20 ) == NULL )
12208
0
  {
12209
0
    libcerror_error_set(
12210
0
     error,
12211
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
12212
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
12213
0
     "%s: unable to set SHA1 hash.",
12214
0
     function );
12215
12216
0
    goto on_error;
12217
0
  }
12218
0
  internal_handle->hash_sections->sha1_digest_set = 1;
12219
12220
0
  if( libewf_hash_values_parse_sha1_hash(
12221
0
       internal_handle->hash_values,
12222
0
       sha1_hash,
12223
0
       20,
12224
0
       error ) != 1 )
12225
0
  {
12226
0
    libcerror_error_set(
12227
0
     error,
12228
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12229
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12230
0
     "%s: unable to parse SHA1 hash for its value.",
12231
0
     function );
12232
12233
0
    goto on_error;
12234
0
  }
12235
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12236
0
  if( libcthreads_read_write_lock_release_for_write(
12237
0
       internal_handle->read_write_lock,
12238
0
       error ) != 1 )
12239
0
  {
12240
0
    libcerror_error_set(
12241
0
     error,
12242
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12243
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12244
0
     "%s: unable to release read/write lock for writing.",
12245
0
     function );
12246
12247
0
    return( -1 );
12248
0
  }
12249
0
#endif
12250
0
  return( 1 );
12251
12252
0
on_error:
12253
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12254
0
  libcthreads_read_write_lock_release_for_write(
12255
0
   internal_handle->read_write_lock,
12256
0
   NULL );
12257
0
#endif
12258
0
  return( -1 );
12259
0
}
12260
12261
/* Sets the read zero chunk on error
12262
 * The chunk is not zeroed if read raw is used
12263
 * Returns 1 if successful or -1 on error
12264
 */
12265
int libewf_handle_set_read_zero_chunk_on_error(
12266
     libewf_handle_t *handle,
12267
     uint8_t zero_on_error,
12268
     libcerror_error_t **error )
12269
0
{
12270
0
  libewf_internal_handle_t *internal_handle = NULL;
12271
0
  static char *function                     = "libewf_handle_set_read_zero_chunk_on_error";
12272
12273
0
  if( handle == NULL )
12274
0
  {
12275
0
    libcerror_error_set(
12276
0
     error,
12277
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
12278
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
12279
0
     "%s: invalid handle.",
12280
0
     function );
12281
12282
0
    return( -1 );
12283
0
  }
12284
0
  internal_handle = (libewf_internal_handle_t *) handle;
12285
12286
0
  if( internal_handle->io_handle == NULL )
12287
0
  {
12288
0
    libcerror_error_set(
12289
0
     error,
12290
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12291
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
12292
0
     "%s: invalid handle - missing IO handle.",
12293
0
     function );
12294
12295
0
    return( -1 );
12296
0
  }
12297
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12298
0
  if( libcthreads_read_write_lock_grab_for_write(
12299
0
       internal_handle->read_write_lock,
12300
0
       error ) != 1 )
12301
0
  {
12302
0
    libcerror_error_set(
12303
0
     error,
12304
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12305
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12306
0
     "%s: unable to grab read/write lock for writing.",
12307
0
     function );
12308
12309
0
    return( -1 );
12310
0
  }
12311
0
#endif
12312
0
  internal_handle->io_handle->zero_on_error = zero_on_error;
12313
12314
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12315
0
  if( libcthreads_read_write_lock_release_for_write(
12316
0
       internal_handle->read_write_lock,
12317
0
       error ) != 1 )
12318
0
  {
12319
0
    libcerror_error_set(
12320
0
     error,
12321
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12322
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12323
0
     "%s: unable to release read/write lock for writing.",
12324
0
     function );
12325
12326
0
    return( -1 );
12327
0
  }
12328
0
#endif
12329
0
  return( 1 );
12330
0
}
12331
12332
/* Copies the media values from the source to the destination handle
12333
 * Returns 1 if successful or -1 on error
12334
 */
12335
int libewf_handle_copy_media_values(
12336
     libewf_handle_t *destination_handle,
12337
     libewf_handle_t *source_handle,
12338
     libcerror_error_t **error )
12339
0
{
12340
0
  libewf_internal_handle_t *internal_destination_handle = NULL;
12341
0
  libewf_internal_handle_t *internal_source_handle      = NULL;
12342
0
  static char *function                                 = "libewf_handle_copy_media_values";
12343
12344
0
  if( destination_handle == NULL )
12345
0
  {
12346
0
    libcerror_error_set(
12347
0
     error,
12348
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
12349
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
12350
0
     "%s: invalid destination handle.",
12351
0
     function );
12352
12353
0
    return( -1 );
12354
0
  }
12355
0
  if( source_handle == NULL )
12356
0
  {
12357
0
    libcerror_error_set(
12358
0
     error,
12359
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
12360
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
12361
0
     "%s: invalid source handle.",
12362
0
     function );
12363
12364
0
    return( -1 );
12365
0
  }
12366
0
  internal_destination_handle = (libewf_internal_handle_t *) destination_handle;
12367
0
  internal_source_handle      = (libewf_internal_handle_t *) source_handle;
12368
12369
0
  if( internal_source_handle->media_values == NULL )
12370
0
  {
12371
0
    libcerror_error_set(
12372
0
     error,
12373
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12374
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
12375
0
     "%s: invalid source handle - missing media values.",
12376
0
     function );
12377
12378
0
    return( -1 );
12379
0
  }
12380
0
  if( internal_destination_handle->media_values == NULL )
12381
0
  {
12382
0
    libcerror_error_set(
12383
0
     error,
12384
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12385
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
12386
0
     "%s: invalid destination handle - missing media values.",
12387
0
     function );
12388
12389
0
    return( -1 );
12390
0
  }
12391
0
  if( memory_copy(
12392
0
       internal_destination_handle->media_values,
12393
0
       internal_source_handle->media_values,
12394
0
       sizeof( libewf_media_values_t ) ) == NULL )
12395
0
  {
12396
0
    libcerror_error_set(
12397
0
     error,
12398
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
12399
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
12400
0
     "%s: unable to copy media values.",
12401
0
     function );
12402
12403
0
    return( -1 );
12404
0
  }
12405
0
  return( 1 );
12406
0
}
12407
12408
/* Retrieves the number of acquiry errors
12409
 * Returns 1 if successful or -1 on error
12410
 */
12411
int libewf_handle_get_number_of_acquiry_errors(
12412
     libewf_handle_t *handle,
12413
     uint32_t *number_of_errors,
12414
     libcerror_error_t **error )
12415
0
{
12416
0
  libewf_internal_handle_t *internal_handle = NULL;
12417
0
  static char *function                     = "libewf_handle_get_number_of_acquiry_errors";
12418
0
  int number_of_elements                    = 0;
12419
12420
0
  if( handle == NULL )
12421
0
  {
12422
0
    libcerror_error_set(
12423
0
     error,
12424
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
12425
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
12426
0
     "%s: invalid handle.",
12427
0
     function );
12428
12429
0
    return( -1 );
12430
0
  }
12431
0
  internal_handle = (libewf_internal_handle_t *) handle;
12432
12433
0
  if( number_of_errors == NULL )
12434
0
  {
12435
0
    libcerror_error_set(
12436
0
     error,
12437
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
12438
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
12439
0
     "%s: invalid number of errors.",
12440
0
     function );
12441
12442
0
    return( -1 );
12443
0
  }
12444
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12445
0
  if( libcthreads_read_write_lock_grab_for_read(
12446
0
       internal_handle->read_write_lock,
12447
0
       error ) != 1 )
12448
0
  {
12449
0
    libcerror_error_set(
12450
0
     error,
12451
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12452
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12453
0
     "%s: unable to grab read/write lock for reading.",
12454
0
     function );
12455
12456
0
    return( -1 );
12457
0
  }
12458
0
#endif
12459
0
  if( internal_handle->acquiry_errors != NULL )
12460
0
  {
12461
0
    if( libcdata_range_list_get_number_of_elements(
12462
0
         internal_handle->acquiry_errors,
12463
0
         &number_of_elements,
12464
0
         error ) != 1 )
12465
0
    {
12466
0
      libcerror_error_set(
12467
0
       error,
12468
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
12469
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
12470
0
       "%s: unable to retrieve number of elements from acquiry errors range list.",
12471
0
       function );
12472
12473
0
      goto on_error;
12474
0
    }
12475
0
  }
12476
0
  if( number_of_elements < 0 )
12477
0
  {
12478
0
    libcerror_error_set(
12479
0
     error,
12480
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12481
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
12482
0
     "%s: invalid number of elements value out of bounds.",
12483
0
     function );
12484
12485
0
    goto on_error;
12486
0
  }
12487
0
  *number_of_errors = (uint32_t) number_of_elements;
12488
12489
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12490
0
  if( libcthreads_read_write_lock_release_for_read(
12491
0
       internal_handle->read_write_lock,
12492
0
       error ) != 1 )
12493
0
  {
12494
0
    libcerror_error_set(
12495
0
     error,
12496
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12497
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12498
0
     "%s: unable to release read/write lock for reading.",
12499
0
     function );
12500
12501
0
    return( -1 );
12502
0
  }
12503
0
#endif
12504
0
  return( 1 );
12505
12506
0
on_error:
12507
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12508
0
  libcthreads_read_write_lock_release_for_read(
12509
0
   internal_handle->read_write_lock,
12510
0
   NULL );
12511
0
#endif
12512
0
  return( -1 );
12513
0
}
12514
12515
/* Retrieves an acquiry error
12516
 * Returns 1 if successful or -1 on error
12517
 */
12518
int libewf_handle_get_acquiry_error(
12519
     libewf_handle_t *handle,
12520
     uint32_t index,
12521
     uint64_t *start_sector,
12522
     uint64_t *number_of_sectors,
12523
     libcerror_error_t **error )
12524
0
{
12525
0
  libewf_internal_handle_t *internal_handle = NULL;
12526
0
  static char *function                     = "libewf_handle_get_acquiry_error";
12527
0
  intptr_t *value                           = NULL;
12528
0
  int result                                = 0;
12529
12530
0
  if( handle == NULL )
12531
0
  {
12532
0
    libcerror_error_set(
12533
0
     error,
12534
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
12535
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
12536
0
     "%s: invalid handle.",
12537
0
     function );
12538
12539
0
    return( -1 );
12540
0
  }
12541
0
  internal_handle = (libewf_internal_handle_t *) handle;
12542
12543
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12544
0
  if( libcthreads_read_write_lock_grab_for_read(
12545
0
       internal_handle->read_write_lock,
12546
0
       error ) != 1 )
12547
0
  {
12548
0
    libcerror_error_set(
12549
0
     error,
12550
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12551
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12552
0
     "%s: unable to grab read/write lock for reading.",
12553
0
     function );
12554
12555
0
    return( -1 );
12556
0
  }
12557
0
#endif
12558
0
  result = libcdata_range_list_get_range_by_index(
12559
0
            internal_handle->acquiry_errors,
12560
0
            (int) index,
12561
0
            start_sector,
12562
0
            number_of_sectors,
12563
0
            &value,
12564
0
            error );
12565
12566
0
  if( result != 1 )
12567
0
  {
12568
0
    libcerror_error_set(
12569
0
     error,
12570
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12571
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
12572
0
     "%s: unable to retrieve acquiry error: %" PRIu32 ".",
12573
0
     function,
12574
0
     index );
12575
0
  }
12576
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12577
0
  if( libcthreads_read_write_lock_release_for_read(
12578
0
       internal_handle->read_write_lock,
12579
0
       error ) != 1 )
12580
0
  {
12581
0
    libcerror_error_set(
12582
0
     error,
12583
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12584
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12585
0
     "%s: unable to release read/write lock for reading.",
12586
0
     function );
12587
12588
0
    return( -1 );
12589
0
  }
12590
0
#endif
12591
0
  return( result );
12592
0
}
12593
12594
/* Append an acquiry error
12595
 * Returns 1 if successful or -1 on error
12596
 */
12597
int libewf_handle_append_acquiry_error(
12598
     libewf_handle_t *handle,
12599
     uint64_t start_sector,
12600
     uint64_t number_of_sectors,
12601
     libcerror_error_t **error )
12602
0
{
12603
0
  libewf_internal_handle_t *internal_handle = NULL;
12604
0
  static char *function                     = "libewf_handle_append_acquiry_error";
12605
0
  int result                                = 0;
12606
12607
0
  if( handle == NULL )
12608
0
  {
12609
0
    libcerror_error_set(
12610
0
     error,
12611
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
12612
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
12613
0
     "%s: invalid handle.",
12614
0
     function );
12615
12616
0
    return( -1 );
12617
0
  }
12618
0
  internal_handle = (libewf_internal_handle_t *) handle;
12619
12620
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12621
0
  if( libcthreads_read_write_lock_grab_for_write(
12622
0
       internal_handle->read_write_lock,
12623
0
       error ) != 1 )
12624
0
  {
12625
0
    libcerror_error_set(
12626
0
     error,
12627
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12628
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12629
0
     "%s: unable to grab read/write lock for writing.",
12630
0
     function );
12631
12632
0
    return( -1 );
12633
0
  }
12634
0
#endif
12635
0
  result = libcdata_range_list_insert_range(
12636
0
            internal_handle->acquiry_errors,
12637
0
            start_sector,
12638
0
            number_of_sectors,
12639
0
            NULL,
12640
0
            NULL,
12641
0
            NULL,
12642
0
            error );
12643
12644
0
  if( result != 1 )
12645
0
  {
12646
0
    libcerror_error_set(
12647
0
     error,
12648
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12649
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
12650
0
     "%s: unable to insert acquiry error in range list.",
12651
0
     function );
12652
0
  }
12653
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12654
0
  if( libcthreads_read_write_lock_release_for_write(
12655
0
       internal_handle->read_write_lock,
12656
0
       error ) != 1 )
12657
0
  {
12658
0
    libcerror_error_set(
12659
0
     error,
12660
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12661
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12662
0
     "%s: unable to release read/write lock for writing.",
12663
0
     function );
12664
12665
0
    return( -1 );
12666
0
  }
12667
0
#endif
12668
0
  return( result );
12669
0
}
12670
12671
/* Retrieves the number of checksum errors
12672
 * Returns 1 if successful or -1 on error
12673
 */
12674
int libewf_handle_get_number_of_checksum_errors(
12675
     libewf_handle_t *handle,
12676
     uint32_t *number_of_errors,
12677
     libcerror_error_t **error )
12678
0
{
12679
0
  libewf_internal_handle_t *internal_handle = NULL;
12680
0
  static char *function                     = "libewf_handle_get_number_of_checksum_errors";
12681
0
  uint32_t number_of_elements               = 0;
12682
12683
0
  if( handle == NULL )
12684
0
  {
12685
0
    libcerror_error_set(
12686
0
     error,
12687
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
12688
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
12689
0
     "%s: invalid handle.",
12690
0
     function );
12691
12692
0
    return( -1 );
12693
0
  }
12694
0
  internal_handle = (libewf_internal_handle_t *) handle;
12695
12696
0
  if( number_of_errors == NULL )
12697
0
  {
12698
0
    libcerror_error_set(
12699
0
     error,
12700
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
12701
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
12702
0
     "%s: invalid number of errors.",
12703
0
     function );
12704
12705
0
    return( -1 );
12706
0
  }
12707
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12708
0
  if( libcthreads_read_write_lock_grab_for_read(
12709
0
       internal_handle->read_write_lock,
12710
0
       error ) != 1 )
12711
0
  {
12712
0
    libcerror_error_set(
12713
0
     error,
12714
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12715
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12716
0
     "%s: unable to grab read/write lock for reading.",
12717
0
     function );
12718
12719
0
    return( -1 );
12720
0
  }
12721
0
#endif
12722
0
  if( internal_handle->chunk_table != NULL )
12723
0
  {
12724
0
    if( libewf_chunk_table_get_number_of_checksum_errors(
12725
0
         internal_handle->chunk_table,
12726
0
         &number_of_elements,
12727
0
         error ) != 1 )
12728
0
    {
12729
0
      libcerror_error_set(
12730
0
       error,
12731
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
12732
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
12733
0
       "%s: unable to retrieve number of checksum errors.",
12734
0
       function );
12735
12736
0
      goto on_error;
12737
0
    }
12738
0
  }
12739
0
  *number_of_errors = number_of_elements;
12740
12741
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12742
0
  if( libcthreads_read_write_lock_release_for_read(
12743
0
       internal_handle->read_write_lock,
12744
0
       error ) != 1 )
12745
0
  {
12746
0
    libcerror_error_set(
12747
0
     error,
12748
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12749
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12750
0
     "%s: unable to release read/write lock for reading.",
12751
0
     function );
12752
12753
0
    return( -1 );
12754
0
  }
12755
0
#endif
12756
0
  return( 1 );
12757
12758
0
on_error:
12759
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12760
0
  libcthreads_read_write_lock_release_for_read(
12761
0
   internal_handle->read_write_lock,
12762
0
   NULL );
12763
0
#endif
12764
0
  return( -1 );
12765
0
}
12766
12767
/* Retrieves a checksum error
12768
 * Returns 1 if successful or -1 on error
12769
 */
12770
int libewf_handle_get_checksum_error(
12771
     libewf_handle_t *handle,
12772
     uint32_t error_index,
12773
     uint64_t *start_sector,
12774
     uint64_t *number_of_sectors,
12775
     libcerror_error_t **error )
12776
0
{
12777
0
  libewf_internal_handle_t *internal_handle = NULL;
12778
0
  static char *function                     = "libewf_handle_get_checksum_error";
12779
0
  int result                                = 0;
12780
12781
0
  if( handle == NULL )
12782
0
  {
12783
0
    libcerror_error_set(
12784
0
     error,
12785
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
12786
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
12787
0
     "%s: invalid handle.",
12788
0
     function );
12789
12790
0
    return( -1 );
12791
0
  }
12792
0
  internal_handle = (libewf_internal_handle_t *) handle;
12793
12794
0
  if( internal_handle->chunk_table == NULL )
12795
0
  {
12796
0
    libcerror_error_set(
12797
0
     error,
12798
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12799
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
12800
0
     "%s: invalid handle - missing chunk table.",
12801
0
     function );
12802
12803
0
    return( -1 );
12804
0
  }
12805
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12806
0
  if( libcthreads_read_write_lock_grab_for_read(
12807
0
       internal_handle->read_write_lock,
12808
0
       error ) != 1 )
12809
0
  {
12810
0
    libcerror_error_set(
12811
0
     error,
12812
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12813
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12814
0
     "%s: unable to grab read/write lock for reading.",
12815
0
     function );
12816
12817
0
    return( -1 );
12818
0
  }
12819
0
#endif
12820
0
  result = libewf_chunk_table_get_checksum_error(
12821
0
            internal_handle->chunk_table,
12822
0
            error_index,
12823
0
            start_sector,
12824
0
            number_of_sectors,
12825
0
            error );
12826
12827
0
  if( result != 1 )
12828
0
  {
12829
0
    libcerror_error_set(
12830
0
     error,
12831
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12832
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
12833
0
     "%s: unable to retrieve checksum error: %" PRIu32 ".",
12834
0
     function,
12835
0
     error_index );
12836
0
  }
12837
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12838
0
  if( libcthreads_read_write_lock_release_for_read(
12839
0
       internal_handle->read_write_lock,
12840
0
       error ) != 1 )
12841
0
  {
12842
0
    libcerror_error_set(
12843
0
     error,
12844
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12845
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12846
0
     "%s: unable to release read/write lock for reading.",
12847
0
     function );
12848
12849
0
    return( -1 );
12850
0
  }
12851
0
#endif
12852
0
  return( result );
12853
0
}
12854
12855
/* Appends a checksum error
12856
 * Returns 1 if successful or -1 on error
12857
 */
12858
int libewf_handle_append_checksum_error(
12859
     libewf_handle_t *handle,
12860
     uint64_t start_sector,
12861
     uint64_t number_of_sectors,
12862
     libcerror_error_t **error )
12863
0
{
12864
0
  libewf_internal_handle_t *internal_handle = NULL;
12865
0
  static char *function                     = "libewf_handle_append_checksum_error";
12866
0
  int result                                = 0;
12867
12868
0
  if( handle == NULL )
12869
0
  {
12870
0
    libcerror_error_set(
12871
0
     error,
12872
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
12873
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
12874
0
     "%s: invalid handle.",
12875
0
     function );
12876
12877
0
    return( -1 );
12878
0
  }
12879
0
  internal_handle = (libewf_internal_handle_t *) handle;
12880
12881
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12882
0
  if( libcthreads_read_write_lock_grab_for_write(
12883
0
       internal_handle->read_write_lock,
12884
0
       error ) != 1 )
12885
0
  {
12886
0
    libcerror_error_set(
12887
0
     error,
12888
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12889
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12890
0
     "%s: unable to grab read/write lock for writing.",
12891
0
     function );
12892
12893
0
    return( -1 );
12894
0
  }
12895
0
#endif
12896
0
  result = libewf_chunk_table_append_checksum_error(
12897
0
            internal_handle->chunk_table,
12898
0
            start_sector,
12899
0
            number_of_sectors,
12900
0
            error );
12901
12902
0
  if( result != 1 )
12903
0
  {
12904
0
    libcerror_error_set(
12905
0
     error,
12906
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12907
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
12908
0
     "%s: unable to append checksum error.",
12909
0
     function );
12910
0
  }
12911
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12912
0
  if( libcthreads_read_write_lock_release_for_write(
12913
0
       internal_handle->read_write_lock,
12914
0
       error ) != 1 )
12915
0
  {
12916
0
    libcerror_error_set(
12917
0
     error,
12918
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12919
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12920
0
     "%s: unable to release read/write lock for writing.",
12921
0
     function );
12922
12923
0
    return( -1 );
12924
0
  }
12925
0
#endif
12926
0
  return( result );
12927
0
}
12928
12929
/* Retrieves the number of sessions
12930
 * Returns 1 if successful or -1 on error
12931
 */
12932
int libewf_handle_get_number_of_sessions(
12933
     libewf_handle_t *handle,
12934
     uint32_t *number_of_sessions,
12935
     libcerror_error_t **error )
12936
0
{
12937
0
  libewf_internal_handle_t *internal_handle = NULL;
12938
0
  static char *function                     = "libewf_handle_get_number_of_sessions";
12939
0
  int number_of_entries                     = 0;
12940
12941
0
  if( handle == NULL )
12942
0
  {
12943
0
    libcerror_error_set(
12944
0
     error,
12945
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
12946
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
12947
0
     "%s: invalid handle.",
12948
0
     function );
12949
12950
0
    return( -1 );
12951
0
  }
12952
0
  internal_handle = (libewf_internal_handle_t *) handle;
12953
12954
0
  if( number_of_sessions == NULL )
12955
0
  {
12956
0
    libcerror_error_set(
12957
0
     error,
12958
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
12959
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
12960
0
     "%s: invalid number of sessions.",
12961
0
     function );
12962
12963
0
    return( -1 );
12964
0
  }
12965
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
12966
0
  if( libcthreads_read_write_lock_grab_for_read(
12967
0
       internal_handle->read_write_lock,
12968
0
       error ) != 1 )
12969
0
  {
12970
0
    libcerror_error_set(
12971
0
     error,
12972
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
12973
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
12974
0
     "%s: unable to grab read/write lock for reading.",
12975
0
     function );
12976
12977
0
    return( -1 );
12978
0
  }
12979
0
#endif
12980
0
  if( internal_handle->sessions != NULL )
12981
0
  {
12982
0
    if( libcdata_array_get_number_of_entries(
12983
0
         internal_handle->sessions,
12984
0
         &number_of_entries,
12985
0
         error ) != 1 )
12986
0
    {
12987
0
      libcerror_error_set(
12988
0
       error,
12989
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
12990
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
12991
0
       "%s: unable to retrieve number of entries from sessions array.",
12992
0
       function );
12993
12994
0
      goto on_error;
12995
0
    }
12996
0
  }
12997
0
  if( number_of_entries < 0 )
12998
0
  {
12999
0
    libcerror_error_set(
13000
0
     error,
13001
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13002
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
13003
0
     "%s: invalid number of entries value out of bounds.",
13004
0
     function );
13005
13006
0
    goto on_error;
13007
0
  }
13008
0
  *number_of_sessions = (uint32_t) number_of_entries;
13009
13010
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13011
0
  if( libcthreads_read_write_lock_release_for_read(
13012
0
       internal_handle->read_write_lock,
13013
0
       error ) != 1 )
13014
0
  {
13015
0
    libcerror_error_set(
13016
0
     error,
13017
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13018
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13019
0
     "%s: unable to release read/write lock for reading.",
13020
0
     function );
13021
13022
0
    return( -1 );
13023
0
  }
13024
0
#endif
13025
0
  return( 1 );
13026
13027
0
on_error:
13028
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13029
0
  libcthreads_read_write_lock_release_for_read(
13030
0
   internal_handle->read_write_lock,
13031
0
   NULL );
13032
0
#endif
13033
0
  return( -1 );
13034
0
}
13035
13036
/* Retrieves a session
13037
 * Returns 1 if successful or -1 on error
13038
 */
13039
int libewf_handle_get_session(
13040
     libewf_handle_t *handle,
13041
     uint32_t index,
13042
     uint64_t *start_sector,
13043
     uint64_t *number_of_sectors,
13044
     libcerror_error_t **error )
13045
0
{
13046
0
  libewf_internal_handle_t *internal_handle = NULL;
13047
0
  static char *function                     = "libewf_handle_get_session";
13048
0
  int result                                = 1;
13049
13050
0
  if( handle == NULL )
13051
0
  {
13052
0
    libcerror_error_set(
13053
0
     error,
13054
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13055
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
13056
0
     "%s: invalid handle.",
13057
0
     function );
13058
13059
0
    return( -1 );
13060
0
  }
13061
0
  internal_handle = (libewf_internal_handle_t *) handle;
13062
13063
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13064
0
  if( libcthreads_read_write_lock_grab_for_read(
13065
0
       internal_handle->read_write_lock,
13066
0
       error ) != 1 )
13067
0
  {
13068
0
    libcerror_error_set(
13069
0
     error,
13070
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13071
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13072
0
     "%s: unable to grab read/write lock for reading.",
13073
0
     function );
13074
13075
0
    return( -1 );
13076
0
  }
13077
0
#endif
13078
0
  if( libewf_sector_range_list_get_range(
13079
0
       internal_handle->sessions,
13080
0
       index,
13081
0
       start_sector,
13082
0
       number_of_sectors,
13083
0
       error ) != 1 )
13084
0
  {
13085
0
    libcerror_error_set(
13086
0
     error,
13087
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13088
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
13089
0
     "%s: unable to retrieve session: %" PRIu32 " sector range.",
13090
0
     function,
13091
0
     index );
13092
13093
0
    result = -1;
13094
0
  }
13095
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13096
0
  if( libcthreads_read_write_lock_release_for_read(
13097
0
       internal_handle->read_write_lock,
13098
0
       error ) != 1 )
13099
0
  {
13100
0
    libcerror_error_set(
13101
0
     error,
13102
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13103
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13104
0
     "%s: unable to release read/write lock for reading.",
13105
0
     function );
13106
13107
0
    return( -1 );
13108
0
  }
13109
0
#endif
13110
0
  return( result );
13111
0
}
13112
13113
/* Appends a session
13114
 * Returns 1 if successful or -1 on error
13115
 */
13116
int libewf_handle_append_session(
13117
     libewf_handle_t *handle,
13118
     uint64_t start_sector,
13119
     uint64_t number_of_sectors,
13120
     libcerror_error_t **error )
13121
0
{
13122
0
  libewf_internal_handle_t *internal_handle = NULL;
13123
0
  static char *function                     = "libewf_handle_append_session";
13124
0
  int result                                = 1;
13125
13126
0
  if( handle == NULL )
13127
0
  {
13128
0
    libcerror_error_set(
13129
0
     error,
13130
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13131
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
13132
0
     "%s: invalid handle.",
13133
0
     function );
13134
13135
0
    return( -1 );
13136
0
  }
13137
0
  internal_handle = (libewf_internal_handle_t *) handle;
13138
13139
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13140
0
  if( libcthreads_read_write_lock_grab_for_write(
13141
0
       internal_handle->read_write_lock,
13142
0
       error ) != 1 )
13143
0
  {
13144
0
    libcerror_error_set(
13145
0
     error,
13146
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13147
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13148
0
     "%s: unable to grab read/write lock for writing.",
13149
0
     function );
13150
13151
0
    return( -1 );
13152
0
  }
13153
0
#endif
13154
0
  if( libewf_sector_range_list_append_range(
13155
0
       internal_handle->sessions,
13156
0
       start_sector,
13157
0
       number_of_sectors,
13158
0
       error ) != 1 )
13159
0
  {
13160
0
    libcerror_error_set(
13161
0
     error,
13162
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13163
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
13164
0
     "%s: unable to append session sector range.",
13165
0
     function );
13166
13167
0
    result = -1;
13168
0
  }
13169
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13170
0
  if( libcthreads_read_write_lock_release_for_write(
13171
0
       internal_handle->read_write_lock,
13172
0
       error ) != 1 )
13173
0
  {
13174
0
    libcerror_error_set(
13175
0
     error,
13176
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13177
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13178
0
     "%s: unable to release read/write lock for writing.",
13179
0
     function );
13180
13181
0
    return( -1 );
13182
0
  }
13183
0
#endif
13184
0
  return( result );
13185
0
}
13186
13187
/* Retrieves the number of tracks
13188
 * Returns 1 if successful or -1 on error
13189
 */
13190
int libewf_handle_get_number_of_tracks(
13191
     libewf_handle_t *handle,
13192
     uint32_t *number_of_tracks,
13193
     libcerror_error_t **error )
13194
0
{
13195
0
  libewf_internal_handle_t *internal_handle = NULL;
13196
0
  static char *function                     = "libewf_handle_get_number_of_tracks";
13197
0
  int number_of_entries                     = 0;
13198
13199
0
  if( handle == NULL )
13200
0
  {
13201
0
    libcerror_error_set(
13202
0
     error,
13203
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13204
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
13205
0
     "%s: invalid handle.",
13206
0
     function );
13207
13208
0
    return( -1 );
13209
0
  }
13210
0
  internal_handle = (libewf_internal_handle_t *) handle;
13211
13212
0
  if( number_of_tracks == NULL )
13213
0
  {
13214
0
    libcerror_error_set(
13215
0
     error,
13216
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13217
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
13218
0
     "%s: invalid number of tracks.",
13219
0
     function );
13220
13221
0
    return( -1 );
13222
0
  }
13223
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13224
0
  if( libcthreads_read_write_lock_grab_for_read(
13225
0
       internal_handle->read_write_lock,
13226
0
       error ) != 1 )
13227
0
  {
13228
0
    libcerror_error_set(
13229
0
     error,
13230
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13231
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13232
0
     "%s: unable to grab read/write lock for reading.",
13233
0
     function );
13234
13235
0
    return( -1 );
13236
0
  }
13237
0
#endif
13238
0
  if( internal_handle->tracks != NULL )
13239
0
  {
13240
0
    if( libcdata_array_get_number_of_entries(
13241
0
         internal_handle->tracks,
13242
0
         &number_of_entries,
13243
0
         error ) != 1 )
13244
0
    {
13245
0
      libcerror_error_set(
13246
0
       error,
13247
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
13248
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
13249
0
       "%s: unable to retrieve number of entries from tracks array.",
13250
0
       function );
13251
13252
0
      goto on_error;
13253
0
    }
13254
0
  }
13255
0
  if( number_of_entries < 0 )
13256
0
  {
13257
0
    libcerror_error_set(
13258
0
     error,
13259
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13260
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
13261
0
     "%s: invalid number of entries value out of bounds.",
13262
0
     function );
13263
13264
0
    goto on_error;
13265
0
  }
13266
0
  *number_of_tracks = (uint32_t) number_of_entries;
13267
13268
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13269
0
  if( libcthreads_read_write_lock_release_for_read(
13270
0
       internal_handle->read_write_lock,
13271
0
       error ) != 1 )
13272
0
  {
13273
0
    libcerror_error_set(
13274
0
     error,
13275
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13276
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13277
0
     "%s: unable to release read/write lock for reading.",
13278
0
     function );
13279
13280
0
    return( -1 );
13281
0
  }
13282
0
#endif
13283
0
  return( 1 );
13284
13285
0
on_error:
13286
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13287
0
  libcthreads_read_write_lock_release_for_read(
13288
0
   internal_handle->read_write_lock,
13289
0
   NULL );
13290
0
#endif
13291
0
  return( -1 );
13292
0
}
13293
13294
/* Retrieves a track
13295
 * Returns 1 if successful or -1 on error
13296
 */
13297
int libewf_handle_get_track(
13298
     libewf_handle_t *handle,
13299
     uint32_t index,
13300
     uint64_t *start_sector,
13301
     uint64_t *number_of_sectors,
13302
     libcerror_error_t **error )
13303
0
{
13304
0
  libewf_internal_handle_t *internal_handle = NULL;
13305
0
  static char *function                     = "libewf_handle_get_track";
13306
0
  int result                                = 1;
13307
13308
0
  if( handle == NULL )
13309
0
  {
13310
0
    libcerror_error_set(
13311
0
     error,
13312
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13313
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
13314
0
     "%s: invalid handle.",
13315
0
     function );
13316
13317
0
    return( -1 );
13318
0
  }
13319
0
  internal_handle = (libewf_internal_handle_t *) handle;
13320
13321
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13322
0
  if( libcthreads_read_write_lock_grab_for_read(
13323
0
       internal_handle->read_write_lock,
13324
0
       error ) != 1 )
13325
0
  {
13326
0
    libcerror_error_set(
13327
0
     error,
13328
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13329
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13330
0
     "%s: unable to grab read/write lock for reading.",
13331
0
     function );
13332
13333
0
    return( -1 );
13334
0
  }
13335
0
#endif
13336
0
  if( libewf_sector_range_list_get_range(
13337
0
       internal_handle->tracks,
13338
0
       index,
13339
0
       start_sector,
13340
0
       number_of_sectors,
13341
0
       error ) != 1 )
13342
0
  {
13343
0
    libcerror_error_set(
13344
0
     error,
13345
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13346
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
13347
0
     "%s: unable to retrieve track: %" PRIu32 " sector range.",
13348
0
     function,
13349
0
     index );
13350
13351
0
    result = -1;
13352
0
  }
13353
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13354
0
  if( libcthreads_read_write_lock_release_for_read(
13355
0
       internal_handle->read_write_lock,
13356
0
       error ) != 1 )
13357
0
  {
13358
0
    libcerror_error_set(
13359
0
     error,
13360
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13361
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13362
0
     "%s: unable to release read/write lock for reading.",
13363
0
     function );
13364
13365
0
    return( -1 );
13366
0
  }
13367
0
#endif
13368
0
  return( result );
13369
0
}
13370
13371
/* Appends a track
13372
 * Returns 1 if successful or -1 on error
13373
 */
13374
int libewf_handle_append_track(
13375
     libewf_handle_t *handle,
13376
     uint64_t start_sector,
13377
     uint64_t number_of_sectors,
13378
     libcerror_error_t **error )
13379
0
{
13380
0
  libewf_internal_handle_t *internal_handle = NULL;
13381
0
  static char *function                     = "libewf_handle_append_track";
13382
0
  int result                                = 1;
13383
13384
0
  if( handle == NULL )
13385
0
  {
13386
0
    libcerror_error_set(
13387
0
     error,
13388
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13389
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
13390
0
     "%s: invalid handle.",
13391
0
     function );
13392
13393
0
    return( -1 );
13394
0
  }
13395
0
  internal_handle = (libewf_internal_handle_t *) handle;
13396
13397
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13398
0
  if( libcthreads_read_write_lock_grab_for_write(
13399
0
       internal_handle->read_write_lock,
13400
0
       error ) != 1 )
13401
0
  {
13402
0
    libcerror_error_set(
13403
0
     error,
13404
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13405
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13406
0
     "%s: unable to grab read/write lock for writing.",
13407
0
     function );
13408
13409
0
    return( -1 );
13410
0
  }
13411
0
#endif
13412
0
  if( libewf_sector_range_list_append_range(
13413
0
       internal_handle->tracks,
13414
0
       start_sector,
13415
0
       number_of_sectors,
13416
0
       error ) != 1 )
13417
0
  {
13418
0
    libcerror_error_set(
13419
0
     error,
13420
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13421
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
13422
0
     "%s: unable to append track sector range.",
13423
0
     function );
13424
13425
0
    result = -1;
13426
0
  }
13427
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13428
0
  if( libcthreads_read_write_lock_release_for_write(
13429
0
       internal_handle->read_write_lock,
13430
0
       error ) != 1 )
13431
0
  {
13432
0
    libcerror_error_set(
13433
0
     error,
13434
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13435
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13436
0
     "%s: unable to release read/write lock for writing.",
13437
0
     function );
13438
13439
0
    return( -1 );
13440
0
  }
13441
0
#endif
13442
0
  return( result );
13443
0
}
13444
13445
/* Retrieves the header codepage
13446
 * Returns 1 if successful or -1 on error
13447
 */
13448
int libewf_handle_get_header_codepage(
13449
     libewf_handle_t *handle,
13450
     int *header_codepage,
13451
     libcerror_error_t **error )
13452
0
{
13453
0
  libewf_internal_handle_t *internal_handle = NULL;
13454
0
  static char *function                     = "libewf_handle_get_header_codepage";
13455
13456
0
  if( handle == NULL )
13457
0
  {
13458
0
    libcerror_error_set(
13459
0
     error,
13460
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13461
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
13462
0
     "%s: invalid handle.",
13463
0
     function );
13464
13465
0
    return( -1 );
13466
0
  }
13467
0
  internal_handle = (libewf_internal_handle_t *) handle;
13468
13469
0
  if( internal_handle->io_handle == NULL )
13470
0
  {
13471
0
    libcerror_error_set(
13472
0
     error,
13473
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13474
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
13475
0
     "%s: invalid handle - missing IO handle.",
13476
0
     function );
13477
13478
0
    return( -1 );
13479
0
  }
13480
0
  if( header_codepage == NULL )
13481
0
  {
13482
0
    libcerror_error_set(
13483
0
     error,
13484
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13485
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
13486
0
     "%s: invalid header codepage.",
13487
0
     function );
13488
13489
0
    return( -1 );
13490
0
  }
13491
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13492
0
  if( libcthreads_read_write_lock_grab_for_read(
13493
0
       internal_handle->read_write_lock,
13494
0
       error ) != 1 )
13495
0
  {
13496
0
    libcerror_error_set(
13497
0
     error,
13498
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13499
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13500
0
     "%s: unable to grab read/write lock for reading.",
13501
0
     function );
13502
13503
0
    return( -1 );
13504
0
  }
13505
0
#endif
13506
0
  *header_codepage = internal_handle->io_handle->header_codepage;
13507
13508
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13509
0
  if( libcthreads_read_write_lock_release_for_read(
13510
0
       internal_handle->read_write_lock,
13511
0
       error ) != 1 )
13512
0
  {
13513
0
    libcerror_error_set(
13514
0
     error,
13515
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13516
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13517
0
     "%s: unable to release read/write lock for reading.",
13518
0
     function );
13519
13520
0
    return( -1 );
13521
0
  }
13522
0
#endif
13523
0
  return( 1 );
13524
0
}
13525
13526
/* Sets the header codepage
13527
 * Returns 1 if successful or -1 on error
13528
 */
13529
int libewf_handle_set_header_codepage(
13530
     libewf_handle_t *handle,
13531
     int header_codepage,
13532
     libcerror_error_t **error )
13533
0
{
13534
0
  libewf_internal_handle_t *internal_handle = NULL;
13535
0
  static char *function                     = "libewf_handle_set_header_codepage";
13536
13537
0
  if( handle == NULL )
13538
0
  {
13539
0
    libcerror_error_set(
13540
0
     error,
13541
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13542
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
13543
0
     "%s: invalid handle.",
13544
0
     function );
13545
13546
0
    return( -1 );
13547
0
  }
13548
0
  internal_handle = (libewf_internal_handle_t *) handle;
13549
13550
0
  if( internal_handle->io_handle == NULL )
13551
0
  {
13552
0
    libcerror_error_set(
13553
0
     error,
13554
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13555
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
13556
0
     "%s: invalid handle - missing IO handle.",
13557
0
     function );
13558
13559
0
    return( -1 );
13560
0
  }
13561
0
  if( ( header_codepage != LIBEWF_CODEPAGE_ASCII )
13562
0
   && ( header_codepage != LIBEWF_CODEPAGE_WINDOWS_874 )
13563
0
   && ( header_codepage != LIBEWF_CODEPAGE_WINDOWS_932 )
13564
0
   && ( header_codepage != LIBEWF_CODEPAGE_WINDOWS_936 )
13565
0
   && ( header_codepage != LIBEWF_CODEPAGE_WINDOWS_1250 )
13566
0
   && ( header_codepage != LIBEWF_CODEPAGE_WINDOWS_1251 )
13567
0
   && ( header_codepage != LIBEWF_CODEPAGE_WINDOWS_1252 )
13568
0
   && ( header_codepage != LIBEWF_CODEPAGE_WINDOWS_1253 )
13569
0
   && ( header_codepage != LIBEWF_CODEPAGE_WINDOWS_1254 )
13570
0
   && ( header_codepage != LIBEWF_CODEPAGE_WINDOWS_1255 )
13571
0
   && ( header_codepage != LIBEWF_CODEPAGE_WINDOWS_1256 )
13572
0
   && ( header_codepage != LIBEWF_CODEPAGE_WINDOWS_1257 )
13573
0
   && ( header_codepage != LIBEWF_CODEPAGE_WINDOWS_1258 ) )
13574
0
  {
13575
0
    libcerror_error_set(
13576
0
     error,
13577
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13578
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
13579
0
     "%s: unsupported header codepage.",
13580
0
     function );
13581
13582
0
    return( -1 );
13583
0
  }
13584
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13585
0
  if( libcthreads_read_write_lock_grab_for_write(
13586
0
       internal_handle->read_write_lock,
13587
0
       error ) != 1 )
13588
0
  {
13589
0
    libcerror_error_set(
13590
0
     error,
13591
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13592
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13593
0
     "%s: unable to grab read/write lock for writing.",
13594
0
     function );
13595
13596
0
    return( -1 );
13597
0
  }
13598
0
#endif
13599
0
  internal_handle->io_handle->header_codepage = header_codepage;
13600
13601
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13602
0
  if( libcthreads_read_write_lock_release_for_write(
13603
0
       internal_handle->read_write_lock,
13604
0
       error ) != 1 )
13605
0
  {
13606
0
    libcerror_error_set(
13607
0
     error,
13608
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13609
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13610
0
     "%s: unable to release read/write lock for writing.",
13611
0
     function );
13612
13613
0
    return( -1 );
13614
0
  }
13615
0
#endif
13616
0
  return( 1 );
13617
0
}
13618
13619
/* Retrieves the header value date format
13620
 * Returns 1 if successful or -1 on error
13621
 */
13622
int libewf_handle_get_header_values_date_format(
13623
     libewf_handle_t *handle,
13624
     int *date_format,
13625
     libcerror_error_t **error )
13626
0
{
13627
0
  libewf_internal_handle_t *internal_handle = NULL;
13628
0
  static char *function                     = "libewf_handle_get_header_values_date_format";
13629
13630
0
  if( handle == NULL )
13631
0
  {
13632
0
    libcerror_error_set(
13633
0
     error,
13634
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13635
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
13636
0
     "%s: invalid handle.",
13637
0
     function );
13638
13639
0
    return( -1 );
13640
0
  }
13641
0
  internal_handle = (libewf_internal_handle_t *) handle;
13642
13643
0
  if( date_format == NULL )
13644
0
  {
13645
0
    libcerror_error_set(
13646
0
     error,
13647
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13648
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
13649
0
     "%s: invalid date format.",
13650
0
     function );
13651
13652
0
    return( -1 );
13653
0
  }
13654
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13655
0
  if( libcthreads_read_write_lock_grab_for_read(
13656
0
       internal_handle->read_write_lock,
13657
0
       error ) != 1 )
13658
0
  {
13659
0
    libcerror_error_set(
13660
0
     error,
13661
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13662
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13663
0
     "%s: unable to grab read/write lock for reading.",
13664
0
     function );
13665
13666
0
    return( -1 );
13667
0
  }
13668
0
#endif
13669
0
  *date_format = internal_handle->date_format;
13670
13671
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13672
0
  if( libcthreads_read_write_lock_release_for_read(
13673
0
       internal_handle->read_write_lock,
13674
0
       error ) != 1 )
13675
0
  {
13676
0
    libcerror_error_set(
13677
0
     error,
13678
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13679
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13680
0
     "%s: unable to release read/write lock for reading.",
13681
0
     function );
13682
13683
0
    return( -1 );
13684
0
  }
13685
0
#endif
13686
0
  return( 1 );
13687
0
}
13688
13689
/* Sets the header values date format
13690
 * Returns 1 if successful or -1 on error
13691
 */
13692
int libewf_handle_set_header_values_date_format(
13693
     libewf_handle_t *handle,
13694
     int date_format,
13695
     libcerror_error_t **error )
13696
0
{
13697
0
  libewf_internal_handle_t *internal_handle = NULL;
13698
0
  static char *function                     = "libewf_handle_set_header_values_date_format";
13699
13700
0
  if( handle == NULL )
13701
0
  {
13702
0
    libcerror_error_set(
13703
0
     error,
13704
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13705
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
13706
0
     "%s: invalid handle.",
13707
0
     function );
13708
13709
0
    return( -1 );
13710
0
  }
13711
0
  internal_handle = (libewf_internal_handle_t *) handle;
13712
13713
0
  if( ( date_format != LIBEWF_DATE_FORMAT_CTIME )
13714
0
   && ( date_format != LIBEWF_DATE_FORMAT_DAYMONTH )
13715
0
   && ( date_format != LIBEWF_DATE_FORMAT_MONTHDAY )
13716
0
   && ( date_format != LIBEWF_DATE_FORMAT_ISO8601 ) )
13717
0
  {
13718
0
    libcerror_error_set(
13719
0
     error,
13720
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13721
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
13722
0
     "%s: unsupported date format.",
13723
0
     function );
13724
13725
0
    return( -1 );
13726
0
  }
13727
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13728
0
  if( libcthreads_read_write_lock_grab_for_write(
13729
0
       internal_handle->read_write_lock,
13730
0
       error ) != 1 )
13731
0
  {
13732
0
    libcerror_error_set(
13733
0
     error,
13734
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13735
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13736
0
     "%s: unable to grab read/write lock for writing.",
13737
0
     function );
13738
13739
0
    return( -1 );
13740
0
  }
13741
0
#endif
13742
0
  internal_handle->date_format = date_format;
13743
13744
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13745
0
  if( libcthreads_read_write_lock_release_for_write(
13746
0
       internal_handle->read_write_lock,
13747
0
       error ) != 1 )
13748
0
  {
13749
0
    libcerror_error_set(
13750
0
     error,
13751
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13752
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13753
0
     "%s: unable to release read/write lock for writing.",
13754
0
     function );
13755
13756
0
    return( -1 );
13757
0
  }
13758
0
#endif
13759
0
  return( 1 );
13760
0
}
13761
13762
/* Retrieves the number of header values
13763
 * Returns 1 if successful or -1 on error
13764
 */
13765
int libewf_handle_get_number_of_header_values(
13766
     libewf_handle_t *handle,
13767
     uint32_t *number_of_values,
13768
     libcerror_error_t **error )
13769
0
{
13770
0
  libewf_internal_handle_t *internal_handle = NULL;
13771
0
  static char *function                     = "libewf_handle_get_number_of_header_values";
13772
0
  int number_of_header_values               = 0;
13773
13774
0
  if( handle == NULL )
13775
0
  {
13776
0
    libcerror_error_set(
13777
0
     error,
13778
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13779
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
13780
0
     "%s: invalid handle.",
13781
0
     function );
13782
13783
0
    return( -1 );
13784
0
  }
13785
0
  internal_handle = (libewf_internal_handle_t *) handle;
13786
13787
0
  if( number_of_values == NULL )
13788
0
  {
13789
0
    libcerror_error_set(
13790
0
     error,
13791
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13792
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
13793
0
     "%s: invalid number of values.",
13794
0
     function );
13795
13796
0
    return( -1 );
13797
0
  }
13798
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13799
0
  if( libcthreads_read_write_lock_grab_for_read(
13800
0
       internal_handle->read_write_lock,
13801
0
       error ) != 1 )
13802
0
  {
13803
0
    libcerror_error_set(
13804
0
     error,
13805
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13806
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13807
0
     "%s: unable to grab read/write lock for reading.",
13808
0
     function );
13809
13810
0
    return( -1 );
13811
0
  }
13812
0
#endif
13813
0
  if( internal_handle->header_values != NULL )
13814
0
  {
13815
0
    if( libfvalue_table_get_number_of_values(
13816
0
         internal_handle->header_values,
13817
0
         &number_of_header_values,
13818
0
         error ) != 1 )
13819
0
    {
13820
0
      libcerror_error_set(
13821
0
       error,
13822
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
13823
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
13824
0
       "%s: unable to retrieve number of header values.",
13825
0
       function );
13826
13827
0
      goto on_error;
13828
0
    }
13829
0
  }
13830
0
  if( number_of_header_values < 0 )
13831
0
  {
13832
0
    libcerror_error_set(
13833
0
     error,
13834
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13835
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
13836
0
     "%s: invalid number of header values value out of bounds.",
13837
0
     function );
13838
13839
0
    goto on_error;
13840
0
  }
13841
0
  *number_of_values = (uint32_t) number_of_header_values;
13842
13843
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13844
0
  if( libcthreads_read_write_lock_release_for_read(
13845
0
       internal_handle->read_write_lock,
13846
0
       error ) != 1 )
13847
0
  {
13848
0
    libcerror_error_set(
13849
0
     error,
13850
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13851
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13852
0
     "%s: unable to release read/write lock for reading.",
13853
0
     function );
13854
13855
0
    return( -1 );
13856
0
  }
13857
0
#endif
13858
0
  return( 1 );
13859
13860
0
on_error:
13861
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13862
0
  libcthreads_read_write_lock_release_for_read(
13863
0
   internal_handle->read_write_lock,
13864
0
   NULL );
13865
0
#endif
13866
0
  return( -1 );
13867
0
}
13868
13869
/* Retrieves the size of the value identifier of a specific index
13870
 * The identifier size includes the end of string character
13871
 * Returns 1 if successful, 0 if no header values are present or -1 on error
13872
 */
13873
int libewf_handle_get_header_value_identifier_size(
13874
     libewf_handle_t *handle,
13875
     uint32_t index,
13876
     size_t *identifier_size,
13877
     libcerror_error_t **error )
13878
0
{
13879
0
  libewf_internal_handle_t *internal_handle = NULL;
13880
0
  static char *function                     = "libewf_handle_get_header_value_identifier_size";
13881
0
  int result                                = 0;
13882
13883
0
  if( handle == NULL )
13884
0
  {
13885
0
    libcerror_error_set(
13886
0
     error,
13887
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13888
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
13889
0
     "%s: invalid handle.",
13890
0
     function );
13891
13892
0
    return( -1 );
13893
0
  }
13894
0
  internal_handle = (libewf_internal_handle_t *) handle;
13895
13896
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13897
0
  if( libcthreads_read_write_lock_grab_for_read(
13898
0
       internal_handle->read_write_lock,
13899
0
       error ) != 1 )
13900
0
  {
13901
0
    libcerror_error_set(
13902
0
     error,
13903
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13904
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13905
0
     "%s: unable to grab read/write lock for reading.",
13906
0
     function );
13907
13908
0
    return( -1 );
13909
0
  }
13910
0
#endif
13911
0
  if( internal_handle->header_values != NULL )
13912
0
  {
13913
0
    result = libewf_header_values_get_identifier_size(
13914
0
              internal_handle->header_values,
13915
0
              index,
13916
0
              identifier_size,
13917
0
              error );
13918
13919
0
    if( result == -1 )
13920
0
    {
13921
0
      libcerror_error_set(
13922
0
       error,
13923
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
13924
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
13925
0
       "%s: unable to retrieve header value: %" PRIu32 " identifier size.",
13926
0
       function,
13927
0
       index );
13928
0
    }
13929
0
  }
13930
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13931
0
  if( libcthreads_read_write_lock_release_for_read(
13932
0
       internal_handle->read_write_lock,
13933
0
       error ) != 1 )
13934
0
  {
13935
0
    libcerror_error_set(
13936
0
     error,
13937
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13938
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13939
0
     "%s: unable to release read/write lock for reading.",
13940
0
     function );
13941
13942
0
    return( -1 );
13943
0
  }
13944
0
#endif
13945
0
  return( result );
13946
0
}
13947
13948
/* Retrieves the header value identifier of a specific index
13949
 * The identifier size should include the end of string character
13950
 * Returns 1 if successful, 0 if no header values are present or -1 on error
13951
 */
13952
int libewf_handle_get_header_value_identifier(
13953
     libewf_handle_t *handle,
13954
     uint32_t index,
13955
     uint8_t *identifier,
13956
     size_t identifier_size,
13957
     libcerror_error_t **error )
13958
0
{
13959
0
  libewf_internal_handle_t *internal_handle = NULL;
13960
0
  static char *function                     = "libewf_handle_get_header_value_identifier";
13961
0
  int result                                = 0;
13962
13963
0
  if( handle == NULL )
13964
0
  {
13965
0
    libcerror_error_set(
13966
0
     error,
13967
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13968
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
13969
0
     "%s: invalid handle.",
13970
0
     function );
13971
13972
0
    return( -1 );
13973
0
  }
13974
0
  internal_handle = (libewf_internal_handle_t *) handle;
13975
13976
0
  if( identifier == NULL )
13977
0
  {
13978
0
    libcerror_error_set(
13979
0
     error,
13980
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
13981
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
13982
0
     "%s: invalid identifier.",
13983
0
     function );
13984
13985
0
    return( -1 );
13986
0
  }
13987
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
13988
0
  if( libcthreads_read_write_lock_grab_for_read(
13989
0
       internal_handle->read_write_lock,
13990
0
       error ) != 1 )
13991
0
  {
13992
0
    libcerror_error_set(
13993
0
     error,
13994
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
13995
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
13996
0
     "%s: unable to grab read/write lock for reading.",
13997
0
     function );
13998
13999
0
    return( -1 );
14000
0
  }
14001
0
#endif
14002
0
  if( internal_handle->header_values != NULL )
14003
0
  {
14004
0
    result = libewf_header_values_get_identifier(
14005
0
              internal_handle->header_values,
14006
0
              index,
14007
0
              identifier,
14008
0
              identifier_size,
14009
0
              error );
14010
14011
0
    if( result == -1 )
14012
0
    {
14013
0
      libcerror_error_set(
14014
0
       error,
14015
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
14016
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
14017
0
       "%s: unable to retrieve header value: %" PRIu32 " identifier.",
14018
0
       function,
14019
0
       index );
14020
0
    }
14021
0
  }
14022
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
14023
0
  if( libcthreads_read_write_lock_release_for_read(
14024
0
       internal_handle->read_write_lock,
14025
0
       error ) != 1 )
14026
0
  {
14027
0
    libcerror_error_set(
14028
0
     error,
14029
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14030
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14031
0
     "%s: unable to release read/write lock for reading.",
14032
0
     function );
14033
14034
0
    return( -1 );
14035
0
  }
14036
0
#endif
14037
0
  return( result );
14038
0
}
14039
14040
/* Retrieves the size of the UTF-8 encoded header value of an identifier
14041
 * The string size includes the end of string character
14042
 * Returns 1 if successful, 0 if not set or -1 on error
14043
 */
14044
int libewf_handle_get_utf8_header_value_size(
14045
     libewf_handle_t *handle,
14046
     const uint8_t *identifier,
14047
     size_t identifier_length,
14048
     size_t *utf8_string_size,
14049
     libcerror_error_t **error )
14050
0
{
14051
0
  libewf_internal_handle_t *internal_handle = NULL;
14052
0
  static char *function                     = "libewf_handle_get_utf8_header_value_size";
14053
0
  int result                                = 0;
14054
14055
0
  if( handle == NULL )
14056
0
  {
14057
0
    libcerror_error_set(
14058
0
     error,
14059
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
14060
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
14061
0
     "%s: invalid handle.",
14062
0
     function );
14063
14064
0
    return( -1 );
14065
0
  }
14066
0
  internal_handle = (libewf_internal_handle_t *) handle;
14067
14068
0
  if( utf8_string_size == NULL )
14069
0
  {
14070
0
    libcerror_error_set(
14071
0
     error,
14072
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
14073
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
14074
0
     "%s: invalid UTF-8 string size.",
14075
0
     function );
14076
14077
0
    return( -1 );
14078
0
  }
14079
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
14080
0
  if( libcthreads_read_write_lock_grab_for_read(
14081
0
       internal_handle->read_write_lock,
14082
0
       error ) != 1 )
14083
0
  {
14084
0
    libcerror_error_set(
14085
0
     error,
14086
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14087
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14088
0
     "%s: unable to grab read/write lock for reading.",
14089
0
     function );
14090
14091
0
    return( -1 );
14092
0
  }
14093
0
#endif
14094
0
  if( internal_handle->header_values != NULL )
14095
0
  {
14096
0
    result = libewf_header_values_get_utf8_value_size(
14097
0
              internal_handle->header_values,
14098
0
              identifier,
14099
0
              identifier_length,
14100
0
              internal_handle->date_format,
14101
0
              utf8_string_size,
14102
0
              error );
14103
14104
0
    if( result == -1 )
14105
0
    {
14106
0
      libcerror_error_set(
14107
0
       error,
14108
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
14109
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
14110
0
       "%s: unable to retrieve header value size.",
14111
0
       function );
14112
0
    }
14113
0
  }
14114
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
14115
0
  if( libcthreads_read_write_lock_release_for_read(
14116
0
       internal_handle->read_write_lock,
14117
0
       error ) != 1 )
14118
0
  {
14119
0
    libcerror_error_set(
14120
0
     error,
14121
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14122
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14123
0
     "%s: unable to release read/write lock for reading.",
14124
0
     function );
14125
14126
0
    return( -1 );
14127
0
  }
14128
0
#endif
14129
0
  return( result );
14130
0
}
14131
14132
/* Retrieves the UTF-8 encoded header value of an identifier
14133
 * The string size should include the end of string character
14134
 * Returns 1 if successful, 0 if not set or -1 on error
14135
 */
14136
int libewf_handle_get_utf8_header_value(
14137
     libewf_handle_t *handle,
14138
     const uint8_t *identifier,
14139
     size_t identifier_length,
14140
     uint8_t *utf8_string,
14141
     size_t utf8_string_size,
14142
     libcerror_error_t **error )
14143
0
{
14144
0
  libewf_internal_handle_t *internal_handle = NULL;
14145
0
  static char *function                     = "libewf_handle_get_utf8_header_value";
14146
0
  int result                                = 0;
14147
14148
0
  if( handle == NULL )
14149
0
  {
14150
0
    libcerror_error_set(
14151
0
     error,
14152
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
14153
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
14154
0
     "%s: invalid handle.",
14155
0
     function );
14156
14157
0
    return( -1 );
14158
0
  }
14159
0
  internal_handle = (libewf_internal_handle_t *) handle;
14160
14161
0
  if( utf8_string == NULL )
14162
0
  {
14163
0
    libcerror_error_set(
14164
0
     error,
14165
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
14166
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
14167
0
     "%s: invalid UTF-8 string.",
14168
0
     function );
14169
14170
0
    return( -1 );
14171
0
  }
14172
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
14173
0
  if( libcthreads_read_write_lock_grab_for_read(
14174
0
       internal_handle->read_write_lock,
14175
0
       error ) != 1 )
14176
0
  {
14177
0
    libcerror_error_set(
14178
0
     error,
14179
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14180
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14181
0
     "%s: unable to grab read/write lock for reading.",
14182
0
     function );
14183
14184
0
    return( -1 );
14185
0
  }
14186
0
#endif
14187
0
  if( internal_handle->header_values != NULL )
14188
0
  {
14189
0
    result = libewf_header_values_get_utf8_value(
14190
0
              internal_handle->header_values,
14191
0
              identifier,
14192
0
              identifier_length,
14193
0
              internal_handle->date_format,
14194
0
              utf8_string,
14195
0
              utf8_string_size,
14196
0
              error );
14197
14198
0
    if( result == -1 )
14199
0
    {
14200
0
      libcerror_error_set(
14201
0
       error,
14202
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
14203
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
14204
0
       "%s: unable to retrieve header value.",
14205
0
       function );
14206
0
    }
14207
0
  }
14208
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
14209
0
  if( libcthreads_read_write_lock_release_for_read(
14210
0
       internal_handle->read_write_lock,
14211
0
       error ) != 1 )
14212
0
  {
14213
0
    libcerror_error_set(
14214
0
     error,
14215
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14216
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14217
0
     "%s: unable to release read/write lock for reading.",
14218
0
     function );
14219
14220
0
    return( -1 );
14221
0
  }
14222
0
#endif
14223
0
  return( result );
14224
0
}
14225
14226
/* Sets the UTF-8 encoded header value specified by the identifier
14227
 * Returns 1 if successful or -1 on error
14228
 */
14229
int libewf_handle_set_utf8_header_value(
14230
     libewf_handle_t *handle,
14231
     const uint8_t *identifier,
14232
     size_t identifier_length,
14233
     const uint8_t *utf8_string,
14234
     size_t utf8_string_length,
14235
     libcerror_error_t **error )
14236
0
{
14237
0
  libewf_internal_handle_t *internal_handle = NULL;
14238
0
  static char *function                     = "libewf_handle_set_utf8_header_value";
14239
0
  int result                                = 1;
14240
14241
0
  if( handle == NULL )
14242
0
  {
14243
0
    libcerror_error_set(
14244
0
     error,
14245
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
14246
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
14247
0
     "%s: invalid handle.",
14248
0
     function );
14249
14250
0
    return( -1 );
14251
0
  }
14252
0
  internal_handle = (libewf_internal_handle_t *) handle;
14253
14254
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
14255
0
  if( libcthreads_read_write_lock_grab_for_write(
14256
0
       internal_handle->read_write_lock,
14257
0
       error ) != 1 )
14258
0
  {
14259
0
    libcerror_error_set(
14260
0
     error,
14261
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14262
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14263
0
     "%s: unable to grab read/write lock for writing.",
14264
0
     function );
14265
14266
0
    return( -1 );
14267
0
  }
14268
0
#endif
14269
0
  if( ( internal_handle->read_io_handle != NULL )
14270
0
   || ( internal_handle->write_io_handle == NULL )
14271
0
   || ( internal_handle->write_io_handle->values_initialized != 0 ) )
14272
0
  {
14273
0
    libcerror_error_set(
14274
0
     error,
14275
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14276
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14277
0
     "%s: header value cannot be changed.",
14278
0
     function );
14279
14280
0
    result = -1;
14281
0
  }
14282
0
  else if( internal_handle->header_values == NULL )
14283
0
  {
14284
0
    result = libewf_header_values_initialize(
14285
0
              &( internal_handle->header_values ),
14286
0
              error );
14287
14288
0
    if( result != 1 )
14289
0
    {
14290
0
      libcerror_error_set(
14291
0
       error,
14292
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
14293
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
14294
0
       "%s: unable to create header values.",
14295
0
       function );
14296
0
    }
14297
0
  }
14298
0
  if( result == 1 )
14299
0
  {
14300
0
    result = libewf_value_table_copy_value_from_utf8_string(
14301
0
        internal_handle->header_values,
14302
0
        identifier,
14303
0
        identifier_length,
14304
0
        utf8_string,
14305
0
        utf8_string_length,
14306
0
        error );
14307
14308
0
    if( result != 1 )
14309
0
    {
14310
0
      libcerror_error_set(
14311
0
       error,
14312
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
14313
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14314
0
       "%s: unable to set header value.",
14315
0
       function );
14316
0
    }
14317
0
  }
14318
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
14319
0
  if( libcthreads_read_write_lock_release_for_write(
14320
0
       internal_handle->read_write_lock,
14321
0
       error ) != 1 )
14322
0
  {
14323
0
    libcerror_error_set(
14324
0
     error,
14325
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14326
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14327
0
     "%s: unable to release read/write lock for writing.",
14328
0
     function );
14329
14330
0
    return( -1 );
14331
0
  }
14332
0
#endif
14333
0
  return( result );
14334
0
}
14335
14336
/* Retrieves the size of the UTF-16 encoded header value of an identifier
14337
 * The string size includes the end of string character
14338
 * Returns 1 if successful, 0 if not set or -1 on error
14339
 */
14340
int libewf_handle_get_utf16_header_value_size(
14341
     libewf_handle_t *handle,
14342
     const uint8_t *identifier,
14343
     size_t identifier_length,
14344
     size_t *utf16_string_size,
14345
     libcerror_error_t **error )
14346
0
{
14347
0
  libewf_internal_handle_t *internal_handle = NULL;
14348
0
  static char *function                     = "libewf_handle_get_utf8_header_value_size";
14349
0
  int result                                = 0;
14350
14351
0
  if( handle == NULL )
14352
0
  {
14353
0
    libcerror_error_set(
14354
0
     error,
14355
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
14356
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
14357
0
     "%s: invalid handle.",
14358
0
     function );
14359
14360
0
    return( -1 );
14361
0
  }
14362
0
  internal_handle = (libewf_internal_handle_t *) handle;
14363
14364
0
  if( utf16_string_size == NULL )
14365
0
  {
14366
0
    libcerror_error_set(
14367
0
     error,
14368
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
14369
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
14370
0
     "%s: invalid UTF-16 string size.",
14371
0
     function );
14372
14373
0
    return( -1 );
14374
0
  }
14375
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
14376
0
  if( libcthreads_read_write_lock_grab_for_read(
14377
0
       internal_handle->read_write_lock,
14378
0
       error ) != 1 )
14379
0
  {
14380
0
    libcerror_error_set(
14381
0
     error,
14382
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14383
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14384
0
     "%s: unable to grab read/write lock for reading.",
14385
0
     function );
14386
14387
0
    return( -1 );
14388
0
  }
14389
0
#endif
14390
0
  if( internal_handle->header_values != NULL )
14391
0
  {
14392
0
    result = libewf_header_values_get_utf16_value_size(
14393
0
              internal_handle->header_values,
14394
0
              identifier,
14395
0
              identifier_length,
14396
0
              internal_handle->date_format,
14397
0
              utf16_string_size,
14398
0
              error );
14399
14400
0
    if( result == -1 )
14401
0
    {
14402
0
      libcerror_error_set(
14403
0
       error,
14404
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
14405
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
14406
0
       "%s: unable to retrieve header value size.",
14407
0
       function );
14408
0
    }
14409
0
  }
14410
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
14411
0
  if( libcthreads_read_write_lock_release_for_read(
14412
0
       internal_handle->read_write_lock,
14413
0
       error ) != 1 )
14414
0
  {
14415
0
    libcerror_error_set(
14416
0
     error,
14417
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14418
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14419
0
     "%s: unable to release read/write lock for reading.",
14420
0
     function );
14421
14422
0
    return( -1 );
14423
0
  }
14424
0
#endif
14425
0
  return( result );
14426
0
}
14427
14428
/* Retrieves the UTF-16 encoded header value of an identifier
14429
 * The string size should include the end of string character
14430
 * Returns 1 if successful, 0 if not set or -1 on error
14431
 */
14432
int libewf_handle_get_utf16_header_value(
14433
     libewf_handle_t *handle,
14434
     const uint8_t *identifier,
14435
     size_t identifier_length,
14436
     uint16_t *utf16_string,
14437
     size_t utf16_string_size,
14438
     libcerror_error_t **error )
14439
0
{
14440
0
  libewf_internal_handle_t *internal_handle = NULL;
14441
0
  static char *function                     = "libewf_handle_get_utf16_header_value";
14442
0
  int result                                = 0;
14443
14444
0
  if( handle == NULL )
14445
0
  {
14446
0
    libcerror_error_set(
14447
0
     error,
14448
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
14449
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
14450
0
     "%s: invalid handle.",
14451
0
     function );
14452
14453
0
    return( -1 );
14454
0
  }
14455
0
  internal_handle = (libewf_internal_handle_t *) handle;
14456
14457
0
  if( utf16_string == NULL )
14458
0
  {
14459
0
    libcerror_error_set(
14460
0
     error,
14461
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
14462
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
14463
0
     "%s: invalid UTF-16 string.",
14464
0
     function );
14465
14466
0
    return( -1 );
14467
0
  }
14468
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
14469
0
  if( libcthreads_read_write_lock_grab_for_read(
14470
0
       internal_handle->read_write_lock,
14471
0
       error ) != 1 )
14472
0
  {
14473
0
    libcerror_error_set(
14474
0
     error,
14475
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14476
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14477
0
     "%s: unable to grab read/write lock for reading.",
14478
0
     function );
14479
14480
0
    return( -1 );
14481
0
  }
14482
0
#endif
14483
0
  if( internal_handle->header_values != NULL )
14484
0
  {
14485
0
    result = libewf_header_values_get_utf16_value(
14486
0
              internal_handle->header_values,
14487
0
              identifier,
14488
0
              identifier_length,
14489
0
              internal_handle->date_format,
14490
0
              utf16_string,
14491
0
              utf16_string_size,
14492
0
              error );
14493
14494
0
    if( result == -1 )
14495
0
    {
14496
0
      libcerror_error_set(
14497
0
       error,
14498
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
14499
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
14500
0
       "%s: unable to retrieve header value.",
14501
0
       function );
14502
0
    }
14503
0
  }
14504
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
14505
0
  if( libcthreads_read_write_lock_release_for_read(
14506
0
       internal_handle->read_write_lock,
14507
0
       error ) != 1 )
14508
0
  {
14509
0
    libcerror_error_set(
14510
0
     error,
14511
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14512
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14513
0
     "%s: unable to release read/write lock for reading.",
14514
0
     function );
14515
14516
0
    return( -1 );
14517
0
  }
14518
0
#endif
14519
0
  return( result );
14520
0
}
14521
14522
/* Sets the UTF-16 encoded header value specified by the identifier
14523
 * Returns 1 if successful or -1 on error
14524
 */
14525
int libewf_handle_set_utf16_header_value(
14526
     libewf_handle_t *handle,
14527
     const uint8_t *identifier,
14528
     size_t identifier_length,
14529
     const uint16_t *utf16_string,
14530
     size_t utf16_string_length,
14531
     libcerror_error_t **error )
14532
0
{
14533
0
  libewf_internal_handle_t *internal_handle = NULL;
14534
0
  static char *function                     = "libewf_handle_set_utf16_header_value";
14535
0
  int result                                = 1;
14536
14537
0
  if( handle == NULL )
14538
0
  {
14539
0
    libcerror_error_set(
14540
0
     error,
14541
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
14542
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
14543
0
     "%s: invalid handle.",
14544
0
     function );
14545
14546
0
    return( -1 );
14547
0
  }
14548
0
  internal_handle = (libewf_internal_handle_t *) handle;
14549
14550
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
14551
0
  if( libcthreads_read_write_lock_grab_for_write(
14552
0
       internal_handle->read_write_lock,
14553
0
       error ) != 1 )
14554
0
  {
14555
0
    libcerror_error_set(
14556
0
     error,
14557
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14558
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14559
0
     "%s: unable to grab read/write lock for writing.",
14560
0
     function );
14561
14562
0
    return( -1 );
14563
0
  }
14564
0
#endif
14565
0
  if( ( internal_handle->read_io_handle != NULL )
14566
0
   || ( internal_handle->write_io_handle == NULL )
14567
0
   || ( internal_handle->write_io_handle->values_initialized != 0 ) )
14568
0
  {
14569
0
    libcerror_error_set(
14570
0
     error,
14571
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14572
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14573
0
     "%s: header value cannot be changed.",
14574
0
     function );
14575
14576
0
    result = -1;
14577
0
  }
14578
0
  else if( internal_handle->header_values == NULL )
14579
0
  {
14580
0
    result = libewf_header_values_initialize(
14581
0
              &( internal_handle->header_values ),
14582
0
              error );
14583
14584
0
    if( result != 1 )
14585
0
    {
14586
0
      libcerror_error_set(
14587
0
       error,
14588
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
14589
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
14590
0
       "%s: unable to create header values.",
14591
0
       function );
14592
0
    }
14593
0
  }
14594
0
  if( result == 1 )
14595
0
  {
14596
0
    result = libewf_value_table_copy_value_from_utf16_string(
14597
0
              internal_handle->header_values,
14598
0
              identifier,
14599
0
              identifier_length,
14600
0
              utf16_string,
14601
0
              utf16_string_length,
14602
0
              error );
14603
14604
0
    if( result != 1 )
14605
0
    {
14606
0
      libcerror_error_set(
14607
0
       error,
14608
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
14609
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14610
0
       "%s: unable to set header value.",
14611
0
       function );
14612
0
    }
14613
0
  }
14614
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
14615
0
  if( libcthreads_read_write_lock_release_for_write(
14616
0
       internal_handle->read_write_lock,
14617
0
       error ) != 1 )
14618
0
  {
14619
0
    libcerror_error_set(
14620
0
     error,
14621
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14622
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14623
0
     "%s: unable to release read/write lock for writing.",
14624
0
     function );
14625
14626
0
    return( -1 );
14627
0
  }
14628
0
#endif
14629
0
  return( result );
14630
0
}
14631
14632
/* Copies the header values from the source to the destination handle
14633
 * Returns 1 if successful or -1 on error
14634
 */
14635
int libewf_handle_copy_header_values(
14636
     libewf_handle_t *destination_handle,
14637
     libewf_handle_t *source_handle,
14638
     libcerror_error_t **error )
14639
0
{
14640
0
  libewf_internal_handle_t *internal_destination_handle = NULL;
14641
0
  libewf_internal_handle_t *internal_source_handle      = NULL;
14642
0
  static char *function                                 = "libewf_handle_copy_header_values";
14643
0
  int result                                            = 1;
14644
14645
0
  if( destination_handle == NULL )
14646
0
  {
14647
0
    libcerror_error_set(
14648
0
     error,
14649
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
14650
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
14651
0
     "%s: invalid destination handle.",
14652
0
     function );
14653
14654
0
    return( -1 );
14655
0
  }
14656
0
  if( source_handle == NULL )
14657
0
  {
14658
0
    libcerror_error_set(
14659
0
     error,
14660
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
14661
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
14662
0
     "%s: invalid source handle.",
14663
0
     function );
14664
14665
0
    return( -1 );
14666
0
  }
14667
0
  internal_destination_handle = (libewf_internal_handle_t *) destination_handle;
14668
0
  internal_source_handle      = (libewf_internal_handle_t *) source_handle;
14669
14670
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
14671
0
  if( libcthreads_read_write_lock_grab_for_read(
14672
0
       internal_source_handle->read_write_lock,
14673
0
       error ) != 1 )
14674
0
  {
14675
0
    libcerror_error_set(
14676
0
     error,
14677
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14678
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14679
0
     "%s: unable to grab read/write lock for reading.",
14680
0
     function );
14681
14682
0
    return( -1 );
14683
0
  }
14684
0
#endif
14685
0
  if( internal_source_handle->header_values == NULL )
14686
0
  {
14687
0
    libcerror_error_set(
14688
0
     error,
14689
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14690
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
14691
0
     "%s: invalid source handle - missing header values.",
14692
0
     function );
14693
14694
0
    result = -1;
14695
0
  }
14696
0
  else
14697
0
  {
14698
/* TODO add destination handle write lock */
14699
0
    if( internal_destination_handle->header_values == NULL )
14700
0
    {
14701
0
      if( libewf_header_values_initialize(
14702
0
           &( internal_destination_handle->header_values ),
14703
0
           error ) != 1 )
14704
0
      {
14705
0
        libcerror_error_set(
14706
0
         error,
14707
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
14708
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
14709
0
         "%s: unable to create header values.",
14710
0
         function );
14711
14712
0
        result = -1;
14713
0
      }
14714
0
    }
14715
0
    if( result == 1 )
14716
0
    {
14717
0
      result = libewf_header_values_copy(
14718
0
                internal_destination_handle->header_values,
14719
0
                internal_source_handle->header_values,
14720
0
                error );
14721
14722
0
      if( result != 1 )
14723
0
      {
14724
0
        libcerror_error_set(
14725
0
         error,
14726
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
14727
0
         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
14728
0
         "%s: unable to copy header values.",
14729
0
         function );
14730
0
      }
14731
0
      else
14732
0
      {
14733
0
        internal_destination_handle->header_values_parsed = 1;
14734
0
      }
14735
0
    }
14736
0
  }
14737
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
14738
0
  if( libcthreads_read_write_lock_release_for_read(
14739
0
       internal_source_handle->read_write_lock,
14740
0
       error ) != 1 )
14741
0
  {
14742
0
    libcerror_error_set(
14743
0
     error,
14744
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14745
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14746
0
     "%s: unable to release read/write lock for reading.",
14747
0
     function );
14748
14749
0
    return( -1 );
14750
0
  }
14751
0
#endif
14752
0
  return( result );
14753
0
}
14754
14755
/* Parses the hash values from the hash, digest and/or xhash section
14756
 * Returns 1 if successful or -1 on error
14757
 */
14758
int libewf_internal_handle_parse_hash_values(
14759
     libewf_internal_handle_t *internal_handle,
14760
     libcerror_error_t **error )
14761
0
{
14762
0
  static char *function = "libewf_internal_handle_parse_hash_values";
14763
0
  int result            = 1;
14764
14765
0
  if( internal_handle == NULL )
14766
0
  {
14767
0
    libcerror_error_set(
14768
0
     error,
14769
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
14770
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
14771
0
     "%s: invalid handle.",
14772
0
     function );
14773
14774
0
    return( -1 );
14775
0
  }
14776
0
  if( internal_handle->hash_sections == NULL )
14777
0
  {
14778
0
    libcerror_error_set(
14779
0
     error,
14780
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14781
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
14782
0
     "%s: invalid handle - missing hash sections.",
14783
0
     function );
14784
14785
0
    return( -1 );
14786
0
  }
14787
0
  if( internal_handle->hash_values != NULL )
14788
0
  {
14789
0
    libcerror_error_set(
14790
0
     error,
14791
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14792
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
14793
0
     "%s: invalid handle - hash sections already set.",
14794
0
     function );
14795
14796
0
    return( -1 );
14797
0
  }
14798
0
  if( libewf_hash_values_initialize(
14799
0
       &( internal_handle->hash_values ),
14800
0
       error ) != 1 )
14801
0
  {
14802
0
    libcerror_error_set(
14803
0
     error,
14804
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14805
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
14806
0
     "%s: unable to create hash values.",
14807
0
     function );
14808
14809
0
    return( -1 );
14810
0
  }
14811
0
  if( ( internal_handle->hash_sections->md5_hash_set != 0 )
14812
0
   && ( libewf_hash_values_parse_md5_hash(
14813
0
         internal_handle->hash_values,
14814
0
         internal_handle->hash_sections->md5_hash,
14815
0
         16,
14816
0
         error ) != 1 ) )
14817
0
  {
14818
0
    libcerror_error_set(
14819
0
     error,
14820
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14821
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14822
0
     "%s: unable to parse MD5 hash for its value.",
14823
0
     function );
14824
14825
0
    result = -1;
14826
0
  }
14827
0
  else if( ( internal_handle->hash_sections->md5_digest_set != 0 )
14828
0
        && ( libewf_hash_values_parse_md5_hash(
14829
0
              internal_handle->hash_values,
14830
0
              internal_handle->hash_sections->md5_digest,
14831
0
              16,
14832
0
              error ) != 1 ) )
14833
0
  {
14834
0
    libcerror_error_set(
14835
0
     error,
14836
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14837
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14838
0
     "%s: unable to parse MD5 digest for its value.",
14839
0
     function );
14840
14841
0
    result = -1;
14842
0
  }
14843
0
  if( ( internal_handle->hash_sections->sha1_hash_set != 0 )
14844
0
   && ( libewf_hash_values_parse_sha1_hash(
14845
0
         internal_handle->hash_values,
14846
0
         internal_handle->hash_sections->sha1_hash,
14847
0
         20,
14848
0
         error ) != 1 ) )
14849
0
  {
14850
0
    libcerror_error_set(
14851
0
     error,
14852
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14853
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14854
0
     "%s: unable to parse SHA1 hash for its value.",
14855
0
     function );
14856
14857
0
    result = -1;
14858
0
  }
14859
0
  else if( ( internal_handle->hash_sections->sha1_digest_set != 0 )
14860
0
        && ( libewf_hash_values_parse_sha1_hash(
14861
0
              internal_handle->hash_values,
14862
0
              internal_handle->hash_sections->sha1_digest,
14863
0
              20,
14864
0
              error ) != 1 ) )
14865
0
  {
14866
0
    libcerror_error_set(
14867
0
     error,
14868
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14869
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14870
0
     "%s: unable to parse SHA1 digest for its value.",
14871
0
     function );
14872
14873
0
    result = -1;
14874
0
  }
14875
0
  if( ( internal_handle->hash_sections->xhash != NULL )
14876
0
   && ( libewf_hash_values_parse_xhash(
14877
0
         internal_handle->hash_values,
14878
0
         internal_handle->hash_sections->xhash,
14879
0
         internal_handle->hash_sections->xhash_size,
14880
0
         error ) != 1 ) )
14881
0
  {
14882
0
    libcerror_error_set(
14883
0
     error,
14884
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14885
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14886
0
     "%s: unable to parse xhash for values.",
14887
0
     function );
14888
14889
0
    result = -1;
14890
0
  }
14891
0
  return( result );
14892
0
}
14893
14894
/* Retrieves the number of hash values
14895
 * Returns 1 if successful or -1 on error
14896
 */
14897
int libewf_handle_get_number_of_hash_values(
14898
     libewf_handle_t *handle,
14899
     uint32_t *number_of_values,
14900
     libcerror_error_t **error )
14901
0
{
14902
0
  libewf_internal_handle_t *internal_handle = NULL;
14903
0
  static char *function                     = "libewf_handle_get_number_of_hash_values";
14904
0
  int number_of_hash_values                 = 0;
14905
14906
0
  if( handle == NULL )
14907
0
  {
14908
0
    libcerror_error_set(
14909
0
     error,
14910
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
14911
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
14912
0
     "%s: invalid handle.",
14913
0
     function );
14914
14915
0
    return( -1 );
14916
0
  }
14917
0
  internal_handle = (libewf_internal_handle_t *) handle;
14918
14919
0
  if( number_of_values == NULL )
14920
0
  {
14921
0
    libcerror_error_set(
14922
0
     error,
14923
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
14924
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
14925
0
     "%s: invalid number of values.",
14926
0
     function );
14927
14928
0
    return( -1 );
14929
0
  }
14930
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
14931
0
  if( libcthreads_read_write_lock_grab_for_write(
14932
0
       internal_handle->read_write_lock,
14933
0
       error ) != 1 )
14934
0
  {
14935
0
    libcerror_error_set(
14936
0
     error,
14937
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14938
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14939
0
     "%s: unable to grab read/write lock for writing.",
14940
0
     function );
14941
14942
0
    return( -1 );
14943
0
  }
14944
0
#endif
14945
0
  if( internal_handle->hash_values_parsed == 0 )
14946
0
  {
14947
0
    if( libewf_internal_handle_parse_hash_values(
14948
0
         internal_handle,
14949
0
         error ) != 1 )
14950
0
    {
14951
0
      libcerror_error_set(
14952
0
       error,
14953
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
14954
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
14955
0
       "%s: unable to parse hash values.",
14956
0
       function );
14957
14958
0
      goto on_error;
14959
0
    }
14960
0
    internal_handle->hash_values_parsed = 1;
14961
0
  }
14962
0
  if( internal_handle->hash_values != NULL )
14963
0
  {
14964
0
    if( libfvalue_table_get_number_of_values(
14965
0
         internal_handle->hash_values,
14966
0
         &number_of_hash_values,
14967
0
         error ) != 1 )
14968
0
    {
14969
0
      libcerror_error_set(
14970
0
       error,
14971
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
14972
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
14973
0
       "%s: unable to retrieve number of hash values.",
14974
0
       function );
14975
14976
0
      goto on_error;
14977
0
    }
14978
0
  }
14979
0
  if( number_of_hash_values < 0 )
14980
0
  {
14981
0
    libcerror_error_set(
14982
0
     error,
14983
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
14984
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
14985
0
     "%s: invalid number of hash values value out of bounds.",
14986
0
     function );
14987
14988
0
    goto on_error;
14989
0
  }
14990
0
  *number_of_values = (uint32_t) number_of_hash_values;
14991
14992
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
14993
0
  if( libcthreads_read_write_lock_release_for_write(
14994
0
       internal_handle->read_write_lock,
14995
0
       error ) != 1 )
14996
0
  {
14997
0
    libcerror_error_set(
14998
0
     error,
14999
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15000
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15001
0
     "%s: unable to release read/write lock for writing.",
15002
0
     function );
15003
15004
0
    return( -1 );
15005
0
  }
15006
0
#endif
15007
0
  return( 1 );
15008
15009
0
on_error:
15010
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
15011
0
  libcthreads_read_write_lock_release_for_write(
15012
0
   internal_handle->read_write_lock,
15013
0
   NULL );
15014
0
#endif
15015
0
  return( -1 );
15016
0
}
15017
15018
/* Retrieves the size of the hash value identifier of a specific index
15019
 * The identifier size includes the end of string character
15020
 * Returns 1 if successful, 0 if if no hash values are present or -1 on error
15021
 */
15022
int libewf_handle_get_hash_value_identifier_size(
15023
     libewf_handle_t *handle,
15024
     uint32_t index,
15025
     size_t *identifier_size,
15026
     libcerror_error_t **error )
15027
0
{
15028
0
  libewf_internal_handle_t *internal_handle = NULL;
15029
0
  static char *function                     = "libewf_handle_get_hash_value_identifier_size";
15030
0
  int result                                = 0;
15031
15032
0
  if( handle == NULL )
15033
0
  {
15034
0
    libcerror_error_set(
15035
0
     error,
15036
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
15037
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
15038
0
     "%s: invalid handle.",
15039
0
     function );
15040
15041
0
    return( -1 );
15042
0
  }
15043
0
  internal_handle = (libewf_internal_handle_t *) handle;
15044
15045
/* TODO add write lock */
15046
0
  if( internal_handle->hash_values_parsed == 0 )
15047
0
  {
15048
0
    if( libewf_internal_handle_parse_hash_values(
15049
0
         internal_handle,
15050
0
         error ) != 1 )
15051
0
    {
15052
0
      libcerror_error_set(
15053
0
       error,
15054
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
15055
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15056
0
       "%s: unable to parse hash values.",
15057
0
       function );
15058
15059
0
      return( -1 );
15060
0
    }
15061
0
    internal_handle->hash_values_parsed = 1;
15062
0
  }
15063
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
15064
0
  if( libcthreads_read_write_lock_grab_for_read(
15065
0
       internal_handle->read_write_lock,
15066
0
       error ) != 1 )
15067
0
  {
15068
0
    libcerror_error_set(
15069
0
     error,
15070
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15071
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15072
0
     "%s: unable to grab read/write lock for reading.",
15073
0
     function );
15074
15075
0
    return( -1 );
15076
0
  }
15077
0
#endif
15078
0
  if( internal_handle->hash_values != NULL )
15079
0
  {
15080
0
    result = libewf_hash_values_get_identifier_size(
15081
0
              internal_handle->hash_values,
15082
0
              index,
15083
0
              identifier_size,
15084
0
              error );
15085
15086
0
    if( result == -1 )
15087
0
    {
15088
0
      libcerror_error_set(
15089
0
       error,
15090
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
15091
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
15092
0
       "%s: unable to retrieve hash value: %" PRIu32 " identifier size.",
15093
0
       function,
15094
0
       index );
15095
0
    }
15096
0
  }
15097
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
15098
0
  if( libcthreads_read_write_lock_release_for_read(
15099
0
       internal_handle->read_write_lock,
15100
0
       error ) != 1 )
15101
0
  {
15102
0
    libcerror_error_set(
15103
0
     error,
15104
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15105
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15106
0
     "%s: unable to release read/write lock for reading.",
15107
0
     function );
15108
15109
0
    return( -1 );
15110
0
  }
15111
0
#endif
15112
0
  return( result );
15113
0
}
15114
15115
/* Retrieves the hash value identifier of a specific index
15116
 * The identifier size should include the end of string character
15117
 * Returns 1 if successful, 0 if no hash values are present or -1 on error
15118
 */
15119
int libewf_handle_get_hash_value_identifier(
15120
     libewf_handle_t *handle,
15121
     uint32_t index,
15122
     uint8_t *identifier,
15123
     size_t identifier_size,
15124
     libcerror_error_t **error )
15125
0
{
15126
0
  libewf_internal_handle_t *internal_handle = NULL;
15127
0
  static char *function                     = "libewf_handle_get_hash_value_identifier";
15128
0
  int result                                = 0;
15129
15130
0
  if( handle == NULL )
15131
0
  {
15132
0
    libcerror_error_set(
15133
0
     error,
15134
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
15135
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
15136
0
     "%s: invalid handle.",
15137
0
     function );
15138
15139
0
    return( -1 );
15140
0
  }
15141
0
  internal_handle = (libewf_internal_handle_t *) handle;
15142
15143
/* TODO add write lock */
15144
0
  if( internal_handle->hash_values_parsed == 0 )
15145
0
  {
15146
0
    if( libewf_internal_handle_parse_hash_values(
15147
0
         internal_handle,
15148
0
         error ) != 1 )
15149
0
    {
15150
0
      libcerror_error_set(
15151
0
       error,
15152
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
15153
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15154
0
       "%s: unable to parse hash values.",
15155
0
       function );
15156
15157
0
      return( -1 );
15158
0
    }
15159
0
    internal_handle->hash_values_parsed = 1;
15160
0
  }
15161
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
15162
0
  if( libcthreads_read_write_lock_grab_for_read(
15163
0
       internal_handle->read_write_lock,
15164
0
       error ) != 1 )
15165
0
  {
15166
0
    libcerror_error_set(
15167
0
     error,
15168
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15169
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15170
0
     "%s: unable to grab read/write lock for reading.",
15171
0
     function );
15172
15173
0
    return( -1 );
15174
0
  }
15175
0
#endif
15176
0
  if( internal_handle->hash_values != NULL )
15177
0
  {
15178
0
    result = libewf_hash_values_get_identifier(
15179
0
              internal_handle->hash_values,
15180
0
              index,
15181
0
              identifier,
15182
0
              identifier_size,
15183
0
              error );
15184
15185
0
    if( result == -1 )
15186
0
    {
15187
0
      libcerror_error_set(
15188
0
       error,
15189
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
15190
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
15191
0
       "%s: unable to retrieve hash value: %" PRIu32 " identifier.",
15192
0
       function,
15193
0
       index );
15194
0
    }
15195
0
  }
15196
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
15197
0
  if( libcthreads_read_write_lock_release_for_read(
15198
0
       internal_handle->read_write_lock,
15199
0
       error ) != 1 )
15200
0
  {
15201
0
    libcerror_error_set(
15202
0
     error,
15203
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15204
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15205
0
     "%s: unable to release read/write lock for reading.",
15206
0
     function );
15207
15208
0
    return( -1 );
15209
0
  }
15210
0
#endif
15211
0
  return( result );
15212
0
}
15213
15214
/* Retrieves the size of the UTF-8 encoded hash value of an identifier
15215
 * The string size includes the end of string character
15216
 * Returns 1 if successful, 0 if not set or -1 on error
15217
 */
15218
int libewf_handle_get_utf8_hash_value_size(
15219
     libewf_handle_t *handle,
15220
     const uint8_t *identifier,
15221
     size_t identifier_length,
15222
     size_t *utf8_string_size,
15223
     libcerror_error_t **error )
15224
0
{
15225
0
  libewf_internal_handle_t *internal_handle = NULL;
15226
0
  static char *function                     = "libewf_handle_get_utf8_hash_value_size";
15227
0
  int result                                = 0;
15228
15229
0
  if( handle == NULL )
15230
0
  {
15231
0
    libcerror_error_set(
15232
0
     error,
15233
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
15234
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
15235
0
     "%s: invalid handle.",
15236
0
     function );
15237
15238
0
    return( -1 );
15239
0
  }
15240
0
  internal_handle = (libewf_internal_handle_t *) handle;
15241
15242
/* TODO add write lock */
15243
0
  if( internal_handle->hash_values_parsed == 0 )
15244
0
  {
15245
0
    if( libewf_internal_handle_parse_hash_values(
15246
0
         internal_handle,
15247
0
         error ) != 1 )
15248
0
    {
15249
0
      libcerror_error_set(
15250
0
       error,
15251
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
15252
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15253
0
       "%s: unable to parse hash values.",
15254
0
       function );
15255
15256
0
      return( -1 );
15257
0
    }
15258
0
    internal_handle->hash_values_parsed = 1;
15259
0
  }
15260
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
15261
0
  if( libcthreads_read_write_lock_grab_for_read(
15262
0
       internal_handle->read_write_lock,
15263
0
       error ) != 1 )
15264
0
  {
15265
0
    libcerror_error_set(
15266
0
     error,
15267
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15268
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15269
0
     "%s: unable to grab read/write lock for reading.",
15270
0
     function );
15271
15272
0
    return( -1 );
15273
0
  }
15274
0
#endif
15275
0
  if( internal_handle->hash_values != NULL )
15276
0
  {
15277
0
    result = libewf_value_table_get_utf8_value_size(
15278
0
              internal_handle->hash_values,
15279
0
              identifier,
15280
0
              identifier_length,
15281
0
              utf8_string_size,
15282
0
              error );
15283
15284
0
    if( result == -1 )
15285
0
    {
15286
0
      libcerror_error_set(
15287
0
       error,
15288
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
15289
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
15290
0
       "%s: unable to retrieve hash value size.",
15291
0
       function );
15292
0
    }
15293
0
  }
15294
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
15295
0
  if( libcthreads_read_write_lock_release_for_read(
15296
0
       internal_handle->read_write_lock,
15297
0
       error ) != 1 )
15298
0
  {
15299
0
    libcerror_error_set(
15300
0
     error,
15301
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15302
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15303
0
     "%s: unable to release read/write lock for reading.",
15304
0
     function );
15305
15306
0
    return( -1 );
15307
0
  }
15308
0
#endif
15309
0
  return( result );
15310
0
}
15311
15312
/* Retrieves the UTF-8 encoded hash value of an identifier
15313
 * The string size should include the end of string character
15314
 * Returns 1 if successful, 0 if not set or -1 on error
15315
 */
15316
int libewf_handle_get_utf8_hash_value(
15317
     libewf_handle_t *handle,
15318
     const uint8_t *identifier,
15319
     size_t identifier_length,
15320
     uint8_t *utf8_string,
15321
     size_t utf8_string_size,
15322
     libcerror_error_t **error )
15323
0
{
15324
0
  libewf_internal_handle_t *internal_handle = NULL;
15325
0
  static char *function                     = "libewf_handle_get_utf8_hash_value";
15326
0
  int result                                = 0;
15327
15328
0
  if( handle == NULL )
15329
0
  {
15330
0
    libcerror_error_set(
15331
0
     error,
15332
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
15333
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
15334
0
     "%s: invalid handle.",
15335
0
     function );
15336
15337
0
    return( -1 );
15338
0
  }
15339
0
  internal_handle = (libewf_internal_handle_t *) handle;
15340
15341
/* TODO add write lock */
15342
0
  if( internal_handle->hash_values_parsed == 0 )
15343
0
  {
15344
0
    if( libewf_internal_handle_parse_hash_values(
15345
0
         internal_handle,
15346
0
         error ) != 1 )
15347
0
    {
15348
0
      libcerror_error_set(
15349
0
       error,
15350
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
15351
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15352
0
       "%s: unable to parse hash values.",
15353
0
       function );
15354
15355
0
      return( -1 );
15356
0
    }
15357
0
    internal_handle->hash_values_parsed = 1;
15358
0
  }
15359
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
15360
0
  if( libcthreads_read_write_lock_grab_for_read(
15361
0
       internal_handle->read_write_lock,
15362
0
       error ) != 1 )
15363
0
  {
15364
0
    libcerror_error_set(
15365
0
     error,
15366
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15367
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15368
0
     "%s: unable to grab read/write lock for reading.",
15369
0
     function );
15370
15371
0
    return( -1 );
15372
0
  }
15373
0
#endif
15374
0
  if( internal_handle->hash_values != NULL )
15375
0
  {
15376
0
    result = libewf_value_table_get_utf8_value(
15377
0
              internal_handle->hash_values,
15378
0
              identifier,
15379
0
              identifier_length,
15380
0
              utf8_string,
15381
0
              utf8_string_size,
15382
0
              error );
15383
15384
0
    if( result == -1 )
15385
0
    {
15386
0
      libcerror_error_set(
15387
0
       error,
15388
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
15389
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
15390
0
       "%s: unable to retrieve hash value.",
15391
0
       function );
15392
0
    }
15393
0
  }
15394
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
15395
0
  if( libcthreads_read_write_lock_release_for_read(
15396
0
       internal_handle->read_write_lock,
15397
0
       error ) != 1 )
15398
0
  {
15399
0
    libcerror_error_set(
15400
0
     error,
15401
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15402
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15403
0
     "%s: unable to release read/write lock for reading.",
15404
0
     function );
15405
15406
0
    return( -1 );
15407
0
  }
15408
0
#endif
15409
0
  return( result );
15410
0
}
15411
15412
/* Sets the UTF-8 encoded hash value specified by the identifier
15413
 * Returns 1 if successful or -1 on error
15414
 */
15415
int libewf_handle_set_utf8_hash_value(
15416
     libewf_handle_t *handle,
15417
     const uint8_t *identifier,
15418
     size_t identifier_length,
15419
     const uint8_t *utf8_string,
15420
     size_t utf8_string_length,
15421
     libcerror_error_t **error )
15422
0
{
15423
0
  libewf_internal_handle_t *internal_handle = NULL;
15424
0
  static char *function                     = "libewf_handle_set_utf8_hash_value";
15425
0
  int result                                = 1;
15426
15427
0
  if( handle == NULL )
15428
0
  {
15429
0
    libcerror_error_set(
15430
0
     error,
15431
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
15432
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
15433
0
     "%s: invalid handle.",
15434
0
     function );
15435
15436
0
    return( -1 );
15437
0
  }
15438
0
  internal_handle = (libewf_internal_handle_t *) handle;
15439
15440
0
  if( internal_handle->io_handle == NULL )
15441
0
  {
15442
0
    libcerror_error_set(
15443
0
     error,
15444
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15445
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
15446
0
     "%s: invalid handle - missing IO handle.",
15447
0
     function );
15448
15449
0
    return( -1 );
15450
0
  }
15451
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
15452
0
  if( libcthreads_read_write_lock_grab_for_write(
15453
0
       internal_handle->read_write_lock,
15454
0
       error ) != 1 )
15455
0
  {
15456
0
    libcerror_error_set(
15457
0
     error,
15458
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15459
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15460
0
     "%s: unable to grab read/write lock for writing.",
15461
0
     function );
15462
15463
0
    return( -1 );
15464
0
  }
15465
0
#endif
15466
0
  if( ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
15467
0
   && ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_RESUME ) == 0 ) )
15468
0
  {
15469
0
    libcerror_error_set(
15470
0
     error,
15471
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15472
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15473
0
     "%s: hash value cannot be changed.",
15474
0
     function );
15475
15476
0
    result = -1;
15477
0
  }
15478
0
  else if( internal_handle->hash_values == NULL )
15479
0
  {
15480
0
    if( libewf_hash_values_initialize(
15481
0
         &( internal_handle->hash_values ),
15482
0
         error ) != 1 )
15483
0
    {
15484
0
      libcerror_error_set(
15485
0
       error,
15486
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
15487
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
15488
0
       "%s: unable to create hash values.",
15489
0
       function );
15490
15491
0
      result = -1;
15492
0
    }
15493
0
    else
15494
0
    {
15495
0
      internal_handle->hash_values_parsed = 1;
15496
0
    }
15497
0
  }
15498
0
  if( result == 1 )
15499
0
  {
15500
0
    result = libewf_value_table_copy_value_from_utf8_string(
15501
0
              internal_handle->hash_values,
15502
0
              identifier,
15503
0
              identifier_length,
15504
0
              utf8_string,
15505
0
              utf8_string_length,
15506
0
              error );
15507
15508
0
    if( result != 1 )
15509
0
    {
15510
0
      libcerror_error_set(
15511
0
       error,
15512
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
15513
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15514
0
       "%s: unable to set hash value.",
15515
0
       function );
15516
0
    }
15517
0
    else if( internal_handle->hash_sections != NULL )
15518
0
    {
15519
0
      result = libewf_hash_sections_set_digest_from_hash_values(
15520
0
          internal_handle->hash_sections,
15521
0
          identifier,
15522
0
          identifier_length,
15523
0
          internal_handle->hash_values,
15524
0
          error );
15525
15526
0
      if( result != 1 )
15527
0
      {
15528
0
        libcerror_error_set(
15529
0
         error,
15530
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
15531
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15532
0
         "%s: unable to set digest in hash sections.",
15533
0
         function );
15534
0
      }
15535
0
    }
15536
0
  }
15537
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
15538
0
  if( libcthreads_read_write_lock_release_for_write(
15539
0
       internal_handle->read_write_lock,
15540
0
       error ) != 1 )
15541
0
  {
15542
0
    libcerror_error_set(
15543
0
     error,
15544
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15545
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15546
0
     "%s: unable to release read/write lock for writing.",
15547
0
     function );
15548
15549
0
    return( -1 );
15550
0
  }
15551
0
#endif
15552
0
  return( result );
15553
0
}
15554
15555
/* Retrieves the size of the UTF-16 encoded hash value of an identifier
15556
 * The string size includes the end of string character
15557
 * Returns 1 if successful, 0 if not set or -1 on error
15558
 */
15559
int libewf_handle_get_utf16_hash_value_size(
15560
     libewf_handle_t *handle,
15561
     const uint8_t *identifier,
15562
     size_t identifier_length,
15563
     size_t *utf16_string_size,
15564
     libcerror_error_t **error )
15565
0
{
15566
0
  libewf_internal_handle_t *internal_handle = NULL;
15567
0
  static char *function                     = "libewf_handle_get_utf16_hash_value_size";
15568
0
  int result                                = 0;
15569
15570
0
  if( handle == NULL )
15571
0
  {
15572
0
    libcerror_error_set(
15573
0
     error,
15574
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
15575
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
15576
0
     "%s: invalid handle.",
15577
0
     function );
15578
15579
0
    return( -1 );
15580
0
  }
15581
0
  internal_handle = (libewf_internal_handle_t *) handle;
15582
15583
/* TODO add write lock */
15584
0
  if( internal_handle->hash_values_parsed == 0 )
15585
0
  {
15586
0
    if( libewf_internal_handle_parse_hash_values(
15587
0
         internal_handle,
15588
0
         error ) != 1 )
15589
0
    {
15590
0
      libcerror_error_set(
15591
0
       error,
15592
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
15593
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15594
0
       "%s: unable to parse hash values.",
15595
0
       function );
15596
15597
0
      return( -1 );
15598
0
    }
15599
0
    internal_handle->hash_values_parsed = 1;
15600
0
  }
15601
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
15602
0
  if( libcthreads_read_write_lock_grab_for_read(
15603
0
       internal_handle->read_write_lock,
15604
0
       error ) != 1 )
15605
0
  {
15606
0
    libcerror_error_set(
15607
0
     error,
15608
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15609
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15610
0
     "%s: unable to grab read/write lock for reading.",
15611
0
     function );
15612
15613
0
    return( -1 );
15614
0
  }
15615
0
#endif
15616
0
  if( internal_handle->hash_values != NULL )
15617
0
  {
15618
0
    result = libewf_value_table_get_utf16_value_size(
15619
0
              internal_handle->hash_values,
15620
0
              identifier,
15621
0
              identifier_length,
15622
0
              utf16_string_size,
15623
0
              error );
15624
15625
0
    if( result == -1 )
15626
0
    {
15627
0
      libcerror_error_set(
15628
0
       error,
15629
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
15630
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
15631
0
       "%s: unable to retrieve hash value size.",
15632
0
       function );
15633
0
    }
15634
0
  }
15635
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
15636
0
  if( libcthreads_read_write_lock_release_for_read(
15637
0
       internal_handle->read_write_lock,
15638
0
       error ) != 1 )
15639
0
  {
15640
0
    libcerror_error_set(
15641
0
     error,
15642
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15643
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15644
0
     "%s: unable to release read/write lock for reading.",
15645
0
     function );
15646
15647
0
    return( -1 );
15648
0
  }
15649
0
#endif
15650
0
  return( result );
15651
0
}
15652
15653
/* Retrieves the UTF-16 encoded hash value of an identifier
15654
 * The string size should include the end of string character
15655
 * Returns 1 if successful, 0 if not set or -1 on error
15656
 */
15657
int libewf_handle_get_utf16_hash_value(
15658
     libewf_handle_t *handle,
15659
     const uint8_t *identifier,
15660
     size_t identifier_length,
15661
     uint16_t *utf16_string,
15662
     size_t utf16_string_size,
15663
     libcerror_error_t **error )
15664
0
{
15665
0
  libewf_internal_handle_t *internal_handle = NULL;
15666
0
  static char *function                     = "libewf_handle_get_utf16_hash_value";
15667
0
  int result                                = 0;
15668
15669
0
  if( handle == NULL )
15670
0
  {
15671
0
    libcerror_error_set(
15672
0
     error,
15673
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
15674
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
15675
0
     "%s: invalid handle.",
15676
0
     function );
15677
15678
0
    return( -1 );
15679
0
  }
15680
0
  internal_handle = (libewf_internal_handle_t *) handle;
15681
15682
/* TODO add write lock */
15683
0
  if( internal_handle->hash_values_parsed == 0 )
15684
0
  {
15685
0
    if( libewf_internal_handle_parse_hash_values(
15686
0
         internal_handle,
15687
0
         error ) != 1 )
15688
0
    {
15689
0
      libcerror_error_set(
15690
0
       error,
15691
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
15692
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15693
0
       "%s: unable to parse hash values.",
15694
0
       function );
15695
15696
0
      return( -1 );
15697
0
    }
15698
0
    internal_handle->hash_values_parsed = 1;
15699
0
  }
15700
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
15701
0
  if( libcthreads_read_write_lock_grab_for_read(
15702
0
       internal_handle->read_write_lock,
15703
0
       error ) != 1 )
15704
0
  {
15705
0
    libcerror_error_set(
15706
0
     error,
15707
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15708
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15709
0
     "%s: unable to grab read/write lock for reading.",
15710
0
     function );
15711
15712
0
    return( -1 );
15713
0
  }
15714
0
#endif
15715
0
  if( internal_handle->hash_values != NULL )
15716
0
  {
15717
0
    result = libewf_value_table_get_utf16_value(
15718
0
              internal_handle->hash_values,
15719
0
              identifier,
15720
0
              identifier_length,
15721
0
              utf16_string,
15722
0
              utf16_string_size,
15723
0
              error );
15724
15725
0
    if( result == -1 )
15726
0
    {
15727
0
      libcerror_error_set(
15728
0
       error,
15729
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
15730
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
15731
0
       "%s: unable to retrieve hash value.",
15732
0
       function );
15733
0
    }
15734
0
  }
15735
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
15736
0
  if( libcthreads_read_write_lock_release_for_read(
15737
0
       internal_handle->read_write_lock,
15738
0
       error ) != 1 )
15739
0
  {
15740
0
    libcerror_error_set(
15741
0
     error,
15742
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15743
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15744
0
     "%s: unable to release read/write lock for reading.",
15745
0
     function );
15746
15747
0
    return( -1 );
15748
0
  }
15749
0
#endif
15750
0
  return( result );
15751
0
}
15752
15753
/* Sets the UTF-16 encoded hash value specified by the identifier
15754
 * Returns 1 if successful or -1 on error
15755
 */
15756
int libewf_handle_set_utf16_hash_value(
15757
     libewf_handle_t *handle,
15758
     const uint8_t *identifier,
15759
     size_t identifier_length,
15760
     const uint16_t *utf16_string,
15761
     size_t utf16_string_length,
15762
     libcerror_error_t **error )
15763
0
{
15764
0
  libewf_internal_handle_t *internal_handle = NULL;
15765
0
  static char *function                     = "libewf_handle_set_utf16_hash_value";
15766
0
  int result                                = 1;
15767
15768
0
  if( handle == NULL )
15769
0
  {
15770
0
    libcerror_error_set(
15771
0
     error,
15772
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
15773
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
15774
0
     "%s: invalid handle.",
15775
0
     function );
15776
15777
0
    return( -1 );
15778
0
  }
15779
0
  internal_handle = (libewf_internal_handle_t *) handle;
15780
15781
0
  if( internal_handle->io_handle == NULL )
15782
0
  {
15783
0
    libcerror_error_set(
15784
0
     error,
15785
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15786
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
15787
0
     "%s: invalid handle - missing IO handle.",
15788
0
     function );
15789
15790
0
    return( -1 );
15791
0
  }
15792
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
15793
0
  if( libcthreads_read_write_lock_grab_for_write(
15794
0
       internal_handle->read_write_lock,
15795
0
       error ) != 1 )
15796
0
  {
15797
0
    libcerror_error_set(
15798
0
     error,
15799
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15800
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15801
0
     "%s: unable to grab read/write lock for writing.",
15802
0
     function );
15803
15804
0
    return( -1 );
15805
0
  }
15806
0
#endif
15807
0
  if( ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
15808
0
   && ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_RESUME ) == 0 ) )
15809
0
  {
15810
0
    libcerror_error_set(
15811
0
     error,
15812
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15813
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15814
0
     "%s: hash value cannot be changed.",
15815
0
     function );
15816
15817
0
    result = -1;
15818
0
  }
15819
0
  else if( internal_handle->hash_values == NULL )
15820
0
  {
15821
0
    if( libewf_hash_values_initialize(
15822
0
         &( internal_handle->hash_values ),
15823
0
         error ) != 1 )
15824
0
    {
15825
0
      libcerror_error_set(
15826
0
       error,
15827
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
15828
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
15829
0
       "%s: unable to create hash values.",
15830
0
       function );
15831
15832
0
      result = -1;
15833
0
    }
15834
0
    else
15835
0
    {
15836
0
      internal_handle->hash_values_parsed = 1;
15837
0
    }
15838
0
  }
15839
0
  if( result == 1 )
15840
0
  {
15841
0
    result = libewf_value_table_copy_value_from_utf16_string(
15842
0
              internal_handle->hash_values,
15843
0
              identifier,
15844
0
              identifier_length,
15845
0
              utf16_string,
15846
0
              utf16_string_length,
15847
0
              error );
15848
15849
0
    if( result != 1 )
15850
0
    {
15851
0
      libcerror_error_set(
15852
0
       error,
15853
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
15854
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15855
0
       "%s: unable to set hash value.",
15856
0
       function );
15857
0
    }
15858
0
    else if( internal_handle->hash_sections != NULL )
15859
0
    {
15860
0
      result = libewf_hash_sections_set_digest_from_hash_values(
15861
0
          internal_handle->hash_sections,
15862
0
          identifier,
15863
0
          identifier_length,
15864
0
          internal_handle->hash_values,
15865
0
          error );
15866
15867
0
      if( result != 1 )
15868
0
      {
15869
0
        libcerror_error_set(
15870
0
         error,
15871
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
15872
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15873
0
         "%s: unable to set digest in hash sections.",
15874
0
         function );
15875
0
      }
15876
0
    }
15877
0
  }
15878
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
15879
0
  if( libcthreads_read_write_lock_release_for_write(
15880
0
       internal_handle->read_write_lock,
15881
0
       error ) != 1 )
15882
0
  {
15883
0
    libcerror_error_set(
15884
0
     error,
15885
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
15886
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
15887
0
     "%s: unable to release read/write lock for writing.",
15888
0
     function );
15889
15890
0
    return( -1 );
15891
0
  }
15892
0
#endif
15893
0
  return( result );
15894
0
}
15895