Coverage Report

Created: 2025-08-28 07:10

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