Coverage Report

Created: 2025-06-22 07:35

/src/libmodi/libmodi/libmodi_handle.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Handle functions
3
 *
4
 * Copyright (C) 2012-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 <system_string.h>
26
#include <types.h>
27
#include <wide_string.h>
28
29
#include "libmodi_bands_data_handle.h"
30
#include "libmodi_block_chunks_data_handle.h"
31
#include "libmodi_data_block.h"
32
#include "libmodi_debug.h"
33
#include "libmodi_definitions.h"
34
#include "libmodi_i18n.h"
35
#include "libmodi_io_handle.h"
36
#include "libmodi_handle.h"
37
#include "libmodi_libbfio.h"
38
#include "libmodi_libcdirectory.h"
39
#include "libmodi_libcerror.h"
40
#include "libmodi_libcfile.h"
41
#include "libmodi_libcnotify.h"
42
#include "libmodi_libcpath.h"
43
#include "libmodi_libcthreads.h"
44
#include "libmodi_libfcache.h"
45
#include "libmodi_libfdata.h"
46
#include "libmodi_libfvalue.h"
47
#include "libmodi_sparse_bundle_xml_plist.h"
48
#include "libmodi_sparse_image_header.h"
49
#include "libmodi_system_string.h"
50
#include "libmodi_udif_block_table.h"
51
#include "libmodi_udif_block_table_entry.h"
52
#include "libmodi_udif_resource_file.h"
53
#include "libmodi_udif_xml_plist.h"
54
55
/* Creates a handle
56
 * Make sure the value handle is referencing, is set to NULL
57
 * Returns 1 if successful or -1 on error
58
 */
59
int libmodi_handle_initialize(
60
     libmodi_handle_t **handle,
61
     libcerror_error_t **error )
62
2.73k
{
63
2.73k
  libmodi_internal_handle_t *internal_handle = NULL;
64
2.73k
  static char *function                      = "libmodi_handle_initialize";
65
66
2.73k
  if( handle == NULL )
67
0
  {
68
0
    libcerror_error_set(
69
0
     error,
70
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
71
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
72
0
     "%s: invalid handle.",
73
0
     function );
74
75
0
    return( -1 );
76
0
  }
77
2.73k
  if( *handle != NULL )
78
0
  {
79
0
    libcerror_error_set(
80
0
     error,
81
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
82
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
83
0
     "%s: invalid handle value already set.",
84
0
     function );
85
86
0
    return( -1 );
87
0
  }
88
2.73k
  internal_handle = memory_allocate_structure(
89
2.73k
                     libmodi_internal_handle_t );
90
91
2.73k
  if( internal_handle == NULL )
92
0
  {
93
0
    libcerror_error_set(
94
0
     error,
95
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
96
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
97
0
     "%s: unable to create handle.",
98
0
     function );
99
100
0
    goto on_error;
101
0
  }
102
2.73k
  if( memory_set(
103
2.73k
       internal_handle,
104
2.73k
       0,
105
2.73k
       sizeof( libmodi_internal_handle_t ) ) == NULL )
106
0
  {
107
0
    libcerror_error_set(
108
0
     error,
109
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
110
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
111
0
     "%s: unable to clear handle.",
112
0
     function );
113
114
0
    memory_free(
115
0
     internal_handle );
116
117
0
    return( -1 );
118
0
  }
119
2.73k
  if( libmodi_io_handle_initialize(
120
2.73k
       &( internal_handle->io_handle ),
121
2.73k
       error ) != 1 )
122
0
  {
123
0
    libcerror_error_set(
124
0
     error,
125
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
126
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
127
0
     "%s: unable to create IO handle.",
128
0
     function );
129
130
0
    goto on_error;
131
0
  }
132
2.73k
  if( libmodi_i18n_initialize(
133
2.73k
       error ) != 1 )
134
0
  {
135
0
    libcerror_error_set(
136
0
     error,
137
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
138
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
139
0
     "%s: unable to initalize internationalization (i18n).",
140
0
     function );
141
142
0
    goto on_error;
143
0
  }
144
2.73k
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
145
2.73k
  if( libcthreads_read_write_lock_initialize(
146
2.73k
       &( internal_handle->read_write_lock ),
147
2.73k
       error ) != 1 )
148
0
  {
149
0
    libcerror_error_set(
150
0
     error,
151
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
152
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
153
0
     "%s: unable to initialize read/write lock.",
154
0
     function );
155
156
0
    goto on_error;
157
0
  }
158
2.73k
#endif
159
2.73k
  internal_handle->maximum_number_of_open_handles = LIBBFIO_POOL_UNLIMITED_NUMBER_OF_OPEN_HANDLES;
160
161
2.73k
  *handle = (libmodi_handle_t *) internal_handle;
162
163
2.73k
  return( 1 );
164
165
0
on_error:
166
0
  if( internal_handle != NULL )
167
0
  {
168
0
    if( internal_handle->io_handle != NULL )
169
0
    {
170
0
      libmodi_io_handle_free(
171
0
       &( internal_handle->io_handle ),
172
0
       NULL );
173
0
    }
174
0
    memory_free(
175
0
     internal_handle );
176
0
  }
177
0
  return( -1 );
178
2.73k
}
179
180
/* Frees a handle
181
 * Returns 1 if successful or -1 on error
182
 */
183
int libmodi_handle_free(
184
     libmodi_handle_t **handle,
185
     libcerror_error_t **error )
186
2.73k
{
187
2.73k
  libmodi_internal_handle_t *internal_handle = NULL;
188
2.73k
  static char *function                      = "libmodi_handle_free";
189
2.73k
  int result                                 = 1;
190
191
2.73k
  if( handle == NULL )
192
0
  {
193
0
    libcerror_error_set(
194
0
     error,
195
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
196
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
197
0
     "%s: invalid handle.",
198
0
     function );
199
200
0
    return( -1 );
201
0
  }
202
2.73k
  if( *handle != NULL )
203
2.73k
  {
204
2.73k
    internal_handle = (libmodi_internal_handle_t *) *handle;
205
206
2.73k
    if( internal_handle->file_io_handle != NULL )
207
0
    {
208
0
      if( libmodi_handle_close(
209
0
           *handle,
210
0
           error ) != 0 )
211
0
      {
212
0
        libcerror_error_set(
213
0
         error,
214
0
         LIBCERROR_ERROR_DOMAIN_IO,
215
0
         LIBCERROR_IO_ERROR_CLOSE_FAILED,
216
0
         "%s: unable to close handle.",
217
0
         function );
218
219
0
        result = -1;
220
0
      }
221
0
    }
222
2.73k
    *handle = NULL;
223
224
2.73k
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
225
2.73k
    if( libcthreads_read_write_lock_free(
226
2.73k
         &( internal_handle->read_write_lock ),
227
2.73k
         error ) != 1 )
228
0
    {
229
0
      libcerror_error_set(
230
0
       error,
231
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
232
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
233
0
       "%s: unable to free read/write lock.",
234
0
       function );
235
236
0
      result = -1;
237
0
    }
238
2.73k
#endif
239
2.73k
    if( internal_handle->bands_directory_path != NULL )
240
0
    {
241
0
      memory_free(
242
0
       internal_handle->bands_directory_path );
243
0
    }
244
2.73k
    if( libmodi_io_handle_free(
245
2.73k
         &( internal_handle->io_handle ),
246
2.73k
         error ) != 1 )
247
0
    {
248
0
      libcerror_error_set(
249
0
       error,
250
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
251
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
252
0
       "%s: unable to free IO handle.",
253
0
       function );
254
255
0
      result = -1;
256
0
    }
257
2.73k
    memory_free(
258
2.73k
     internal_handle );
259
2.73k
  }
260
2.73k
  return( result );
261
2.73k
}
262
263
/* Signals a handle to abort its current activity
264
 * Returns 1 if successful or -1 on error
265
 */
266
int libmodi_handle_signal_abort(
267
     libmodi_handle_t *handle,
268
     libcerror_error_t **error )
269
0
{
270
0
  libmodi_internal_handle_t *internal_handle = NULL;
271
0
  static char *function                      = "libmodi_handle_signal_abort";
272
273
0
  if( handle == NULL )
274
0
  {
275
0
    libcerror_error_set(
276
0
     error,
277
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
278
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
279
0
     "%s: invalid handle.",
280
0
     function );
281
282
0
    return( -1 );
283
0
  }
284
0
  internal_handle = (libmodi_internal_handle_t *) handle;
285
286
0
  if( internal_handle->io_handle == NULL )
287
0
  {
288
0
    libcerror_error_set(
289
0
     error,
290
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
291
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
292
0
     "%s: invalid handle - missing IO handle.",
293
0
     function );
294
295
0
    return( -1 );
296
0
  }
297
0
  internal_handle->io_handle->abort = 1;
298
299
0
  return( 1 );
300
0
}
301
302
/* Sets the bands directory path
303
 * Returns 1 if successful or -1 on error
304
 */
305
int libmodi_internal_handle_set_bands_directory_path(
306
     libmodi_internal_handle_t *internal_handle,
307
     const char *path,
308
     size_t path_length,
309
     libcerror_error_t **error )
310
0
{
311
0
  char *bands_directory_path       = NULL;
312
0
  static char *function            = "libmodi_internal_handle_set_bands_directory_path";
313
0
  size_t bands_directory_path_size = 0;
314
315
0
  if( internal_handle == NULL )
316
0
  {
317
0
    libcerror_error_set(
318
0
     error,
319
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
320
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
321
0
     "%s: invalid handle.",
322
0
     function );
323
324
0
    return( -1 );
325
0
  }
326
0
  if( path == NULL )
327
0
  {
328
0
    libcerror_error_set(
329
0
     error,
330
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
331
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
332
0
     "%s: invalid path.",
333
0
     function );
334
335
0
    goto on_error;
336
0
  }
337
0
  if( internal_handle->bands_directory_path != NULL )
338
0
  {
339
0
    memory_free(
340
0
     internal_handle->bands_directory_path );
341
342
0
    internal_handle->bands_directory_path      = NULL;
343
0
    internal_handle->bands_directory_path_size = 0;
344
0
  }
345
0
  if( libcpath_path_join(
346
0
       &bands_directory_path,
347
0
       &bands_directory_path_size,
348
0
       path,
349
0
       path_length,
350
0
       "bands",
351
0
       5,
352
0
       error ) != 1 )
353
0
  {
354
0
    libcerror_error_set(
355
0
     error,
356
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
357
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
358
0
     "%s: unable to create bands directory path.",
359
0
     function );
360
361
0
    goto on_error;
362
0
  }
363
0
  if( libmodi_system_string_size_from_narrow_string(
364
0
       bands_directory_path,
365
0
       bands_directory_path_size,
366
0
       &( internal_handle->bands_directory_path_size ),
367
0
       error ) != 1 )
368
0
  {
369
0
    libcerror_error_set(
370
0
     error,
371
0
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
372
0
     LIBCERROR_CONVERSION_ERROR_GENERIC,
373
0
     "%s: unable to determine bands directory  size.",
374
0
     function );
375
376
0
    goto on_error;
377
0
  }
378
0
  internal_handle->bands_directory_path = system_string_allocate(
379
0
                                           internal_handle->bands_directory_path_size );
380
381
0
  if( internal_handle->bands_directory_path == NULL )
382
0
  {
383
0
    libcerror_error_set(
384
0
     error,
385
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
386
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
387
0
     "%s: unable to create bands directory path.",
388
0
     function );
389
390
0
    goto on_error;
391
0
  }
392
0
  if( libmodi_system_string_copy_from_narrow_string(
393
0
       internal_handle->bands_directory_path,
394
0
       internal_handle->bands_directory_path_size,
395
0
       bands_directory_path,
396
0
       bands_directory_path_size,
397
0
       error ) != 1 )
398
0
  {
399
0
    libcerror_error_set(
400
0
     error,
401
0
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
402
0
     LIBCERROR_CONVERSION_ERROR_GENERIC,
403
0
     "%s: unable to set bands directory path.",
404
0
     function );
405
406
0
    goto on_error;
407
0
  }
408
0
  memory_free(
409
0
   bands_directory_path );
410
411
0
  return( 1 );
412
413
0
on_error:
414
0
  if( bands_directory_path != NULL )
415
0
  {
416
0
    memory_free(
417
0
     bands_directory_path );
418
0
  }
419
0
  if( internal_handle->bands_directory_path != NULL )
420
0
  {
421
0
    memory_free(
422
0
     internal_handle->bands_directory_path );
423
424
0
    internal_handle->bands_directory_path = NULL;
425
0
  }
426
0
  internal_handle->bands_directory_path_size = 0;
427
428
0
  return( -1 );
429
0
}
430
431
#if defined( HAVE_WIDE_CHARACTER_TYPE )
432
433
/* Sets the bands directory path
434
 * Returns 1 if successful or -1 on error
435
 */
436
int libmodi_internal_handle_set_bands_directory_path_wide(
437
     libmodi_internal_handle_t *internal_handle,
438
     const wchar_t *path,
439
     size_t path_length,
440
     libcerror_error_t **error )
441
{
442
  wchar_t *bands_directory_path    = NULL;
443
  static char *function            = "libmodi_internal_handle_set_bands_directory_path_wide";
444
  size_t bands_directory_path_size = 0;
445
446
  if( internal_handle == NULL )
447
  {
448
    libcerror_error_set(
449
     error,
450
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
451
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
452
     "%s: invalid handle.",
453
     function );
454
455
    return( -1 );
456
  }
457
  if( path == NULL )
458
  {
459
    libcerror_error_set(
460
     error,
461
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
462
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
463
     "%s: invalid path.",
464
     function );
465
466
    goto on_error;
467
  }
468
  if( internal_handle->bands_directory_path != NULL )
469
  {
470
    memory_free(
471
     internal_handle->bands_directory_path );
472
473
    internal_handle->bands_directory_path      = NULL;
474
    internal_handle->bands_directory_path_size = 0;
475
  }
476
  if( libcpath_path_join_wide(
477
       &bands_directory_path,
478
       &bands_directory_path_size,
479
       path,
480
       path_length,
481
       L"bands",
482
       5,
483
       error ) != 1 )
484
  {
485
    libcerror_error_set(
486
     error,
487
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
488
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
489
     "%s: unable to create bands directory path.",
490
     function );
491
492
    goto on_error;
493
  }
494
  if( libmodi_system_string_size_from_wide_string(
495
       bands_directory_path,
496
       bands_directory_path_size,
497
       &( internal_handle->bands_directory_path_size ),
498
       error ) != 1 )
499
  {
500
    libcerror_error_set(
501
     error,
502
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
503
     LIBCERROR_CONVERSION_ERROR_GENERIC,
504
     "%s: unable to determine bands directory  size.",
505
     function );
506
507
    goto on_error;
508
  }
509
  internal_handle->bands_directory_path = system_string_allocate(
510
                                           internal_handle->bands_directory_path_size );
511
512
  if( internal_handle->bands_directory_path == NULL )
513
  {
514
    libcerror_error_set(
515
     error,
516
     LIBCERROR_ERROR_DOMAIN_MEMORY,
517
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
518
     "%s: unable to create bands directory path.",
519
     function );
520
521
    goto on_error;
522
  }
523
  if( libmodi_system_string_copy_from_wide_string(
524
       internal_handle->bands_directory_path,
525
       internal_handle->bands_directory_path_size,
526
       bands_directory_path,
527
       bands_directory_path_size,
528
       error ) != 1 )
529
  {
530
    libcerror_error_set(
531
     error,
532
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
533
     LIBCERROR_CONVERSION_ERROR_GENERIC,
534
     "%s: unable to set bands directory path.",
535
     function );
536
537
    goto on_error;
538
  }
539
  memory_free(
540
   bands_directory_path );
541
542
  return( 1 );
543
544
on_error:
545
  if( bands_directory_path != NULL )
546
  {
547
    memory_free(
548
     bands_directory_path );
549
  }
550
  if( internal_handle->bands_directory_path != NULL )
551
  {
552
    memory_free(
553
     internal_handle->bands_directory_path );
554
555
    internal_handle->bands_directory_path = NULL;
556
  }
557
  internal_handle->bands_directory_path_size = 0;
558
559
  return( -1 );
560
}
561
562
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
563
564
/* Opens a handle
565
 * Returns 1 if successful or -1 on error
566
 */
567
int libmodi_handle_open(
568
     libmodi_handle_t *handle,
569
     const char *filename,
570
     int access_flags,
571
     libcerror_error_t **error )
572
0
{
573
0
  libbfio_handle_t *file_io_handle           = NULL;
574
0
  libcdirectory_directory_t *directory       = NULL;
575
0
  libmodi_internal_handle_t *internal_handle = NULL;
576
0
  char *basename_end                         = NULL;
577
0
  static char *function                      = "libmodi_handle_open";
578
0
  char *info_plist_path                      = NULL;
579
0
  size_t basename_length                     = 0;
580
0
  size_t filename_length                     = 0;
581
0
  size_t info_plist_path_size                = 0;
582
0
  int is_directory                           = 0;
583
584
0
  if( handle == NULL )
585
0
  {
586
0
    libcerror_error_set(
587
0
     error,
588
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
589
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
590
0
     "%s: invalid handle.",
591
0
     function );
592
593
0
    return( -1 );
594
0
  }
595
0
  internal_handle = (libmodi_internal_handle_t *) handle;
596
597
0
  if( internal_handle->io_handle == NULL )
598
0
  {
599
0
    libcerror_error_set(
600
0
     error,
601
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
602
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
603
0
     "%s: invalid handle - missing IO handle.",
604
0
     function );
605
606
0
    return( -1 );
607
0
  }
608
0
  if( filename == NULL )
609
0
  {
610
0
    libcerror_error_set(
611
0
     error,
612
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
613
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
614
0
     "%s: invalid filename.",
615
0
     function );
616
617
0
    return( -1 );
618
0
  }
619
0
  if( ( ( access_flags & LIBMODI_ACCESS_FLAG_READ ) == 0 )
620
0
   && ( ( access_flags & LIBMODI_ACCESS_FLAG_WRITE ) == 0 ) )
621
0
  {
622
0
    libcerror_error_set(
623
0
     error,
624
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
625
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
626
0
     "%s: unsupported access flags.",
627
0
     function );
628
629
0
    return( -1 );
630
0
  }
631
0
  if( ( access_flags & LIBMODI_ACCESS_FLAG_WRITE ) != 0 )
632
0
  {
633
0
    libcerror_error_set(
634
0
     error,
635
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
636
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
637
0
     "%s: write access currently not supported.",
638
0
     function );
639
640
0
    return( -1 );
641
0
  }
642
0
  if( libcdirectory_directory_initialize(
643
0
       &directory,
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 directory.",
651
0
     function );
652
653
0
    goto on_error;
654
0
  }
655
0
  is_directory = libcdirectory_directory_open(
656
0
                  directory,
657
0
                  filename,
658
0
                  NULL );
659
660
0
  if( libcdirectory_directory_free(
661
0
       &directory,
662
0
       error ) != 1 )
663
0
  {
664
0
    libcerror_error_set(
665
0
     error,
666
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
667
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
668
0
     "%s: unable to free directory.",
669
0
     function );
670
671
0
    goto on_error;
672
0
  }
673
0
  if( libbfio_file_initialize(
674
0
       &file_io_handle,
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 file IO handle.",
682
0
     function );
683
684
0
    goto on_error;
685
0
  }
686
#if defined( HAVE_DEBUG_OUTPUT )
687
  if( libbfio_handle_set_track_offsets_read(
688
       file_io_handle,
689
       1,
690
       error ) != 1 )
691
  {
692
    libcerror_error_set(
693
     error,
694
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
695
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
696
     "%s: unable to set track offsets read in file IO handle.",
697
     function );
698
699
    goto on_error;
700
  }
701
#endif
702
0
  if( is_directory == 1 )
703
0
  {
704
0
    filename_length = narrow_string_length(
705
0
                       filename );
706
707
0
    if( libcpath_path_join(
708
0
         &info_plist_path,
709
0
         &info_plist_path_size,
710
0
         filename,
711
0
         filename_length,
712
0
         "Info.plist",
713
0
         10,
714
0
         error ) != 1 )
715
0
    {
716
0
      libcerror_error_set(
717
0
       error,
718
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
719
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
720
0
       "%s: unable to create info.plist path.",
721
0
       function );
722
723
0
      goto on_error;
724
0
    }
725
0
    if( libbfio_file_set_name(
726
0
         file_io_handle,
727
0
         info_plist_path,
728
0
         info_plist_path_size - 1,
729
0
         error ) != 1 )
730
0
    {
731
0
      libcerror_error_set(
732
0
       error,
733
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
734
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
735
0
       "%s: unable to set filename in file IO handle.",
736
0
       function );
737
738
0
      goto on_error;
739
0
    }
740
0
    filename        = info_plist_path;
741
0
    filename_length = info_plist_path_size - 1;
742
0
  }
743
0
  else
744
0
  {
745
0
    filename_length = narrow_string_length(
746
0
                       filename );
747
748
0
    if( libbfio_file_set_name(
749
0
         file_io_handle,
750
0
         filename,
751
0
         filename_length,
752
0
         error ) != 1 )
753
0
    {
754
0
      libcerror_error_set(
755
0
       error,
756
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
757
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
758
0
       "%s: unable to set filename in file IO handle.",
759
0
       function );
760
761
0
      goto on_error;
762
0
    }
763
0
  }
764
0
  if( libmodi_handle_open_file_io_handle(
765
0
       handle,
766
0
       file_io_handle,
767
0
       access_flags,
768
0
       error ) != 1 )
769
0
  {
770
0
    libcerror_error_set(
771
0
     error,
772
0
     LIBCERROR_ERROR_DOMAIN_IO,
773
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
774
0
     "%s: unable to open handle from file: %s.",
775
0
     function,
776
0
     filename );
777
778
0
    goto on_error;
779
0
  }
780
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
781
0
  if( libcthreads_read_write_lock_grab_for_write(
782
0
       internal_handle->read_write_lock,
783
0
       error ) != 1 )
784
0
  {
785
0
    libcerror_error_set(
786
0
     error,
787
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
788
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
789
0
     "%s: unable to grab read/write lock for writing.",
790
0
     function );
791
792
0
    return( -1 );
793
0
  }
794
0
#endif
795
0
  if( internal_handle->io_handle->image_type == LIBMODI_IMAGE_TYPE_SPARSE_BUNDLE )
796
0
  {
797
0
    filename_length = narrow_string_length(
798
0
                       filename );
799
800
0
    basename_end = narrow_string_search_character_reverse(
801
0
                    filename,
802
0
                    (int) LIBCPATH_SEPARATOR,
803
0
                    filename_length + 1 );
804
805
0
    if( basename_end != NULL )
806
0
    {
807
0
      basename_length = (size_t) ( basename_end - filename );
808
0
    }
809
0
    if( basename_length > 0 )
810
0
    {
811
0
      if( libmodi_internal_handle_set_bands_directory_path(
812
0
           internal_handle,
813
0
           filename,
814
0
           basename_length,
815
0
           error ) != 1 )
816
0
      {
817
0
        libcerror_error_set(
818
0
         error,
819
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
820
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
821
0
         "%s: unable to set bands directory path.",
822
0
         function );
823
824
0
        goto on_error;
825
0
      }
826
0
    }
827
0
  }
828
0
  internal_handle->file_io_handle_created_in_library = 1;
829
830
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
831
0
  if( libcthreads_read_write_lock_release_for_write(
832
0
       internal_handle->read_write_lock,
833
0
       error ) != 1 )
834
0
  {
835
0
    libcerror_error_set(
836
0
     error,
837
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
838
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
839
0
     "%s: unable to release read/write lock for writing.",
840
0
     function );
841
842
0
    return( -1 );
843
0
  }
844
0
#endif
845
0
  if( info_plist_path != NULL )
846
0
  {
847
0
    memory_free(
848
0
     info_plist_path );
849
850
0
    info_plist_path = NULL;
851
0
  }
852
0
  return( 1 );
853
854
0
on_error:
855
0
  if( file_io_handle != NULL )
856
0
  {
857
0
    libbfio_handle_free(
858
0
     &file_io_handle,
859
0
     NULL );
860
0
  }
861
0
  if( info_plist_path != NULL )
862
0
  {
863
0
    memory_free(
864
0
     info_plist_path );
865
0
  }
866
0
  if( directory != NULL )
867
0
  {
868
0
    libcdirectory_directory_free(
869
0
     &directory,
870
0
     NULL );
871
0
  }
872
0
  return( -1 );
873
0
}
874
875
#if defined( HAVE_WIDE_CHARACTER_TYPE )
876
877
/* Opens a handle
878
 * Returns 1 if successful or -1 on error
879
 */
880
int libmodi_handle_open_wide(
881
     libmodi_handle_t *handle,
882
     const wchar_t *filename,
883
     int access_flags,
884
     libcerror_error_t **error )
885
{
886
  libbfio_handle_t *file_io_handle           = NULL;
887
  libcdirectory_directory_t *directory       = NULL;
888
  libmodi_internal_handle_t *internal_handle = NULL;
889
  wchar_t *basename_end                      = NULL;
890
  wchar_t *info_plist_path                   = NULL;
891
  static char *function                      = "libmodi_handle_open_wide";
892
  size_t basename_length                     = 0;
893
  size_t filename_length                     = 0;
894
  size_t info_plist_path_size                = 0;
895
  int is_directory                           = 0;
896
897
  if( handle == NULL )
898
  {
899
    libcerror_error_set(
900
     error,
901
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
902
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
903
     "%s: invalid handle.",
904
     function );
905
906
    return( -1 );
907
  }
908
  internal_handle = (libmodi_internal_handle_t *) handle;
909
910
  if( internal_handle->io_handle == NULL )
911
  {
912
    libcerror_error_set(
913
     error,
914
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
915
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
916
     "%s: invalid handle - missing IO handle.",
917
     function );
918
919
    return( -1 );
920
  }
921
  if( filename == NULL )
922
  {
923
    libcerror_error_set(
924
     error,
925
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
926
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
927
     "%s: invalid filename.",
928
     function );
929
930
    return( -1 );
931
  }
932
  if( ( ( access_flags & LIBMODI_ACCESS_FLAG_READ ) == 0 )
933
   && ( ( access_flags & LIBMODI_ACCESS_FLAG_WRITE ) == 0 ) )
934
  {
935
    libcerror_error_set(
936
     error,
937
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
938
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
939
     "%s: unsupported access flags.",
940
     function );
941
942
    return( -1 );
943
  }
944
  if( ( access_flags & LIBMODI_ACCESS_FLAG_WRITE ) != 0 )
945
  {
946
    libcerror_error_set(
947
     error,
948
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
949
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
950
     "%s: write access currently not supported.",
951
     function );
952
953
    return( -1 );
954
  }
955
  if( libcdirectory_directory_initialize(
956
       &directory,
957
       error ) != 1 )
958
  {
959
    libcerror_error_set(
960
     error,
961
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
962
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
963
     "%s: unable to create directory.",
964
     function );
965
966
    goto on_error;
967
  }
968
  is_directory = libcdirectory_directory_open_wide(
969
                  directory,
970
                  filename,
971
                  NULL );
972
973
  if( libcdirectory_directory_free(
974
       &directory,
975
       error ) != 1 )
976
  {
977
    libcerror_error_set(
978
     error,
979
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
980
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
981
     "%s: unable to free directory.",
982
     function );
983
984
    goto on_error;
985
  }
986
  if( libbfio_file_initialize(
987
       &file_io_handle,
988
       error ) != 1 )
989
  {
990
    libcerror_error_set(
991
     error,
992
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
993
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
994
     "%s: unable to create file IO handle.",
995
     function );
996
997
    goto on_error;
998
  }
999
#if defined( HAVE_DEBUG_OUTPUT )
1000
  if( libbfio_handle_set_track_offsets_read(
1001
       file_io_handle,
1002
       1,
1003
       error ) != 1 )
1004
  {
1005
    libcerror_error_set(
1006
     error,
1007
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1008
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1009
     "%s: unable to set track offsets read in file IO handle.",
1010
     function );
1011
1012
    goto on_error;
1013
  }
1014
#endif
1015
  if( is_directory == 1 )
1016
  {
1017
    filename_length = wide_string_length(
1018
                       filename );
1019
1020
    if( libcpath_path_join_wide(
1021
         &info_plist_path,
1022
         &info_plist_path_size,
1023
         filename,
1024
         filename_length,
1025
         L"Info.plist",
1026
         10,
1027
         error ) != 1 )
1028
    {
1029
      libcerror_error_set(
1030
       error,
1031
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1032
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1033
       "%s: unable to create info.plist path.",
1034
       function );
1035
1036
      goto on_error;
1037
    }
1038
    if( libbfio_file_set_name_wide(
1039
         file_io_handle,
1040
         info_plist_path,
1041
         info_plist_path_size - 1,
1042
         error ) != 1 )
1043
    {
1044
      libcerror_error_set(
1045
       error,
1046
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1047
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1048
       "%s: unable to set filename in file IO handle.",
1049
       function );
1050
1051
      goto on_error;
1052
    }
1053
  }
1054
  else
1055
  {
1056
    filename_length = wide_string_length(
1057
                       filename );
1058
1059
    if( libbfio_file_set_name_wide(
1060
         file_io_handle,
1061
         filename,
1062
         filename_length,
1063
         error ) != 1 )
1064
    {
1065
      libcerror_error_set(
1066
       error,
1067
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1068
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1069
       "%s: unable to set filename in file IO handle.",
1070
       function );
1071
1072
      goto on_error;
1073
    }
1074
  }
1075
  if( libmodi_handle_open_file_io_handle(
1076
       handle,
1077
       file_io_handle,
1078
       access_flags,
1079
       error ) != 1 )
1080
  {
1081
    libcerror_error_set(
1082
     error,
1083
     LIBCERROR_ERROR_DOMAIN_IO,
1084
     LIBCERROR_IO_ERROR_OPEN_FAILED,
1085
     "%s: unable to open handle: %ls.",
1086
     function,
1087
     filename );
1088
1089
    goto on_error;
1090
  }
1091
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
1092
  if( libcthreads_read_write_lock_grab_for_write(
1093
       internal_handle->read_write_lock,
1094
       error ) != 1 )
1095
  {
1096
    libcerror_error_set(
1097
     error,
1098
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1099
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1100
     "%s: unable to grab read/write lock for writing.",
1101
     function );
1102
1103
    return( -1 );
1104
  }
1105
#endif
1106
  if( internal_handle->io_handle->image_type == LIBMODI_IMAGE_TYPE_SPARSE_BUNDLE )
1107
  {
1108
    filename_length = wide_string_length(
1109
                       filename );
1110
1111
/* TODO does this work for UTF-16 ? */
1112
    basename_end = wide_string_search_character_reverse(
1113
                    filename,
1114
                    (int) LIBCPATH_SEPARATOR,
1115
                    filename_length + 1 );
1116
1117
    if( basename_end != NULL )
1118
    {
1119
      basename_length = (size_t) ( basename_end - filename );
1120
    }
1121
    if( basename_length > 0 )
1122
    {
1123
      if( libmodi_internal_handle_set_bands_directory_path_wide(
1124
           internal_handle,
1125
           filename,
1126
           basename_length,
1127
           error ) != 1 )
1128
      {
1129
        libcerror_error_set(
1130
         error,
1131
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1132
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1133
         "%s: unable to set bands directory path.",
1134
         function );
1135
1136
        goto on_error;
1137
      }
1138
    }
1139
  }
1140
  internal_handle->file_io_handle_created_in_library = 1;
1141
1142
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
1143
  if( libcthreads_read_write_lock_release_for_write(
1144
       internal_handle->read_write_lock,
1145
       error ) != 1 )
1146
  {
1147
    libcerror_error_set(
1148
     error,
1149
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1150
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1151
     "%s: unable to release read/write lock for writing.",
1152
     function );
1153
1154
    return( -1 );
1155
  }
1156
#endif
1157
  if( info_plist_path != NULL )
1158
  {
1159
    memory_free(
1160
     info_plist_path );
1161
1162
    info_plist_path = NULL;
1163
  }
1164
  return( 1 );
1165
1166
on_error:
1167
  if( file_io_handle != NULL )
1168
  {
1169
    libbfio_handle_free(
1170
     &file_io_handle,
1171
     NULL );
1172
  }
1173
  if( info_plist_path != NULL )
1174
  {
1175
    memory_free(
1176
     info_plist_path );
1177
  }
1178
  if( directory != NULL )
1179
  {
1180
    libcdirectory_directory_free(
1181
     &directory,
1182
     NULL );
1183
  }
1184
  return( -1 );
1185
}
1186
1187
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
1188
1189
/* Opens a handle using a Basic File IO (bfio) handle
1190
 * Returns 1 if successful or -1 on error
1191
 */
1192
int libmodi_handle_open_file_io_handle(
1193
     libmodi_handle_t *handle,
1194
     libbfio_handle_t *file_io_handle,
1195
     int access_flags,
1196
     libcerror_error_t **error )
1197
2.73k
{
1198
2.73k
  libmodi_internal_handle_t *internal_handle = NULL;
1199
2.73k
  static char *function                      = "libmodi_handle_open_file_io_handle";
1200
2.73k
  uint8_t file_io_handle_opened_in_library   = 0;
1201
2.73k
  int bfio_access_flags                      = 0;
1202
2.73k
  int file_io_handle_is_open                 = 0;
1203
1204
2.73k
  if( handle == NULL )
1205
0
  {
1206
0
    libcerror_error_set(
1207
0
     error,
1208
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1209
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1210
0
     "%s: invalid handle.",
1211
0
     function );
1212
1213
0
    return( -1 );
1214
0
  }
1215
2.73k
  internal_handle = (libmodi_internal_handle_t *) handle;
1216
1217
2.73k
  if( file_io_handle == NULL )
1218
0
  {
1219
0
    libcerror_error_set(
1220
0
     error,
1221
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1222
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1223
0
     "%s: invalid file IO handle.",
1224
0
     function );
1225
1226
0
    return( -1 );
1227
0
  }
1228
2.73k
  if( ( ( access_flags & LIBMODI_ACCESS_FLAG_READ ) == 0 )
1229
2.73k
   && ( ( access_flags & LIBMODI_ACCESS_FLAG_WRITE ) == 0 ) )
1230
0
  {
1231
0
    libcerror_error_set(
1232
0
     error,
1233
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1234
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1235
0
     "%s: unsupported access flags.",
1236
0
     function );
1237
1238
0
    return( -1 );
1239
0
  }
1240
2.73k
  if( ( access_flags & LIBMODI_ACCESS_FLAG_WRITE ) != 0 )
1241
0
  {
1242
0
    libcerror_error_set(
1243
0
     error,
1244
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1245
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1246
0
     "%s: write access currently not supported.",
1247
0
     function );
1248
1249
0
    return( -1 );
1250
0
  }
1251
2.73k
  if( ( access_flags & LIBMODI_ACCESS_FLAG_READ ) != 0 )
1252
2.73k
  {
1253
2.73k
    bfio_access_flags = LIBBFIO_ACCESS_FLAG_READ;
1254
2.73k
  }
1255
2.73k
  file_io_handle_is_open = libbfio_handle_is_open(
1256
2.73k
                            file_io_handle,
1257
2.73k
                            error );
1258
1259
2.73k
  if( file_io_handle_is_open == -1 )
1260
0
  {
1261
0
    libcerror_error_set(
1262
0
     error,
1263
0
     LIBCERROR_ERROR_DOMAIN_IO,
1264
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
1265
0
     "%s: unable to determine if file IO handle is open.",
1266
0
     function );
1267
1268
0
    goto on_error;
1269
0
  }
1270
2.73k
  else if( file_io_handle_is_open == 0 )
1271
2.73k
  {
1272
2.73k
    if( libbfio_handle_open(
1273
2.73k
         file_io_handle,
1274
2.73k
         bfio_access_flags,
1275
2.73k
         error ) != 1 )
1276
0
    {
1277
0
      libcerror_error_set(
1278
0
       error,
1279
0
       LIBCERROR_ERROR_DOMAIN_IO,
1280
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
1281
0
       "%s: unable to open file IO handle.",
1282
0
       function );
1283
1284
0
      goto on_error;
1285
0
    }
1286
2.73k
    file_io_handle_opened_in_library = 1;
1287
2.73k
  }
1288
2.73k
  if( libmodi_internal_handle_open_read(
1289
2.73k
       internal_handle,
1290
2.73k
       file_io_handle,
1291
2.73k
       error ) != 1 )
1292
2.54k
  {
1293
2.54k
    libcerror_error_set(
1294
2.54k
     error,
1295
2.54k
     LIBCERROR_ERROR_DOMAIN_IO,
1296
2.54k
     LIBCERROR_IO_ERROR_READ_FAILED,
1297
2.54k
     "%s: unable to read from file IO handle.",
1298
2.54k
     function );
1299
1300
2.54k
    goto on_error;
1301
2.54k
  }
1302
191
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
1303
191
  if( libcthreads_read_write_lock_grab_for_write(
1304
191
       internal_handle->read_write_lock,
1305
191
       error ) != 1 )
1306
0
  {
1307
0
    libcerror_error_set(
1308
0
     error,
1309
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1310
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1311
0
     "%s: unable to grab read/write lock for writing.",
1312
0
     function );
1313
1314
0
    return( -1 );
1315
0
  }
1316
191
#endif
1317
191
  internal_handle->file_io_handle                   = file_io_handle;
1318
191
  internal_handle->file_io_handle_opened_in_library = file_io_handle_opened_in_library;
1319
191
  internal_handle->access_flags                     = access_flags;
1320
1321
191
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
1322
191
  if( libcthreads_read_write_lock_release_for_write(
1323
191
       internal_handle->read_write_lock,
1324
191
       error ) != 1 )
1325
0
  {
1326
0
    libcerror_error_set(
1327
0
     error,
1328
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1329
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1330
0
     "%s: unable to release read/write lock for writing.",
1331
0
     function );
1332
1333
0
    return( -1 );
1334
0
  }
1335
191
#endif
1336
191
  return( 1 );
1337
1338
2.54k
on_error:
1339
2.54k
  if( file_io_handle_opened_in_library != 0 )
1340
2.54k
  {
1341
2.54k
    libbfio_handle_close(
1342
2.54k
     file_io_handle,
1343
2.54k
     error );
1344
2.54k
  }
1345
2.54k
  return( -1 );
1346
191
}
1347
1348
/* Opens the band data files
1349
 * If the band data filenames were not set explicitly this function assumes the band data files
1350
 * are in the sub directory band in the same location as the Info.plist file
1351
 * Returns 1 if successful or -1 on error
1352
 */
1353
int libmodi_handle_open_band_data_files(
1354
     libmodi_handle_t *handle,
1355
     libcerror_error_t **error )
1356
0
{
1357
0
        libbfio_pool_t *file_io_pool               = NULL;
1358
0
  libmodi_internal_handle_t *internal_handle = NULL;
1359
0
  static char *function                      = "libmodi_handle_open_band_data_files";
1360
0
  int band_index                             = 0;
1361
0
  int result                                 = 0;
1362
1363
0
  if( handle == NULL )
1364
0
  {
1365
0
    libcerror_error_set(
1366
0
     error,
1367
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1368
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1369
0
     "%s: invalid handle.",
1370
0
     function );
1371
1372
0
    return( -1 );
1373
0
  }
1374
0
  internal_handle = (libmodi_internal_handle_t *) handle;
1375
1376
0
  if( ( ( internal_handle->access_flags & LIBMODI_ACCESS_FLAG_READ ) == 0 )
1377
0
   && ( ( internal_handle->access_flags & LIBMODI_ACCESS_FLAG_WRITE ) == 0 ) )
1378
0
  {
1379
0
    libcerror_error_set(
1380
0
     error,
1381
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1382
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1383
0
     "%s: unsupported access flags.",
1384
0
     function );
1385
1386
0
    return( -1 );
1387
0
  }
1388
0
  if( ( internal_handle->access_flags & LIBMODI_ACCESS_FLAG_WRITE ) != 0 )
1389
0
  {
1390
0
    libcerror_error_set(
1391
0
     error,
1392
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1393
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1394
0
     "%s: write access currently not supported.",
1395
0
     function );
1396
1397
0
    return( -1 );
1398
0
  }
1399
0
  if( internal_handle->io_handle == NULL )
1400
0
  {
1401
0
    libcerror_error_set(
1402
0
     error,
1403
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1404
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1405
0
     "%s: invalid handle - missing IO handle.",
1406
0
     function );
1407
1408
0
    return( -1 );
1409
0
  }
1410
0
  if( ( internal_handle->io_handle->image_type == LIBMODI_IMAGE_TYPE_SPARSE_BUNDLE )
1411
0
   && ( internal_handle->io_handle->number_of_bands <= 0 ) )
1412
0
  {
1413
0
    libcerror_error_set(
1414
0
     error,
1415
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1416
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1417
0
     "%s: invalid handle - invalid IO handle - missing number of bands.",
1418
0
     function );
1419
1420
0
    return( -1 );
1421
0
  }
1422
0
  if( internal_handle->band_data_file_io_pool != NULL )
1423
0
  {
1424
0
    libcerror_error_set(
1425
0
     error,
1426
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1427
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1428
0
     "%s: invalid handle - band data file IO pool already exists.",
1429
0
     function );
1430
1431
0
    return( -1 );
1432
0
  }
1433
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
1434
0
  if( libcthreads_read_write_lock_grab_for_write(
1435
0
       internal_handle->read_write_lock,
1436
0
       error ) != 1 )
1437
0
  {
1438
0
    libcerror_error_set(
1439
0
     error,
1440
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1441
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1442
0
     "%s: unable to grab read/write lock for writing.",
1443
0
     function );
1444
1445
0
    return( -1 );
1446
0
  }
1447
0
#endif
1448
0
  if( internal_handle->io_handle->image_type == LIBMODI_IMAGE_TYPE_SPARSE_BUNDLE )
1449
0
  {
1450
0
    if( libbfio_pool_initialize(
1451
0
         &file_io_pool,
1452
0
         internal_handle->io_handle->number_of_bands,
1453
0
         internal_handle->maximum_number_of_open_handles,
1454
0
         error ) != 1 )
1455
0
    {
1456
0
      libcerror_error_set(
1457
0
       error,
1458
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1459
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1460
0
       "%s: unable to create file IO pool.",
1461
0
       function );
1462
1463
0
      goto on_error;
1464
0
    }
1465
0
    for( band_index = 0;
1466
0
         band_index < internal_handle->io_handle->number_of_bands;
1467
0
         band_index++ )
1468
0
    {
1469
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
1470
      result = libmodi_internal_handle_open_band_data_file_wide(
1471
          internal_handle,
1472
          file_io_pool,
1473
          band_index,
1474
          error );
1475
#else
1476
0
      result = libmodi_internal_handle_open_band_data_file(
1477
0
          internal_handle,
1478
0
          file_io_pool,
1479
0
          band_index,
1480
0
          error );
1481
0
#endif
1482
0
      if( result != 1 )
1483
0
      {
1484
0
        libcerror_error_set(
1485
0
         error,
1486
0
         LIBCERROR_ERROR_DOMAIN_IO,
1487
0
         LIBCERROR_IO_ERROR_OPEN_FAILED,
1488
0
         "%s: unable to open band data file: %x.",
1489
0
         function,
1490
0
         band_index );
1491
1492
0
        goto on_error;
1493
0
      }
1494
0
    }
1495
0
    if( libmodi_internal_handle_open_band_data_files_file_io_pool(
1496
0
         internal_handle,
1497
0
         file_io_pool,
1498
0
         error ) != 1 )
1499
0
    {
1500
0
      libcerror_error_set(
1501
0
       error,
1502
0
       LIBCERROR_ERROR_DOMAIN_IO,
1503
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
1504
0
       "%s: unable to open band data files from file IO pool.",
1505
0
       function );
1506
1507
0
      goto on_error;
1508
0
    }
1509
0
    internal_handle->band_data_file_io_pool_created_in_library = 1;
1510
0
  }
1511
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
1512
0
  if( libcthreads_read_write_lock_release_for_write(
1513
0
       internal_handle->read_write_lock,
1514
0
       error ) != 1 )
1515
0
  {
1516
0
    libcerror_error_set(
1517
0
     error,
1518
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1519
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1520
0
     "%s: unable to release read/write lock for writing.",
1521
0
     function );
1522
1523
0
    return( -1 );
1524
0
  }
1525
0
#endif
1526
0
  return( 1 );
1527
1528
0
on_error:
1529
0
  if( file_io_pool != NULL )
1530
0
  {
1531
0
    libbfio_pool_close_all(
1532
0
     file_io_pool,
1533
0
     NULL );
1534
0
    libbfio_pool_free(
1535
0
     &file_io_pool,
1536
0
     NULL );
1537
0
  }
1538
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
1539
0
  libcthreads_read_write_lock_release_for_write(
1540
0
   internal_handle->read_write_lock,
1541
0
   NULL );
1542
0
#endif
1543
0
  return( -1 );
1544
0
}
1545
1546
/* Opens the band data files using a Basic File IO (bfio) pool
1547
 * This function assumes the band data files are in order and
1548
 * non-existing band data files are set to NULL
1549
 * Returns 1 if successful or -1 on error
1550
 */
1551
int libmodi_handle_open_band_data_files_file_io_pool(
1552
     libmodi_handle_t *handle,
1553
     libbfio_pool_t *file_io_pool,
1554
     libcerror_error_t **error )
1555
0
{
1556
0
  libmodi_internal_handle_t *internal_handle = NULL;
1557
0
  static char *function                      = "libmodi_handle_open_band_data_files_file_io_pool";
1558
0
  int result                                 = 1;
1559
1560
0
  if( handle == NULL )
1561
0
  {
1562
0
    libcerror_error_set(
1563
0
     error,
1564
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1565
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1566
0
     "%s: invalid handle.",
1567
0
     function );
1568
1569
0
    return( -1 );
1570
0
  }
1571
0
  internal_handle = (libmodi_internal_handle_t *) handle;
1572
1573
0
  if( ( ( internal_handle->access_flags & LIBMODI_ACCESS_FLAG_READ ) == 0 )
1574
0
   && ( ( internal_handle->access_flags & LIBMODI_ACCESS_FLAG_WRITE ) == 0 ) )
1575
0
  {
1576
0
    libcerror_error_set(
1577
0
     error,
1578
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1579
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1580
0
     "%s: unsupported access flags.",
1581
0
     function );
1582
1583
0
    return( -1 );
1584
0
  }
1585
0
  if( ( internal_handle->access_flags & LIBMODI_ACCESS_FLAG_WRITE ) != 0 )
1586
0
  {
1587
0
    libcerror_error_set(
1588
0
     error,
1589
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1590
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1591
0
     "%s: write access currently not supported.",
1592
0
     function );
1593
1594
0
    return( -1 );
1595
0
  }
1596
0
  if( internal_handle->io_handle == NULL )
1597
0
  {
1598
0
    libcerror_error_set(
1599
0
     error,
1600
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1601
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1602
0
     "%s: invalid handle - missing IO handle.",
1603
0
     function );
1604
1605
0
    return( -1 );
1606
0
  }
1607
0
  if( internal_handle->band_data_file_io_pool != NULL )
1608
0
  {
1609
0
    libcerror_error_set(
1610
0
     error,
1611
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1612
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1613
0
     "%s: invalid handle - band data file IO pool already exists.",
1614
0
     function );
1615
1616
0
    return( -1 );
1617
0
  }
1618
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
1619
0
  if( libcthreads_read_write_lock_grab_for_write(
1620
0
       internal_handle->read_write_lock,
1621
0
       error ) != 1 )
1622
0
  {
1623
0
    libcerror_error_set(
1624
0
     error,
1625
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1626
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1627
0
     "%s: unable to grab read/write lock for writing.",
1628
0
     function );
1629
1630
0
    return( -1 );
1631
0
  }
1632
0
#endif
1633
0
  if( internal_handle->io_handle->image_type == LIBMODI_IMAGE_TYPE_SPARSE_BUNDLE )
1634
0
  {
1635
0
    if( libmodi_internal_handle_open_band_data_files_file_io_pool(
1636
0
         internal_handle,
1637
0
         file_io_pool,
1638
0
         error ) != 1 )
1639
0
    {
1640
0
      libcerror_error_set(
1641
0
       error,
1642
0
       LIBCERROR_ERROR_DOMAIN_IO,
1643
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
1644
0
       "%s: unable to open band data files from file IO pool.",
1645
0
       function );
1646
1647
0
      result = -1;
1648
0
    }
1649
0
  }
1650
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
1651
0
  if( libcthreads_read_write_lock_release_for_write(
1652
0
       internal_handle->read_write_lock,
1653
0
       error ) != 1 )
1654
0
  {
1655
0
    libcerror_error_set(
1656
0
     error,
1657
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1658
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1659
0
     "%s: unable to release read/write lock for writing.",
1660
0
     function );
1661
1662
0
    return( -1 );
1663
0
  }
1664
0
#endif
1665
0
  return( result );
1666
0
}
1667
1668
/* Opens the band data files using a Basic File IO (bfio) pool
1669
 * This function assumes the band data files are in order and
1670
 * non-existing band data files are set to NULL
1671
 * Returns 1 if successful or -1 on error
1672
 */
1673
int libmodi_internal_handle_open_band_data_files_file_io_pool(
1674
     libmodi_internal_handle_t *internal_handle,
1675
     libbfio_pool_t *file_io_pool,
1676
     libcerror_error_t **error )
1677
0
{
1678
0
  libbfio_handle_t *file_io_handle = NULL;
1679
0
  static char *function            = "libmodi_internal_handle_open_band_data_files_file_io_pool";
1680
0
  size64_t band_data_size          = 0;
1681
0
  size64_t file_size               = 0;
1682
0
  size64_t media_size              = 0;
1683
0
  size64_t sparse_band_data_size   = 0;
1684
0
  int file_io_handle_index         = 0;
1685
0
  int number_of_file_io_handles    = 0;
1686
1687
0
  if( internal_handle == NULL )
1688
0
  {
1689
0
    libcerror_error_set(
1690
0
     error,
1691
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1692
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1693
0
     "%s: invalid handle.",
1694
0
     function );
1695
1696
0
    return( -1 );
1697
0
  }
1698
0
  if( internal_handle->band_data_file_io_pool != NULL )
1699
0
  {
1700
0
    libcerror_error_set(
1701
0
     error,
1702
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1703
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1704
0
     "%s: invalid handle - band data file IO pool already exists.",
1705
0
     function );
1706
1707
0
    return( -1 );
1708
0
  }
1709
0
  if( internal_handle->io_handle == NULL )
1710
0
  {
1711
0
    libcerror_error_set(
1712
0
     error,
1713
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1714
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1715
0
     "%s: invalid handle - missing IO handle.",
1716
0
     function );
1717
1718
0
    return( -1 );
1719
0
  }
1720
0
  if( internal_handle->io_handle->band_data_size == 0 )
1721
0
  {
1722
0
    libcerror_error_set(
1723
0
     error,
1724
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1725
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1726
0
     "%s: invalid handle - invalid IO handle - missing band data size.",
1727
0
     function );
1728
1729
0
    return( -1 );
1730
0
  }
1731
0
  if( libbfio_pool_get_number_of_handles(
1732
0
       file_io_pool,
1733
0
       &number_of_file_io_handles,
1734
0
       error ) != 1 )
1735
0
  {
1736
0
    libcerror_error_set(
1737
0
     error,
1738
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1739
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1740
0
     "%s: unable to retrieve number of handles in file IO pool.",
1741
0
     function );
1742
1743
0
    return( -1 );
1744
0
  }
1745
0
  if( number_of_file_io_handles != internal_handle->io_handle->number_of_bands )
1746
0
  {
1747
0
    libcerror_error_set(
1748
0
     error,
1749
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1750
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1751
0
     "%s: invalid number of handles in file IO pool value does not match number of bands.",
1752
0
     function );
1753
1754
0
    return( -1 );
1755
0
  }
1756
0
  media_size = internal_handle->io_handle->media_size;
1757
1758
0
  for( file_io_handle_index = 0;
1759
0
       file_io_handle_index < number_of_file_io_handles;
1760
0
       file_io_handle_index++ )
1761
0
  {
1762
0
    if( libbfio_pool_get_handle(
1763
0
         file_io_pool,
1764
0
         file_io_handle_index,
1765
0
         &file_io_handle,
1766
0
         error ) != 1 )
1767
0
    {
1768
0
      libcerror_error_set(
1769
0
       error,
1770
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1771
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1772
0
       "%s: unable to retrieve handle: %d from file IO pool.",
1773
0
       function,
1774
0
       file_io_handle_index );
1775
1776
0
      return( -1 );
1777
0
    }
1778
0
    if( file_io_handle == NULL )
1779
0
    {
1780
0
      band_data_size        = 0;
1781
0
      sparse_band_data_size = internal_handle->io_handle->band_data_size;
1782
0
    }
1783
0
    else
1784
0
    {
1785
0
      if( libbfio_handle_get_size(
1786
0
           file_io_handle,
1787
0
           &file_size,
1788
0
           error ) != 1 )
1789
0
      {
1790
0
        libcerror_error_set(
1791
0
         error,
1792
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1793
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1794
0
         "%s: unable to retrieve file size.",
1795
0
         function );
1796
1797
0
        return( -1 );
1798
0
      }
1799
0
      if( internal_handle->io_handle->band_data_size < media_size )
1800
0
      {
1801
0
        sparse_band_data_size = internal_handle->io_handle->band_data_size;
1802
0
      }
1803
0
      else
1804
0
      {
1805
0
        sparse_band_data_size = media_size;
1806
0
      }
1807
0
      if( file_size > sparse_band_data_size )
1808
0
      {
1809
0
        libcerror_error_set(
1810
0
         error,
1811
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1812
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1813
0
         "%s: invalid band data file: %d size value out of bounds.",
1814
0
         function,
1815
0
         file_io_handle_index );
1816
1817
0
        return( -1 );
1818
0
      }
1819
0
      band_data_size         = file_size;
1820
0
      sparse_band_data_size -= file_size;
1821
0
    }
1822
0
    if( band_data_size > 0 )
1823
0
    {
1824
0
      if( libmodi_bands_data_handle_append_segment(
1825
0
           internal_handle->bands_data_handle,
1826
0
           file_io_handle_index,
1827
0
           0,
1828
0
           band_data_size,
1829
0
           0,
1830
0
           error ) != 1 )
1831
0
      {
1832
0
        libcerror_error_set(
1833
0
         error,
1834
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1835
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1836
0
         "%s: unable to append band data file: %d as segment to bands data handle.",
1837
0
         function,
1838
0
         file_io_handle_index );
1839
1840
0
        return( -1 );
1841
0
      }
1842
0
    }
1843
0
    if( sparse_band_data_size > 0 )
1844
0
    {
1845
0
      if( libmodi_bands_data_handle_append_segment(
1846
0
           internal_handle->bands_data_handle,
1847
0
           file_io_handle_index,
1848
0
           0,
1849
0
           sparse_band_data_size,
1850
0
           LIBFDATA_RANGE_FLAG_IS_SPARSE,
1851
0
           error ) != 1 )
1852
0
      {
1853
0
        libcerror_error_set(
1854
0
         error,
1855
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1856
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1857
0
         "%s: unable to append band data file: %d as sparse segment to bands data handle.",
1858
0
         function,
1859
0
         file_io_handle_index );
1860
1861
0
        return( -1 );
1862
0
      }
1863
0
    }
1864
0
    media_size -= internal_handle->io_handle->band_data_size;
1865
0
  }
1866
0
  internal_handle->band_data_file_io_pool = file_io_pool;
1867
1868
0
  return( 1 );
1869
0
}
1870
1871
/* Opens a specific band data file
1872
 * Returns 1 if successful or -1 on error
1873
 */
1874
int libmodi_internal_handle_open_band_data_file(
1875
     libmodi_internal_handle_t *internal_handle,
1876
     libbfio_pool_t *file_io_pool,
1877
     int band_index,
1878
     libcerror_error_t **error )
1879
0
{
1880
0
  char filename[ 16 ];
1881
1882
0
  libbfio_handle_t *file_io_handle = NULL;
1883
0
  char *bands_file_path            = NULL;
1884
0
  static char *function            = "libmodi_internal_handle_open_band_data_file";
1885
0
  size_t bands_file_path_size      = 0;
1886
0
  size_t filename_length           = 0;
1887
0
  int bfio_access_flags            = 0;
1888
0
  int result                       = 0;
1889
1890
0
  if( internal_handle == NULL )
1891
0
  {
1892
0
    libcerror_error_set(
1893
0
     error,
1894
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1895
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1896
0
     "%s: invalid handle.",
1897
0
     function );
1898
1899
0
    return( -1 );
1900
0
  }
1901
0
  if( libfvalue_utf8_string_copy_from_integer(
1902
0
       (uint8_t *) filename,
1903
0
       16,
1904
0
       band_index,
1905
0
       SIZEOF_INT * 8,
1906
0
       LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR | LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL,
1907
0
       error ) != 1 )
1908
0
  {
1909
0
    libcerror_error_set(
1910
0
     error,
1911
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1912
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1913
0
     "%s: unable to copy band index to string.",
1914
0
     function );
1915
1916
0
    goto on_error;
1917
0
  }
1918
0
  filename_length = narrow_string_length(
1919
0
                     filename );
1920
1921
0
  if( libcpath_path_join(
1922
0
       &bands_file_path,
1923
0
       &bands_file_path_size,
1924
0
       (char *) internal_handle->bands_directory_path,
1925
0
       internal_handle->bands_directory_path_size - 1,
1926
0
       filename,
1927
0
       filename_length,
1928
0
       error ) != 1 )
1929
0
  {
1930
0
    libcerror_error_set(
1931
0
     error,
1932
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1933
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1934
0
     "%s: unable to create bands file: %d path.",
1935
0
     function,
1936
0
     band_index );
1937
1938
0
    goto on_error;
1939
0
  }
1940
0
  result = libcfile_file_exists(
1941
0
            bands_file_path,
1942
0
            error );
1943
1944
0
  if( result == -1 )
1945
0
  {
1946
0
    libcerror_error_set(
1947
0
     error,
1948
0
     LIBCERROR_ERROR_DOMAIN_IO,
1949
0
     LIBCERROR_IO_ERROR_GENERIC,
1950
0
     "%s: unable to determine if band data file exists.",
1951
0
     function );
1952
0
  }
1953
0
  else if( result != 0 )
1954
0
  {
1955
0
    if( ( internal_handle->access_flags & LIBMODI_ACCESS_FLAG_READ ) != 0 )
1956
0
    {
1957
0
      bfio_access_flags = LIBBFIO_ACCESS_FLAG_READ;
1958
0
    }
1959
0
    if( libbfio_file_initialize(
1960
0
         &file_io_handle,
1961
0
         error ) != 1 )
1962
0
    {
1963
0
      libcerror_error_set(
1964
0
       error,
1965
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1966
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1967
0
       "%s: unable to create file IO handle.",
1968
0
       function );
1969
1970
0
      goto on_error;
1971
0
    }
1972
#if defined( HAVE_DEBUG_OUTPUT )
1973
    if( libbfio_handle_set_track_offsets_read(
1974
         file_io_handle,
1975
         1,
1976
         error ) != 1 )
1977
    {
1978
      libcerror_error_set(
1979
       error,
1980
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1981
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1982
       "%s: unable to set track offsets read in file IO handle.",
1983
       function );
1984
1985
      goto on_error;
1986
    }
1987
#endif
1988
0
    if( libbfio_file_set_name(
1989
0
         file_io_handle,
1990
0
         bands_file_path,
1991
0
         bands_file_path_size,
1992
0
         error ) != 1 )
1993
0
    {
1994
0
      libcerror_error_set(
1995
0
       error,
1996
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1997
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1998
0
       "%s: unable to set filename in file IO handle.",
1999
0
       function );
2000
2001
0
      goto on_error;
2002
0
    }
2003
0
    if( libbfio_handle_open(
2004
0
         file_io_handle,
2005
0
         bfio_access_flags,
2006
0
         error ) != 1 )
2007
0
    {
2008
0
      libcerror_error_set(
2009
0
       error,
2010
0
       LIBCERROR_ERROR_DOMAIN_IO,
2011
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
2012
0
       "%s: unable to open file IO handle.",
2013
0
       function );
2014
2015
0
      goto on_error;
2016
0
    }
2017
0
    if( libbfio_pool_set_handle(
2018
0
         file_io_pool,
2019
0
         band_index,
2020
0
         file_io_handle,
2021
0
         bfio_access_flags,
2022
0
         error ) != 1 )
2023
0
    {
2024
0
      libcerror_error_set(
2025
0
       error,
2026
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2027
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2028
0
       "%s: unable to set file IO handle: %d in pool.",
2029
0
       function,
2030
0
       band_index );
2031
2032
0
      goto on_error;
2033
0
    }
2034
0
  }
2035
0
  memory_free(
2036
0
   bands_file_path );
2037
2038
0
  return( 1 );
2039
2040
0
on_error:
2041
0
  if( file_io_handle != NULL )
2042
0
  {
2043
0
    libbfio_handle_free(
2044
0
     &file_io_handle,
2045
0
     NULL );
2046
0
  }
2047
0
  if( bands_file_path != NULL )
2048
0
  {
2049
0
    memory_free(
2050
0
     bands_file_path );
2051
0
  }
2052
0
  return( -1 );
2053
0
}
2054
2055
#if defined( HAVE_WIDE_CHARACTER_TYPE )
2056
2057
/* Opens a specific band data file
2058
 * Returns 1 if successful or -1 on error
2059
 */
2060
int libmodi_internal_handle_open_band_data_file_wide(
2061
     libmodi_internal_handle_t *internal_handle,
2062
     libbfio_pool_t *file_io_pool,
2063
     int band_index,
2064
     libcerror_error_t **error )
2065
{
2066
  wchar_t filename[ 16 ];
2067
2068
  libbfio_handle_t *file_io_handle = NULL;
2069
  wchar_t *bands_file_path         = NULL;
2070
  static char *function            = "libmodi_internal_handle_open_band_data_file_wide";
2071
  size_t bands_file_path_size      = 0;
2072
  size_t filename_length           = 0;
2073
  int bfio_access_flags            = 0;
2074
  int result                       = 0;
2075
2076
  if( internal_handle == NULL )
2077
  {
2078
    libcerror_error_set(
2079
     error,
2080
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2081
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2082
     "%s: invalid handle.",
2083
     function );
2084
2085
    return( -1 );
2086
  }
2087
#if ( SIZEOF_WCHAR_T == 4 )
2088
  result = libfvalue_utf32_string_copy_from_integer(
2089
            (uint32_t *) filename,
2090
            16,
2091
            band_index,
2092
            SIZEOF_INT * 8,
2093
            LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR | LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL,
2094
            error );
2095
#else
2096
  result = libfvalue_utf16_string_copy_from_integer(
2097
            (uint16_t *) filename,
2098
            16,
2099
            band_index,
2100
            SIZEOF_INT * 8,
2101
            LIBFVALUE_INTEGER_FORMAT_FLAG_NO_BASE_INDICATOR | LIBFVALUE_INTEGER_FORMAT_TYPE_HEXADECIMAL,
2102
            error );
2103
#endif
2104
  if( result != 1 )
2105
  {
2106
    libcerror_error_set(
2107
     error,
2108
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2109
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2110
     "%s: unable to copy band index to string.",
2111
     function );
2112
2113
    goto on_error;
2114
  }
2115
  filename_length = wide_string_length(
2116
                     filename );
2117
2118
  if( libcpath_path_join_wide(
2119
       &bands_file_path,
2120
       &bands_file_path_size,
2121
       (wchar_t *) internal_handle->bands_directory_path,
2122
       internal_handle->bands_directory_path_size - 1,
2123
       filename,
2124
       filename_length,
2125
       error ) != 1 )
2126
  {
2127
    libcerror_error_set(
2128
     error,
2129
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2130
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2131
     "%s: unable to create bands file path.",
2132
     function );
2133
2134
    goto on_error;
2135
  }
2136
  result = libcfile_file_exists_wide(
2137
            bands_file_path,
2138
            error );
2139
2140
  if( result == -1 )
2141
  {
2142
    libcerror_error_set(
2143
     error,
2144
     LIBCERROR_ERROR_DOMAIN_IO,
2145
     LIBCERROR_IO_ERROR_GENERIC,
2146
     "%s: unable to determine if band data file exists.",
2147
     function );
2148
  }
2149
  else if( result != 0 )
2150
  {
2151
    if( ( internal_handle->access_flags & LIBMODI_ACCESS_FLAG_READ ) != 0 )
2152
    {
2153
      bfio_access_flags = LIBBFIO_ACCESS_FLAG_READ;
2154
    }
2155
    if( libbfio_file_initialize(
2156
         &file_io_handle,
2157
         error ) != 1 )
2158
    {
2159
      libcerror_error_set(
2160
       error,
2161
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2162
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2163
       "%s: unable to create file IO handle.",
2164
       function );
2165
2166
      goto on_error;
2167
    }
2168
#if defined( HAVE_DEBUG_OUTPUT )
2169
    if( libbfio_handle_set_track_offsets_read(
2170
         file_io_handle,
2171
         1,
2172
         error ) != 1 )
2173
    {
2174
      libcerror_error_set(
2175
       error,
2176
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2177
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2178
       "%s: unable to set track offsets read in file IO handle.",
2179
       function );
2180
2181
      goto on_error;
2182
    }
2183
#endif
2184
    if( libbfio_file_set_name_wide(
2185
         file_io_handle,
2186
         bands_file_path,
2187
         bands_file_path_size,
2188
         error ) != 1 )
2189
    {
2190
      libcerror_error_set(
2191
       error,
2192
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2193
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2194
       "%s: unable to set filename in file IO handle.",
2195
       function );
2196
2197
      goto on_error;
2198
    }
2199
    if( libbfio_handle_open(
2200
         file_io_handle,
2201
         bfio_access_flags,
2202
         error ) != 1 )
2203
    {
2204
      libcerror_error_set(
2205
       error,
2206
       LIBCERROR_ERROR_DOMAIN_IO,
2207
       LIBCERROR_IO_ERROR_OPEN_FAILED,
2208
       "%s: unable to open file IO handle.",
2209
       function );
2210
2211
      goto on_error;
2212
    }
2213
    if( libbfio_pool_set_handle(
2214
         file_io_pool,
2215
         band_index,
2216
         file_io_handle,
2217
         bfio_access_flags,
2218
         error ) != 1 )
2219
    {
2220
      libcerror_error_set(
2221
       error,
2222
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2223
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2224
       "%s: unable to set file IO handle: %d in pool.",
2225
       function,
2226
       band_index );
2227
2228
      goto on_error;
2229
    }
2230
  }
2231
  memory_free(
2232
   bands_file_path );
2233
2234
  return( 1 );
2235
2236
on_error:
2237
  if( file_io_handle != NULL )
2238
  {
2239
    libbfio_handle_free(
2240
     &file_io_handle,
2241
     NULL );
2242
  }
2243
  if( bands_file_path != NULL )
2244
  {
2245
    memory_free(
2246
     bands_file_path );
2247
  }
2248
  return( -1 );
2249
}
2250
2251
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
2252
2253
/* Closes a handle
2254
 * Returns 0 if successful or -1 on error
2255
 */
2256
int libmodi_handle_close(
2257
     libmodi_handle_t *handle,
2258
     libcerror_error_t **error )
2259
191
{
2260
191
  libmodi_internal_handle_t *internal_handle = NULL;
2261
191
  static char *function                      = "libmodi_handle_close";
2262
191
  int result                                 = 0;
2263
2264
191
  if( handle == NULL )
2265
0
  {
2266
0
    libcerror_error_set(
2267
0
     error,
2268
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2269
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2270
0
     "%s: invalid handle.",
2271
0
     function );
2272
2273
0
    return( -1 );
2274
0
  }
2275
191
  internal_handle = (libmodi_internal_handle_t *) handle;
2276
2277
191
  if( internal_handle->file_io_handle == NULL )
2278
0
  {
2279
0
    libcerror_error_set(
2280
0
     error,
2281
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2282
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2283
0
     "%s: invalid handle - missing file IO handle.",
2284
0
     function );
2285
2286
0
    return( -1 );
2287
0
  }
2288
191
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
2289
191
  if( libcthreads_read_write_lock_grab_for_write(
2290
191
       internal_handle->read_write_lock,
2291
191
       error ) != 1 )
2292
0
  {
2293
0
    libcerror_error_set(
2294
0
     error,
2295
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2296
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2297
0
     "%s: unable to grab read/write lock for writing.",
2298
0
     function );
2299
2300
0
    return( -1 );
2301
0
  }
2302
191
#endif
2303
#if defined( HAVE_DEBUG_OUTPUT )
2304
  if( libcnotify_verbose != 0 )
2305
  {
2306
    if( internal_handle->file_io_handle_created_in_library != 0 )
2307
    {
2308
      if( libmodi_debug_print_read_offsets(
2309
           internal_handle->file_io_handle,
2310
           error ) != 1 )
2311
      {
2312
        libcerror_error_set(
2313
         error,
2314
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2315
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
2316
         "%s: unable to print the read offsets.",
2317
         function );
2318
2319
        result = -1;
2320
      }
2321
    }
2322
  }
2323
#endif
2324
191
  if( internal_handle->band_data_file_io_pool_created_in_library != 0 )
2325
0
  {
2326
0
    if( libbfio_pool_close_all(
2327
0
         internal_handle->band_data_file_io_pool,
2328
0
         error ) != 0 )
2329
0
    {
2330
0
      libcerror_error_set(
2331
0
       error,
2332
0
       LIBCERROR_ERROR_DOMAIN_IO,
2333
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
2334
0
       "%s: unable to close all files in band data file IO pool.",
2335
0
       function );
2336
2337
0
      result = -1;
2338
0
    }
2339
0
    if( libbfio_pool_free(
2340
0
         &( internal_handle->band_data_file_io_pool ),
2341
0
         error ) != 1 )
2342
0
    {
2343
0
      libcerror_error_set(
2344
0
       error,
2345
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2346
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2347
0
       "%s: unable to free band data file IO pool.",
2348
0
       function );
2349
2350
0
      result = -1;
2351
0
    }
2352
0
    internal_handle->band_data_file_io_pool_created_in_library = 0;
2353
0
  }
2354
191
  internal_handle->band_data_file_io_pool = NULL;
2355
2356
191
  if( internal_handle->file_io_handle_opened_in_library != 0 )
2357
191
  {
2358
191
    if( libbfio_handle_close(
2359
191
         internal_handle->file_io_handle,
2360
191
         error ) != 0 )
2361
0
    {
2362
0
      libcerror_error_set(
2363
0
       error,
2364
0
       LIBCERROR_ERROR_DOMAIN_IO,
2365
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
2366
0
       "%s: unable to close file IO handle.",
2367
0
       function );
2368
2369
0
      result = -1;
2370
0
    }
2371
191
    internal_handle->file_io_handle_opened_in_library = 0;
2372
191
  }
2373
191
  if( internal_handle->file_io_handle_created_in_library != 0 )
2374
0
  {
2375
0
    if( libbfio_handle_free(
2376
0
         &( internal_handle->file_io_handle ),
2377
0
         error ) != 1 )
2378
0
    {
2379
0
      libcerror_error_set(
2380
0
       error,
2381
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2382
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2383
0
       "%s: unable to free file IO handle.",
2384
0
       function );
2385
2386
0
      result = -1;
2387
0
    }
2388
0
    internal_handle->file_io_handle_created_in_library = 0;
2389
0
  }
2390
191
  internal_handle->file_io_handle = NULL;
2391
2392
191
  if( libmodi_io_handle_clear(
2393
191
       internal_handle->io_handle,
2394
191
       error ) != 1 )
2395
0
  {
2396
0
    libcerror_error_set(
2397
0
     error,
2398
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2399
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2400
0
     "%s: unable to clear IO handle.",
2401
0
     function );
2402
2403
0
    result = -1;
2404
0
  }
2405
191
  if( libfdata_stream_free(
2406
191
       &( internal_handle->data_stream ),
2407
191
       error ) != 1 )
2408
0
  {
2409
0
    libcerror_error_set(
2410
0
     error,
2411
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2412
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2413
0
     "%s: unable to free data stream.",
2414
0
     function );
2415
2416
0
    result = -1;
2417
0
  }
2418
191
  if( internal_handle->bands_data_handle != NULL )
2419
110
  {
2420
110
    if( libmodi_bands_data_handle_free(
2421
110
         &( internal_handle->bands_data_handle ),
2422
110
         error ) != 1 )
2423
0
    {
2424
0
      libcerror_error_set(
2425
0
       error,
2426
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2427
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2428
0
       "%s: unable to free bands data handle.",
2429
0
       function );
2430
2431
0
      result = -1;
2432
0
    }
2433
110
  }
2434
191
  if( internal_handle->block_chunks_data_handle != NULL )
2435
81
  {
2436
81
    if( libmodi_block_chunks_data_handle_free(
2437
81
         &( internal_handle->block_chunks_data_handle ),
2438
81
         error ) != 1 )
2439
0
    {
2440
0
      libcerror_error_set(
2441
0
       error,
2442
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2443
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2444
0
       "%s: unable to free block chunks data handle.",
2445
0
       function );
2446
2447
0
      result = -1;
2448
0
    }
2449
81
  }
2450
191
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
2451
191
  if( libcthreads_read_write_lock_release_for_write(
2452
191
       internal_handle->read_write_lock,
2453
191
       error ) != 1 )
2454
0
  {
2455
0
    libcerror_error_set(
2456
0
     error,
2457
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2458
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2459
0
     "%s: unable to release read/write lock for writing.",
2460
0
     function );
2461
2462
0
    return( -1 );
2463
0
  }
2464
191
#endif
2465
191
  return( result );
2466
191
}
2467
2468
/* Opens a handle for reading
2469
 * Returns 1 if successful or -1 on error
2470
 */
2471
int libmodi_internal_handle_open_read(
2472
     libmodi_internal_handle_t *internal_handle,
2473
     libbfio_handle_t *file_io_handle,
2474
     libcerror_error_t **error )
2475
2.73k
{
2476
2.73k
  static char *function      = "libmodi_internal_handle_open_read";
2477
2.73k
  size64_t element_size      = 0;
2478
2.73k
  size64_t file_size         = 0;
2479
2.73k
  size64_t mapped_size       = 0;
2480
2.73k
  off64_t element_offset     = 0;
2481
2.73k
  off64_t mapped_offset      = 0;
2482
2.73k
  uint32_t element_flags     = 0;
2483
2.73k
  int block_chunk_index      = 0;
2484
2.73k
  int element_file_index     = 0;
2485
2.73k
  int number_of_block_chunks = 0;
2486
2.73k
  int result                 = 0;
2487
2.73k
  int segment_index          = 0;
2488
2489
2.73k
  if( internal_handle == NULL )
2490
0
  {
2491
0
    libcerror_error_set(
2492
0
     error,
2493
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2494
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2495
0
     "%s: invalid handle.",
2496
0
     function );
2497
2498
0
    return( -1 );
2499
0
  }
2500
2.73k
  if( internal_handle->io_handle == NULL )
2501
0
  {
2502
0
    libcerror_error_set(
2503
0
     error,
2504
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2505
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2506
0
     "%s: invalid handle - missing IO handle.",
2507
0
     function );
2508
2509
0
    return( -1 );
2510
0
  }
2511
2.73k
  if( internal_handle->data_stream != NULL )
2512
0
  {
2513
0
    libcerror_error_set(
2514
0
     error,
2515
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2516
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2517
0
     "%s: invalid file - data stream value already set.",
2518
0
     function );
2519
2520
0
    return( -1 );
2521
0
  }
2522
2.73k
  if( libbfio_handle_get_size(
2523
2.73k
       file_io_handle,
2524
2.73k
       &file_size,
2525
2.73k
       error ) != 1 )
2526
0
  {
2527
0
    libcerror_error_set(
2528
0
     error,
2529
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2530
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2531
0
     "%s: unable to retrieve file size.",
2532
0
     function );
2533
2534
0
    goto on_error;
2535
0
  }
2536
2.73k
  if( ( internal_handle->io_handle->image_type == LIBMODI_IMAGE_TYPE_UNKNOWN )
2537
2.73k
   && ( file_size >= 512 ) )
2538
1.92k
  {
2539
1.92k
    if( libmodi_internal_handle_open_read_udif_image(
2540
1.92k
         internal_handle,
2541
1.92k
         file_io_handle,
2542
1.92k
         file_size,
2543
1.92k
         error ) != 1 )
2544
1.39k
    {
2545
1.39k
      libcerror_error_set(
2546
1.39k
       error,
2547
1.39k
       LIBCERROR_ERROR_DOMAIN_IO,
2548
1.39k
       LIBCERROR_IO_ERROR_READ_FAILED,
2549
1.39k
       "%s: unable to read UDIF image from file IO handle.",
2550
1.39k
       function );
2551
2552
1.39k
      goto on_error;
2553
1.39k
    }
2554
1.92k
  }
2555
1.34k
  if( ( internal_handle->io_handle->image_type == LIBMODI_IMAGE_TYPE_UNKNOWN )
2556
1.34k
   && ( file_size >= 4096 ) )
2557
339
  {
2558
339
    if( libmodi_internal_handle_open_read_sparse_image(
2559
339
         internal_handle,
2560
339
         file_io_handle,
2561
339
         error ) != 1 )
2562
135
    {
2563
135
      libcerror_error_set(
2564
135
       error,
2565
135
       LIBCERROR_ERROR_DOMAIN_IO,
2566
135
       LIBCERROR_IO_ERROR_READ_FAILED,
2567
135
       "%s: unable to read sparse image from file IO handle.",
2568
135
       function );
2569
2570
135
      goto on_error;
2571
135
    }
2572
339
  }
2573
1.20k
  if( ( internal_handle->io_handle->image_type == LIBMODI_IMAGE_TYPE_UNKNOWN )
2574
1.20k
   && ( file_size < MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
2575
1.09k
  {
2576
1.09k
    if( libmodi_internal_handle_open_read_sparse_bundle(
2577
1.09k
         internal_handle,
2578
1.09k
         file_io_handle,
2579
1.09k
         file_size,
2580
1.09k
         error ) != 1 )
2581
1.01k
    {
2582
1.01k
      libcerror_error_set(
2583
1.01k
       error,
2584
1.01k
       LIBCERROR_ERROR_DOMAIN_IO,
2585
1.01k
       LIBCERROR_IO_ERROR_READ_FAILED,
2586
1.01k
       "%s: unable to read sparse bundle from file IO handle.",
2587
1.01k
       function );
2588
2589
1.01k
      goto on_error;
2590
1.01k
    }
2591
1.09k
  }
2592
191
  if( internal_handle->io_handle->image_type == LIBMODI_IMAGE_TYPE_UNKNOWN )
2593
82
  {
2594
82
    if( libmodi_bands_data_handle_initialize(
2595
82
         &( internal_handle->bands_data_handle ),
2596
82
         internal_handle->io_handle,
2597
82
         error ) != 1 )
2598
0
    {
2599
0
      libcerror_error_set(
2600
0
       error,
2601
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2602
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2603
0
       "%s: unable to create bands data handle.",
2604
0
       function );
2605
2606
0
      goto on_error;
2607
0
    }
2608
82
    if( libmodi_bands_data_handle_append_segment(
2609
82
         internal_handle->bands_data_handle,
2610
82
         0,
2611
82
         0,
2612
82
         file_size,
2613
82
         0,
2614
82
         error ) != 1 )
2615
0
    {
2616
0
      libcerror_error_set(
2617
0
       error,
2618
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2619
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2620
0
       "%s: unable to append segment to bands data handle.",
2621
0
       function );
2622
2623
0
      goto on_error;
2624
0
    }
2625
82
    internal_handle->io_handle->image_type = LIBMODI_IMAGE_TYPE_RAW;
2626
82
    internal_handle->io_handle->media_size = file_size;
2627
82
  }
2628
191
  if( internal_handle->bands_data_handle != NULL )
2629
110
  {
2630
110
    result = libfdata_stream_initialize(
2631
110
              &( internal_handle->data_stream ),
2632
110
              (intptr_t *) internal_handle->bands_data_handle,
2633
110
              NULL,
2634
110
              NULL,
2635
110
              NULL,
2636
110
              (ssize_t (*)(intptr_t *, intptr_t *, int, int, uint8_t *, size_t, uint32_t, uint8_t, libcerror_error_t **)) &libmodi_bands_data_handle_read_segment_data,
2637
110
              NULL,
2638
110
              (off64_t (*)(intptr_t *, intptr_t *, int, int, off64_t, libcerror_error_t **)) &libmodi_bands_data_handle_seek_segment_offset,
2639
110
              LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
2640
110
              error );
2641
110
  }
2642
81
  else if( internal_handle->block_chunks_data_handle != NULL )
2643
81
  {
2644
81
    result = libfdata_stream_initialize(
2645
81
              &( internal_handle->data_stream ),
2646
81
              (intptr_t *) internal_handle->block_chunks_data_handle,
2647
81
              NULL,
2648
81
              NULL,
2649
81
              NULL,
2650
81
              (ssize_t (*)(intptr_t *, intptr_t *, int, int, uint8_t *, size_t, uint32_t, uint8_t, libcerror_error_t **)) &libmodi_block_chunks_data_handle_read_segment_data,
2651
81
              NULL,
2652
81
              (off64_t (*)(intptr_t *, intptr_t *, int, int, off64_t, libcerror_error_t **)) &libmodi_block_chunks_data_handle_seek_segment_offset,
2653
81
              LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
2654
81
              error );
2655
81
  }
2656
0
  else
2657
0
  {
2658
0
    result = libfdata_stream_initialize(
2659
0
              &( internal_handle->data_stream ),
2660
0
              NULL,
2661
0
              NULL,
2662
0
              NULL,
2663
0
              NULL,
2664
0
              NULL,
2665
0
              NULL,
2666
0
              NULL,
2667
0
              LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED,
2668
0
              error );
2669
0
  }
2670
191
  if( result != 1 )
2671
0
  {
2672
0
    libcerror_error_set(
2673
0
     error,
2674
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2675
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2676
0
     "%s: unable to create data stream.",
2677
0
     function );
2678
2679
0
    goto on_error;
2680
0
  }
2681
191
  if( internal_handle->block_chunks_data_handle != NULL )
2682
81
  {
2683
81
    if( libfdata_list_get_number_of_elements(
2684
81
         internal_handle->block_chunks_data_handle->block_chunks_list,
2685
81
         &number_of_block_chunks,
2686
81
         error ) != 1 )
2687
0
    {
2688
0
      libcerror_error_set(
2689
0
       error,
2690
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2691
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2692
0
       "%s: unable to retrieve number of block chunks.",
2693
0
       function );
2694
2695
0
      goto on_error;
2696
0
    }
2697
81
    for( block_chunk_index = 0;
2698
187
         block_chunk_index < number_of_block_chunks;
2699
106
         block_chunk_index++ )
2700
106
    {
2701
106
      if( libfdata_list_get_element_by_index_with_mapped_size(
2702
106
           internal_handle->block_chunks_data_handle->block_chunks_list,
2703
106
           block_chunk_index,
2704
106
           &element_file_index,
2705
106
           &element_offset,
2706
106
           &element_size,
2707
106
           &element_flags,
2708
106
           &mapped_size,
2709
106
           error ) != 1 )
2710
0
      {
2711
0
        libcerror_error_set(
2712
0
         error,
2713
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2714
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2715
0
         "%s: unable to retrieve block chunk: %d.",
2716
0
         function,
2717
0
         block_chunk_index );
2718
2719
0
        goto on_error;
2720
0
      }
2721
106
      if( libfdata_stream_append_segment(
2722
106
           internal_handle->data_stream,
2723
106
           &segment_index,
2724
106
           0,
2725
106
           mapped_offset,
2726
106
           mapped_size,
2727
106
           element_flags,
2728
106
           error ) != 1 )
2729
0
      {
2730
0
        libcerror_error_set(
2731
0
         error,
2732
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2733
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2734
0
         "%s: unable to append segment to data stream.",
2735
0
         function );
2736
2737
0
        goto on_error;
2738
0
      }
2739
106
      mapped_offset += mapped_size;
2740
106
    }
2741
81
  }
2742
110
  else
2743
110
  {
2744
110
    if( libfdata_stream_append_segment(
2745
110
         internal_handle->data_stream,
2746
110
         &segment_index,
2747
110
         0,
2748
110
         0,
2749
110
         internal_handle->io_handle->media_size,
2750
110
         0,
2751
110
         error ) != 1 )
2752
0
    {
2753
0
      libcerror_error_set(
2754
0
       error,
2755
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2756
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2757
0
       "%s: unable to append segment to data stream.",
2758
0
       function );
2759
2760
0
      goto on_error;
2761
0
    }
2762
110
  }
2763
191
  return( 1 );
2764
2765
2.54k
on_error:
2766
2.54k
  if( internal_handle->data_stream != NULL )
2767
0
  {
2768
0
    libfdata_stream_free(
2769
0
     &( internal_handle->data_stream ),
2770
0
     NULL );
2771
0
  }
2772
2.54k
  if( internal_handle->block_chunks_data_handle != NULL )
2773
0
  {
2774
0
    libmodi_block_chunks_data_handle_free(
2775
0
     &( internal_handle->block_chunks_data_handle ),
2776
0
     NULL );
2777
0
  }
2778
2.54k
  if( internal_handle->bands_data_handle != NULL )
2779
0
  {
2780
0
    libmodi_bands_data_handle_free(
2781
0
     &( internal_handle->bands_data_handle ),
2782
0
     NULL );
2783
0
  }
2784
2.54k
  return( -1 );
2785
191
}
2786
2787
/* Opens a handle of a sparse bundle for reading
2788
 * Returns 1 if successful or -1 on error
2789
 */
2790
int libmodi_internal_handle_open_read_sparse_bundle(
2791
     libmodi_internal_handle_t *internal_handle,
2792
     libbfio_handle_t *file_io_handle,
2793
     size64_t file_size,
2794
     libcerror_error_t **error )
2795
1.09k
{
2796
1.09k
  libmodi_sparse_bundle_xml_plist_t *sparse_bundle_xml_plist = NULL;
2797
1.09k
  static char *function                                      = "libmodi_internal_handle_open_read_sparse_bundle";
2798
1.09k
  int result                                                 = 0;
2799
2800
1.09k
  if( internal_handle == NULL )
2801
0
  {
2802
0
    libcerror_error_set(
2803
0
     error,
2804
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2805
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2806
0
     "%s: invalid handle.",
2807
0
     function );
2808
2809
0
    return( -1 );
2810
0
  }
2811
#if defined( HAVE_DEBUG_OUTPUT )
2812
  if( libcnotify_verbose != 0 )
2813
  {
2814
    libcnotify_printf(
2815
     "Reading info.plist:\n" );
2816
  }
2817
#endif
2818
1.09k
  if( libmodi_sparse_bundle_xml_plist_initialize(
2819
1.09k
       &sparse_bundle_xml_plist,
2820
1.09k
       error ) != 1 )
2821
0
  {
2822
0
    libcerror_error_set(
2823
0
     error,
2824
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2825
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2826
0
     "%s: unable to create sparse bundle XML plist",
2827
0
     function );
2828
2829
0
    goto on_error;
2830
0
  }
2831
1.09k
  result = libmodi_sparse_bundle_xml_plist_read_file_io_handle(
2832
1.09k
            sparse_bundle_xml_plist,
2833
1.09k
            file_io_handle,
2834
1.09k
            0,
2835
1.09k
            file_size,
2836
1.09k
            error );
2837
2838
1.09k
  if( result == -1 )
2839
1.01k
  {
2840
1.01k
    libcerror_error_set(
2841
1.01k
     error,
2842
1.01k
     LIBCERROR_ERROR_DOMAIN_IO,
2843
1.01k
     LIBCERROR_IO_ERROR_READ_FAILED,
2844
1.01k
     "%s: unable to read sparse bundle info.plist.",
2845
1.01k
     function );
2846
2847
1.01k
    goto on_error;
2848
1.01k
  }
2849
82
  else if( result != 0 )
2850
0
  {
2851
0
    if( libmodi_bands_data_handle_initialize(
2852
0
         &( internal_handle->bands_data_handle ),
2853
0
         internal_handle->io_handle,
2854
0
         error ) != 1 )
2855
0
    {
2856
0
      libcerror_error_set(
2857
0
       error,
2858
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2859
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2860
0
       "%s: unable to create data handle.",
2861
0
       function );
2862
2863
0
      goto on_error;
2864
0
    }
2865
0
    internal_handle->io_handle->image_type      = LIBMODI_IMAGE_TYPE_SPARSE_BUNDLE;
2866
0
    internal_handle->io_handle->band_data_size  = (size64_t) sparse_bundle_xml_plist->band_data_size;
2867
0
    internal_handle->io_handle->number_of_bands = (int) sparse_bundle_xml_plist->number_of_bands;
2868
0
    internal_handle->io_handle->media_size      = (size64_t) sparse_bundle_xml_plist->media_size;
2869
0
  }
2870
82
  if( libmodi_sparse_bundle_xml_plist_free(
2871
82
       &sparse_bundle_xml_plist,
2872
82
       error ) != 1 )
2873
0
  {
2874
0
    libcerror_error_set(
2875
0
     error,
2876
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2877
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2878
0
     "%s: unable to free sparse bundle XML plist",
2879
0
     function );
2880
2881
0
    goto on_error;
2882
0
  }
2883
82
  return( 1 );
2884
2885
1.01k
on_error:
2886
1.01k
  if( internal_handle->bands_data_handle != NULL )
2887
0
  {
2888
0
    libmodi_bands_data_handle_free(
2889
0
     &( internal_handle->bands_data_handle ),
2890
0
     NULL );
2891
0
  }
2892
1.01k
  if( sparse_bundle_xml_plist != NULL )
2893
1.01k
  {
2894
1.01k
    libmodi_sparse_bundle_xml_plist_free(
2895
1.01k
     &sparse_bundle_xml_plist,
2896
1.01k
     NULL );
2897
1.01k
  }
2898
1.01k
  return( -1 );
2899
82
}
2900
2901
/* Opens a handle of a sparse image for reading
2902
 * Returns 1 if successful or -1 on error
2903
 */
2904
int libmodi_internal_handle_open_read_sparse_image(
2905
     libmodi_internal_handle_t *internal_handle,
2906
     libbfio_handle_t *file_io_handle,
2907
     libcerror_error_t **error )
2908
339
{
2909
339
  libmodi_sparse_image_header_t *sparse_image_header = NULL;
2910
339
  static char *function                              = "libmodi_internal_handle_open_read_sparse_image";
2911
339
  size64_t band_data_size                            = 0;
2912
339
  off64_t band_data_offset                           = 0;
2913
339
  uint32_t band_data_range_flags                     = 0;
2914
339
  uint32_t band_reference                            = 0;
2915
339
  uint32_t band_reference_index                      = 0;
2916
339
  int result                                         = 0;
2917
2918
339
  if( internal_handle == NULL )
2919
0
  {
2920
0
    libcerror_error_set(
2921
0
     error,
2922
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2923
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2924
0
     "%s: invalid handle.",
2925
0
     function );
2926
2927
0
    return( -1 );
2928
0
  }
2929
#if defined( HAVE_DEBUG_OUTPUT )
2930
  if( libcnotify_verbose != 0 )
2931
  {
2932
    libcnotify_printf(
2933
     "Reading sparse image header:\n" );
2934
  }
2935
#endif
2936
339
  if( libmodi_sparse_image_header_initialize(
2937
339
       &sparse_image_header,
2938
339
       error ) != 1 )
2939
0
  {
2940
0
    libcerror_error_set(
2941
0
     error,
2942
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2943
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2944
0
     "%s: unable to create sparse image header.",
2945
0
     function );
2946
2947
0
    goto on_error;
2948
0
  }
2949
339
  result = libmodi_sparse_image_header_read_file_io_handle(
2950
339
            sparse_image_header,
2951
339
            file_io_handle,
2952
339
            0,
2953
339
            error );
2954
2955
339
  if( result == -1 )
2956
135
  {
2957
135
    libcerror_error_set(
2958
135
     error,
2959
135
     LIBCERROR_ERROR_DOMAIN_IO,
2960
135
     LIBCERROR_IO_ERROR_READ_FAILED,
2961
135
     "%s: unable to read sparse image header at offset: 0 (0x00000000).",
2962
135
     function );
2963
2964
135
    goto on_error;
2965
135
  }
2966
204
  else if( result != 0 )
2967
28
  {
2968
28
    if( libmodi_bands_data_handle_initialize(
2969
28
         &( internal_handle->bands_data_handle ),
2970
28
         internal_handle->io_handle,
2971
28
         error ) != 1 )
2972
0
    {
2973
0
      libcerror_error_set(
2974
0
       error,
2975
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2976
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2977
0
       "%s: unable to create data handle.",
2978
0
       function );
2979
2980
0
      goto on_error;
2981
0
    }
2982
28
    band_data_size = (size64_t) sparse_image_header->sectors_per_band * 512;
2983
2984
28
    for( band_reference_index = 0;
2985
3.12k
         band_reference_index < sparse_image_header->number_of_bands;
2986
3.09k
         band_reference_index++ )
2987
3.09k
    {
2988
3.09k
      band_reference = sparse_image_header->band_references[ band_reference_index ];
2989
2990
#if defined( HAVE_DEBUG_OUTPUT )
2991
      if( libcnotify_verbose != 0 )
2992
      {
2993
        libcnotify_printf(
2994
         "%s: band reference: %03" PRIu32 "\t\t: 0x%08" PRIx32 "",
2995
         function,
2996
         band_reference_index,
2997
         band_reference );
2998
2999
        if( band_reference == 0xffffffffUL )
3000
        {
3001
          libcnotify_printf(
3002
           " (sparse)\n" );
3003
        }
3004
        else
3005
        {
3006
          libcnotify_printf(
3007
           " (data offset: 0x%08" PRIx64 ")\n",
3008
           4096 + ( band_reference * band_data_size ) );
3009
        }
3010
      }
3011
#endif
3012
3.09k
      if( band_reference == 0xffffffffUL )
3013
2.99k
      {
3014
2.99k
        band_data_offset      = 0;
3015
2.99k
        band_data_range_flags = LIBFDATA_RANGE_FLAG_IS_SPARSE;
3016
2.99k
      }
3017
98
      else
3018
98
      {
3019
98
        band_data_offset      = 4096 + ( band_reference * band_data_size );
3020
98
        band_data_range_flags = 0;
3021
98
      }
3022
3.09k
      if( libmodi_bands_data_handle_append_segment(
3023
3.09k
           internal_handle->bands_data_handle,
3024
3.09k
           0,
3025
3.09k
           band_data_offset,
3026
3.09k
           band_data_size,
3027
3.09k
           band_data_range_flags,
3028
3.09k
           error ) != 1 )
3029
0
      {
3030
0
        libcerror_error_set(
3031
0
         error,
3032
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3033
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
3034
0
         "%s: unable to append band reference: %" PRIu32 " as segment to bands data handle.",
3035
0
         function,
3036
0
         band_reference_index );
3037
3038
0
        goto on_error;
3039
0
      }
3040
3.09k
    }
3041
#if defined( HAVE_DEBUG_OUTPUT )
3042
    if( libcnotify_verbose != 0 )
3043
    {
3044
      libcnotify_printf(
3045
       "\n" );
3046
    }
3047
#endif
3048
28
    internal_handle->io_handle->image_type = LIBMODI_IMAGE_TYPE_SPARSE_IMAGE;
3049
28
    internal_handle->io_handle->media_size = (size64_t) sparse_image_header->number_of_sectors * 512;
3050
28
  }
3051
204
  if( libmodi_sparse_image_header_free(
3052
204
       &sparse_image_header,
3053
204
       error ) != 1 )
3054
0
  {
3055
0
    libcerror_error_set(
3056
0
     error,
3057
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3058
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3059
0
     "%s: unable to free sparse image header.",
3060
0
     function );
3061
3062
0
    goto on_error;
3063
0
  }
3064
204
  return( 1 );
3065
3066
135
on_error:
3067
135
  if( internal_handle->bands_data_handle != NULL )
3068
0
  {
3069
0
    libmodi_bands_data_handle_free(
3070
0
     &( internal_handle->bands_data_handle ),
3071
0
     NULL );
3072
0
  }
3073
135
  if( sparse_image_header != NULL )
3074
135
  {
3075
135
    libmodi_sparse_image_header_free(
3076
135
     &sparse_image_header,
3077
135
     NULL );
3078
135
  }
3079
135
  return( -1 );
3080
204
}
3081
3082
/* Opens a handle of an UDIF image for reading
3083
 * Returns 1 if successful or -1 on error
3084
 */
3085
int libmodi_internal_handle_open_read_udif_image(
3086
     libmodi_internal_handle_t *internal_handle,
3087
     libbfio_handle_t *file_io_handle,
3088
     size64_t file_size,
3089
     libcerror_error_t **error )
3090
1.92k
{
3091
1.92k
  libmodi_udif_block_table_t *block_table             = NULL;
3092
1.92k
  libmodi_udif_block_table_entry_t *block_table_entry = NULL;
3093
1.92k
  libmodi_udif_resource_file_t *udif_resource_file    = NULL;
3094
1.92k
  libmodi_udif_xml_plist_t *udif_xml_plist            = NULL;
3095
1.92k
  static char *function                               = "libmodi_internal_handle_open_read_udif_image";
3096
1.92k
  uint64_t last_block_entry_sector                    = 0;
3097
1.92k
  uint32_t compressed_entry_type                      = 0;
3098
1.92k
  uint32_t segment_flags                              = 0;
3099
1.92k
  int block_table_entry_index                         = 0;
3100
1.92k
  int block_table_index                               = 0;
3101
1.92k
  int number_of_block_table_entries                   = 0;
3102
1.92k
  int number_of_block_tables                          = 0;
3103
1.92k
  int result                                          = 0;
3104
3105
1.92k
  if( internal_handle == NULL )
3106
0
  {
3107
0
    libcerror_error_set(
3108
0
     error,
3109
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3110
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3111
0
     "%s: invalid handle.",
3112
0
     function );
3113
3114
0
    return( -1 );
3115
0
  }
3116
1.92k
  if( internal_handle->block_chunks_data_handle != NULL )
3117
0
  {
3118
0
    libcerror_error_set(
3119
0
     error,
3120
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3121
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3122
0
     "%s: invalid handle - block chunks data handle already exists.",
3123
0
     function );
3124
3125
0
    return( -1 );
3126
0
  }
3127
#if defined( HAVE_DEBUG_OUTPUT )
3128
  if( libcnotify_verbose != 0 )
3129
  {
3130
    libcnotify_printf(
3131
     "Reading Universal Disk Image Format (UDIF) resource file:\n" );
3132
  }
3133
#endif
3134
1.92k
  if( libmodi_udif_resource_file_initialize(
3135
1.92k
       &udif_resource_file,
3136
1.92k
       error ) != 1 )
3137
0
  {
3138
0
    libcerror_error_set(
3139
0
     error,
3140
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3141
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3142
0
     "%s: unable to create UDIF resource file.",
3143
0
     function );
3144
3145
0
    goto on_error;
3146
0
  }
3147
1.92k
  result = libmodi_udif_resource_file_read_file_io_handle(
3148
1.92k
            udif_resource_file,
3149
1.92k
            file_io_handle,
3150
1.92k
            file_size - 512,
3151
1.92k
            error );
3152
3153
1.92k
  if( result == -1 )
3154
43
  {
3155
43
    libcerror_error_set(
3156
43
     error,
3157
43
     LIBCERROR_ERROR_DOMAIN_IO,
3158
43
     LIBCERROR_IO_ERROR_READ_FAILED,
3159
43
     "%s: unable to read UDIF resource file at offset: %" PRIi64 " (0x%08" PRIx64 ").",
3160
43
     function,
3161
43
     file_size - 512,
3162
43
     file_size - 512 );
3163
3164
43
    goto on_error;
3165
43
  }
3166
1.88k
  else if( result != 0 )
3167
1.42k
  {
3168
1.42k
    if( libmodi_block_chunks_data_handle_initialize(
3169
1.42k
         &( internal_handle->block_chunks_data_handle ),
3170
1.42k
         internal_handle->io_handle,
3171
1.42k
         error ) != 1 )
3172
0
    {
3173
0
      libcerror_error_set(
3174
0
       error,
3175
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3176
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3177
0
       "%s: unable to create block chunks data handle.",
3178
0
       function );
3179
3180
0
      goto on_error;
3181
0
    }
3182
1.42k
    if( udif_resource_file->xml_plist_size == 0 )
3183
2
    {
3184
2
      internal_handle->io_handle->media_size = udif_resource_file->data_fork_size;
3185
2
    }
3186
1.42k
    else
3187
1.42k
    {
3188
#if defined( HAVE_DEBUG_OUTPUT )
3189
      if( libcnotify_verbose != 0 )
3190
      {
3191
        libcnotify_printf(
3192
         "Reading Universal Disk Image Format (UDIF) XML plist:\n" );
3193
      }
3194
#endif
3195
1.42k
      if( libmodi_udif_xml_plist_initialize(
3196
1.42k
           &udif_xml_plist,
3197
1.42k
           error ) != 1 )
3198
0
      {
3199
0
        libcerror_error_set(
3200
0
         error,
3201
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3202
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3203
0
         "%s: unable to create UDIF XML plist.",
3204
0
         function );
3205
3206
0
        goto on_error;
3207
0
      }
3208
1.42k
      result = libmodi_udif_xml_plist_read_file_io_handle(
3209
1.42k
          udif_xml_plist,
3210
1.42k
          file_io_handle,
3211
1.42k
          udif_resource_file->xml_plist_offset,
3212
1.42k
          udif_resource_file->xml_plist_size,
3213
1.42k
          error );
3214
3215
1.42k
      if( result == -1 )
3216
1.04k
      {
3217
1.04k
        libcerror_error_set(
3218
1.04k
         error,
3219
1.04k
         LIBCERROR_ERROR_DOMAIN_IO,
3220
1.04k
         LIBCERROR_IO_ERROR_READ_FAILED,
3221
1.04k
         "%s: unable to read UDIF XML plist at offset: %" PRIi64 " (0x%08" PRIx64 ").",
3222
1.04k
         function,
3223
1.04k
         udif_resource_file->xml_plist_offset,
3224
1.04k
         udif_resource_file->xml_plist_offset );
3225
3226
1.04k
        goto on_error;
3227
1.04k
      }
3228
383
      internal_handle->io_handle->media_size = 0;
3229
3230
383
      if( libmodi_udif_xml_plist_get_number_of_block_tables(
3231
383
           udif_xml_plist,
3232
383
           &number_of_block_tables,
3233
383
           error ) != 1 )
3234
0
      {
3235
0
        libcerror_error_set(
3236
0
         error,
3237
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3238
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3239
0
         "%s: unable to retrieve number of block tables in UDIF XML plist.",
3240
0
         function );
3241
3242
0
        goto on_error;
3243
0
      }
3244
383
      for( block_table_index = 0;
3245
941
           block_table_index < number_of_block_tables;
3246
558
           block_table_index++ )
3247
862
      {
3248
862
        if( libmodi_udif_xml_plist_get_block_table_by_index(
3249
862
             udif_xml_plist,
3250
862
             block_table_index,
3251
862
             &block_table,
3252
862
             error ) != 1 )
3253
0
        {
3254
0
          libcerror_error_set(
3255
0
           error,
3256
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
3257
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3258
0
           "%s: unable to retrieve block table: %d from UDIF XML plist.",
3259
0
           function,
3260
0
           block_table_index );
3261
3262
0
          goto on_error;
3263
0
        }
3264
862
        if( block_table->start_sector != last_block_entry_sector )
3265
117
        {
3266
117
          libcerror_error_set(
3267
117
           error,
3268
117
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
3269
117
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3270
117
           "%s: unsupported block table: %d start sector value out of bounds.",
3271
117
           function,
3272
117
           block_table_index );
3273
3274
117
          goto on_error;
3275
117
        }
3276
745
        if( libmodi_udif_block_table_get_number_of_entries(
3277
745
             block_table,
3278
745
             &number_of_block_table_entries,
3279
745
             error ) != 1 )
3280
0
        {
3281
0
          libcerror_error_set(
3282
0
           error,
3283
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
3284
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3285
0
           "%s: unable to retrieve number of entries in block table: %d.",
3286
0
           function,
3287
0
           block_table_index );
3288
3289
0
          goto on_error;
3290
0
        }
3291
745
        for( block_table_entry_index = 0;
3292
1.24k
             block_table_entry_index < number_of_block_table_entries;
3293
745
             block_table_entry_index++ )
3294
685
        {
3295
685
          if( libmodi_udif_block_table_get_entry_by_index(
3296
685
               block_table,
3297
685
               block_table_entry_index,
3298
685
               &block_table_entry,
3299
685
               error ) != 1 )
3300
0
          {
3301
0
            libcerror_error_set(
3302
0
             error,
3303
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
3304
0
             LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3305
0
             "%s: unable to retrieve entry: %d from block table: %d.",
3306
0
             function,
3307
0
             block_table_entry_index,
3308
0
             block_table_index );
3309
3310
0
            goto on_error;
3311
0
          }
3312
685
          if( block_table_entry->type == 0x7ffffffeUL )
3313
1
          {
3314
1
            continue;
3315
1
          }
3316
684
          if( block_table_entry->type == 0xffffffffUL )
3317
0
          {
3318
0
            break;
3319
0
          }
3320
684
          if( ( block_table_entry->number_of_sectors == 0 )
3321
684
           || ( block_table_entry->number_of_sectors > ( (uint64_t) INT64_MAX / 512 ) ) )
3322
0
          {
3323
0
            libcerror_error_set(
3324
0
             error,
3325
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
3326
0
             LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3327
0
             "%s: unsupported block table: %d entry: %d number of sectors value out of bounds.",
3328
0
             function,
3329
0
             block_table_index,
3330
0
             block_table_entry_index );
3331
3332
0
            goto on_error;
3333
0
          }
3334
684
          if( block_table_entry->data_offset > (off64_t) INT64_MAX )
3335
36
          {
3336
36
            libcerror_error_set(
3337
36
             error,
3338
36
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
3339
36
             LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3340
36
             "%s: unsupported block table: %d entry: %d data offset value out of bounds.",
3341
36
             function,
3342
36
             block_table_index,
3343
36
             block_table_entry_index );
3344
3345
36
            goto on_error;
3346
36
          }
3347
648
          if( ( block_table_entry->type == LIBMODI_UDIF_BLOCK_TABLE_ENTRY_TYPE_ADC_COMPRESSED )
3348
648
           || ( block_table_entry->type == LIBMODI_UDIF_BLOCK_TABLE_ENTRY_TYPE_ZLIB_COMPRESSED )
3349
648
           || ( block_table_entry->type == LIBMODI_UDIF_BLOCK_TABLE_ENTRY_TYPE_BZIP2_COMPRESSED )
3350
648
           || ( block_table_entry->type == LIBMODI_UDIF_BLOCK_TABLE_ENTRY_TYPE_LZFSE_COMPRESSED )
3351
648
           || ( block_table_entry->type == LIBMODI_UDIF_BLOCK_TABLE_ENTRY_TYPE_LZMA_COMPRESSED ) )
3352
422
          {
3353
422
            if( block_table_entry->number_of_sectors > 2048 )
3354
0
            {
3355
0
              libcerror_error_set(
3356
0
               error,
3357
0
               LIBCERROR_ERROR_DOMAIN_RUNTIME,
3358
0
               LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3359
0
               "%s: unsupported compressed block table: %d entry: %d number of sectors value out of bounds.",
3360
0
               function,
3361
0
               block_table_index,
3362
0
               block_table_entry_index );
3363
3364
0
              goto on_error;
3365
0
            }
3366
422
            if( compressed_entry_type == 0 )
3367
187
            {
3368
187
              compressed_entry_type = block_table_entry->type;
3369
187
            }
3370
235
            else if( compressed_entry_type != block_table_entry->type )
3371
3
            {
3372
3
              libcerror_error_set(
3373
3
               error,
3374
3
               LIBCERROR_ERROR_DOMAIN_RUNTIME,
3375
3
               LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3376
3
               "%s: mixed compressed block table entry types not supported.",
3377
3
               function );
3378
3379
3
              goto on_error;
3380
3
            }
3381
419
            segment_flags = LIBFDATA_RANGE_FLAG_IS_COMPRESSED;
3382
419
          }
3383
226
          else if( ( block_table_entry->type == 0x00000000UL )
3384
226
                || ( block_table_entry->type == 0x00000002UL ) )
3385
108
          {
3386
108
            segment_flags = LIBFDATA_RANGE_FLAG_IS_SPARSE;
3387
108
          }
3388
118
          else if( block_table_entry->type == 0x00000001UL )
3389
15
          {
3390
15
            segment_flags = 0;
3391
15
          }
3392
103
          else
3393
103
          {
3394
103
            libcerror_error_set(
3395
103
             error,
3396
103
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
3397
103
             LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3398
103
             "%s: unsupported block table: %d entry: %d type.",
3399
103
             function,
3400
103
             block_table_index,
3401
103
             block_table_entry_index );
3402
3403
103
            goto on_error;
3404
103
          }
3405
542
          if( ( block_table_entry->start_sector > ( ( (uint64_t) INT64_MAX / 512 ) - block_table->start_sector ) )
3406
542
           || ( ( block_table->start_sector + block_table_entry->start_sector ) != last_block_entry_sector ) )
3407
1
          {
3408
1
            libcerror_error_set(
3409
1
             error,
3410
1
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
3411
1
             LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3412
1
             "%s: unsupported block table: %d entry: %d start sector value out of bounds.",
3413
1
             function,
3414
1
             block_table_index,
3415
1
             block_table_entry_index );
3416
3417
1
            goto on_error;
3418
1
          }
3419
541
          if( libmodi_block_chunks_data_handle_append_segment(
3420
541
               internal_handle->block_chunks_data_handle,
3421
541
               0,
3422
541
               block_table_entry->data_offset,
3423
541
               block_table_entry->data_size,
3424
541
               segment_flags,
3425
541
               block_table_entry->number_of_sectors * 512,
3426
541
               error ) != 1 )
3427
44
          {
3428
44
            libcerror_error_set(
3429
44
             error,
3430
44
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
3431
44
             LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
3432
44
             "%s: unable to append block table: %d entry: %d as segment to block chunks data handle.",
3433
44
             function,
3434
44
             block_table_index,
3435
44
             block_table_entry_index );
3436
3437
44
            goto on_error;
3438
44
          }
3439
497
          last_block_entry_sector += block_table_entry->number_of_sectors;
3440
497
        }
3441
745
      }
3442
79
      internal_handle->io_handle->media_size = last_block_entry_sector * 512;
3443
3444
79
      if( libmodi_udif_xml_plist_free(
3445
79
           &udif_xml_plist,
3446
79
           error ) != 1 )
3447
0
      {
3448
0
        libcerror_error_set(
3449
0
         error,
3450
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3451
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3452
0
         "%s: unable to free UDIF XML plist.",
3453
0
         function );
3454
3455
0
        goto on_error;
3456
0
      }
3457
79
    }
3458
81
    if( compressed_entry_type == 0 )
3459
46
    {
3460
46
      internal_handle->io_handle->image_type = LIBMODI_IMAGE_TYPE_UDIF_UNCOMPRESSED;
3461
46
    }
3462
35
    else
3463
35
    {
3464
35
      switch( compressed_entry_type )
3465
35
      {
3466
11
        case LIBMODI_UDIF_BLOCK_TABLE_ENTRY_TYPE_ADC_COMPRESSED:
3467
11
          internal_handle->io_handle->compression_method = LIBMODI_COMPRESSION_METHOD_ADC;
3468
11
          break;
3469
3470
10
        case LIBMODI_UDIF_BLOCK_TABLE_ENTRY_TYPE_ZLIB_COMPRESSED:
3471
10
          internal_handle->io_handle->compression_method = LIBMODI_COMPRESSION_METHOD_DEFLATE;
3472
10
          break;
3473
3474
5
        case LIBMODI_UDIF_BLOCK_TABLE_ENTRY_TYPE_BZIP2_COMPRESSED:
3475
5
          internal_handle->io_handle->compression_method = LIBMODI_COMPRESSION_METHOD_BZIP2;
3476
5
          break;
3477
3478
5
        case LIBMODI_UDIF_BLOCK_TABLE_ENTRY_TYPE_LZFSE_COMPRESSED:
3479
5
          internal_handle->io_handle->compression_method = LIBMODI_COMPRESSION_METHOD_LZFSE;
3480
5
          break;
3481
3482
4
        case LIBMODI_UDIF_BLOCK_TABLE_ENTRY_TYPE_LZMA_COMPRESSED:
3483
4
          internal_handle->io_handle->compression_method = LIBMODI_COMPRESSION_METHOD_LZMA;
3484
4
          break;
3485
35
      }
3486
35
      internal_handle->io_handle->image_type = LIBMODI_IMAGE_TYPE_UDIF_COMPRESSED;
3487
35
    }
3488
81
  }
3489
536
  if( libmodi_udif_resource_file_free(
3490
536
       &udif_resource_file,
3491
536
       error ) != 1 )
3492
0
  {
3493
0
    libcerror_error_set(
3494
0
     error,
3495
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3496
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3497
0
     "%s: unable to free UDIF resource file.",
3498
0
     function );
3499
3500
0
    goto on_error;
3501
0
  }
3502
536
  return( 1 );
3503
3504
1.39k
on_error:
3505
1.39k
  if( udif_xml_plist != NULL )
3506
1.34k
  {
3507
1.34k
    libmodi_udif_xml_plist_free(
3508
1.34k
     &udif_xml_plist,
3509
1.34k
     NULL );
3510
1.34k
  }
3511
1.39k
  if( internal_handle->block_chunks_data_handle != NULL )
3512
1.34k
  {
3513
1.34k
    libmodi_block_chunks_data_handle_free(
3514
1.34k
     &( internal_handle->block_chunks_data_handle ),
3515
1.34k
     NULL );
3516
1.34k
  }
3517
1.39k
  if( udif_resource_file != NULL )
3518
1.39k
  {
3519
1.39k
    libmodi_udif_resource_file_free(
3520
1.39k
     &udif_resource_file,
3521
1.39k
     NULL );
3522
1.39k
  }
3523
1.39k
  return( -1 );
3524
536
}
3525
3526
/* Reads (media) data from the current offset into a buffer
3527
 * Returns the number of bytes read or -1 on error
3528
 */
3529
ssize_t libmodi_handle_read_buffer(
3530
         libmodi_handle_t *handle,
3531
         void *buffer,
3532
         size_t buffer_size,
3533
         libcerror_error_t **error )
3534
0
{
3535
0
  libmodi_internal_handle_t *internal_handle = NULL;
3536
0
  intptr_t *file_io_handle                   = NULL;
3537
0
  static char *function                      = "libmodi_handle_read_buffer";
3538
0
  ssize_t read_count                         = 0;
3539
3540
0
  if( handle == NULL )
3541
0
  {
3542
0
    libcerror_error_set(
3543
0
     error,
3544
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3545
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3546
0
     "%s: invalid handle.",
3547
0
     function );
3548
3549
0
    return( -1 );
3550
0
  }
3551
0
  internal_handle = (libmodi_internal_handle_t *) handle;
3552
3553
0
  if( internal_handle->io_handle == NULL )
3554
0
  {
3555
0
    libcerror_error_set(
3556
0
     error,
3557
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3558
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3559
0
     "%s: invalid handle - missing IO handle.",
3560
0
     function );
3561
3562
0
    return( -1 );
3563
0
  }
3564
0
  if( internal_handle->file_io_handle == NULL )
3565
0
  {
3566
0
    libcerror_error_set(
3567
0
     error,
3568
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3569
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3570
0
     "%s: invalid handle - missing file IO handle.",
3571
0
     function );
3572
3573
0
    return( -1 );
3574
0
  }
3575
0
  if( ( internal_handle->io_handle->image_type == LIBMODI_IMAGE_TYPE_SPARSE_BUNDLE )
3576
0
   && ( internal_handle->band_data_file_io_pool == NULL ) )
3577
0
  {
3578
0
    libcerror_error_set(
3579
0
     error,
3580
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3581
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3582
0
     "%s: invalid handle - missing band data file IO pool.",
3583
0
     function );
3584
3585
0
    return( -1 );
3586
0
  }
3587
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
3588
0
  if( libcthreads_read_write_lock_grab_for_write(
3589
0
       internal_handle->read_write_lock,
3590
0
       error ) != 1 )
3591
0
  {
3592
0
    libcerror_error_set(
3593
0
     error,
3594
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3595
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3596
0
     "%s: unable to grab read/write lock for writing.",
3597
0
     function );
3598
3599
0
    return( -1 );
3600
0
  }
3601
0
#endif
3602
0
  if( internal_handle->io_handle->image_type == LIBMODI_IMAGE_TYPE_SPARSE_BUNDLE )
3603
0
  {
3604
0
    file_io_handle = (intptr_t *) internal_handle->band_data_file_io_pool;
3605
0
  }
3606
0
  else
3607
0
  {
3608
0
    file_io_handle = (intptr_t *) internal_handle->file_io_handle;
3609
0
  }
3610
0
  read_count = libfdata_stream_read_buffer(
3611
0
          internal_handle->data_stream,
3612
0
          file_io_handle,
3613
0
          buffer,
3614
0
          buffer_size,
3615
0
          0,
3616
0
          error );
3617
3618
0
  if( read_count == -1 )
3619
0
  {
3620
0
    libcerror_error_set(
3621
0
     error,
3622
0
     LIBCERROR_ERROR_DOMAIN_IO,
3623
0
     LIBCERROR_IO_ERROR_READ_FAILED,
3624
0
     "%s: unable to read buffer.",
3625
0
     function );
3626
3627
0
    read_count = -1;
3628
0
  }
3629
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
3630
0
  if( libcthreads_read_write_lock_release_for_write(
3631
0
       internal_handle->read_write_lock,
3632
0
       error ) != 1 )
3633
0
  {
3634
0
    libcerror_error_set(
3635
0
     error,
3636
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3637
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3638
0
     "%s: unable to release read/write lock for writing.",
3639
0
     function );
3640
3641
0
    return( -1 );
3642
0
  }
3643
0
#endif
3644
0
  return( read_count );
3645
0
}
3646
3647
/* Reads (media) data at a specific offset
3648
 * Returns the number of bytes read or -1 on error
3649
 */
3650
ssize_t libmodi_handle_read_buffer_at_offset(
3651
         libmodi_handle_t *handle,
3652
         void *buffer,
3653
         size_t buffer_size,
3654
         off64_t offset,
3655
         libcerror_error_t **error )
3656
0
{
3657
0
  libmodi_internal_handle_t *internal_handle = NULL;
3658
0
  intptr_t *file_io_handle                   = NULL;
3659
0
  static char *function                      = "libmodi_handle_read_buffer_at_offset";
3660
0
  ssize_t read_count                         = 0;
3661
3662
0
  if( handle == NULL )
3663
0
  {
3664
0
    libcerror_error_set(
3665
0
     error,
3666
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3667
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3668
0
     "%s: invalid handle.",
3669
0
     function );
3670
3671
0
    return( -1 );
3672
0
  }
3673
0
  internal_handle = (libmodi_internal_handle_t *) handle;
3674
3675
0
  if( internal_handle->io_handle == NULL )
3676
0
  {
3677
0
    libcerror_error_set(
3678
0
     error,
3679
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3680
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3681
0
     "%s: invalid handle - missing IO handle.",
3682
0
     function );
3683
3684
0
    return( -1 );
3685
0
  }
3686
0
  if( internal_handle->file_io_handle == NULL )
3687
0
  {
3688
0
    libcerror_error_set(
3689
0
     error,
3690
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3691
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3692
0
     "%s: invalid handle - missing file IO handle.",
3693
0
     function );
3694
3695
0
    return( -1 );
3696
0
  }
3697
0
  if( ( internal_handle->io_handle->image_type == LIBMODI_IMAGE_TYPE_SPARSE_BUNDLE )
3698
0
   && ( internal_handle->band_data_file_io_pool == NULL ) )
3699
0
  {
3700
0
    libcerror_error_set(
3701
0
     error,
3702
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3703
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3704
0
     "%s: invalid handle - missing band data file IO pool.",
3705
0
     function );
3706
3707
0
    return( -1 );
3708
0
  }
3709
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
3710
0
  if( libcthreads_read_write_lock_grab_for_write(
3711
0
       internal_handle->read_write_lock,
3712
0
       error ) != 1 )
3713
0
  {
3714
0
    libcerror_error_set(
3715
0
     error,
3716
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3717
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3718
0
     "%s: unable to grab read/write lock for writing.",
3719
0
     function );
3720
3721
0
    return( -1 );
3722
0
  }
3723
0
#endif
3724
0
  if( internal_handle->io_handle->image_type == LIBMODI_IMAGE_TYPE_SPARSE_BUNDLE )
3725
0
  {
3726
0
    file_io_handle = (intptr_t *) internal_handle->band_data_file_io_pool;
3727
0
  }
3728
0
  else
3729
0
  {
3730
0
    file_io_handle = (intptr_t *) internal_handle->file_io_handle;
3731
0
  }
3732
0
  read_count = libfdata_stream_read_buffer_at_offset(
3733
0
          internal_handle->data_stream,
3734
0
          file_io_handle,
3735
0
          buffer,
3736
0
          buffer_size,
3737
0
          offset,
3738
0
          0,
3739
0
          error );
3740
3741
0
  if( read_count == -1 )
3742
0
  {
3743
0
    libcerror_error_set(
3744
0
     error,
3745
0
     LIBCERROR_ERROR_DOMAIN_IO,
3746
0
     LIBCERROR_IO_ERROR_READ_FAILED,
3747
0
     "%s: unable to read buffer.",
3748
0
     function );
3749
3750
0
    goto on_error;
3751
0
  }
3752
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
3753
0
  if( libcthreads_read_write_lock_release_for_write(
3754
0
       internal_handle->read_write_lock,
3755
0
       error ) != 1 )
3756
0
  {
3757
0
    libcerror_error_set(
3758
0
     error,
3759
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3760
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3761
0
     "%s: unable to release read/write lock for writing.",
3762
0
     function );
3763
3764
0
    return( -1 );
3765
0
  }
3766
0
#endif
3767
0
  return( read_count );
3768
3769
0
on_error:
3770
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
3771
0
  libcthreads_read_write_lock_release_for_write(
3772
0
   internal_handle->read_write_lock,
3773
0
   NULL );
3774
0
#endif
3775
0
  return( -1 );
3776
0
}
3777
3778
/* Seeks a certain offset of the (media) data
3779
 * Returns the offset if seek is successful or -1 on error
3780
 */
3781
off64_t libmodi_handle_seek_offset(
3782
         libmodi_handle_t *handle,
3783
         off64_t offset,
3784
         int whence,
3785
         libcerror_error_t **error )
3786
0
{
3787
0
  libmodi_internal_handle_t *internal_handle = NULL;
3788
0
  static char *function                      = "libmodi_handle_seek_offset";
3789
3790
0
  if( handle == NULL )
3791
0
  {
3792
0
    libcerror_error_set(
3793
0
     error,
3794
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3795
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3796
0
     "%s: invalid handle.",
3797
0
     function );
3798
3799
0
    return( -1 );
3800
0
  }
3801
0
  internal_handle = (libmodi_internal_handle_t *) handle;
3802
3803
0
  if( internal_handle->file_io_handle == NULL )
3804
0
  {
3805
0
    libcerror_error_set(
3806
0
     error,
3807
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3808
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3809
0
     "%s: invalid handle - missing file IO handle.",
3810
0
     function );
3811
3812
0
    return( -1 );
3813
0
  }
3814
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
3815
0
  if( libcthreads_read_write_lock_grab_for_write(
3816
0
       internal_handle->read_write_lock,
3817
0
       error ) != 1 )
3818
0
  {
3819
0
    libcerror_error_set(
3820
0
     error,
3821
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3822
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3823
0
     "%s: unable to grab read/write lock for writing.",
3824
0
     function );
3825
3826
0
    return( -1 );
3827
0
  }
3828
0
#endif
3829
0
  offset = libfdata_stream_seek_offset(
3830
0
            internal_handle->data_stream,
3831
0
            offset,
3832
0
            whence,
3833
0
            error );
3834
3835
0
  if( offset == -1 )
3836
0
  {
3837
0
    libcerror_error_set(
3838
0
     error,
3839
0
     LIBCERROR_ERROR_DOMAIN_IO,
3840
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
3841
0
     "%s: unable to seek offset.",
3842
0
     function );
3843
3844
0
    offset = -1;
3845
0
  }
3846
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
3847
0
  if( libcthreads_read_write_lock_release_for_write(
3848
0
       internal_handle->read_write_lock,
3849
0
       error ) != 1 )
3850
0
  {
3851
0
    libcerror_error_set(
3852
0
     error,
3853
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3854
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3855
0
     "%s: unable to release read/write lock for writing.",
3856
0
     function );
3857
3858
0
    return( -1 );
3859
0
  }
3860
0
#endif
3861
0
  return( offset );
3862
0
}
3863
3864
/* Retrieves the current offset of the (media) data
3865
 * Returns 1 if successful or -1 on error
3866
 */
3867
int libmodi_handle_get_offset(
3868
     libmodi_handle_t *handle,
3869
     off64_t *offset,
3870
     libcerror_error_t **error )
3871
0
{
3872
0
  libmodi_internal_handle_t *internal_handle = NULL;
3873
0
  static char *function                      = "libmodi_handle_get_offset";
3874
0
  int result                                 = 1;
3875
3876
0
  if( handle == NULL )
3877
0
  {
3878
0
    libcerror_error_set(
3879
0
     error,
3880
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3881
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3882
0
     "%s: invalid handle.",
3883
0
     function );
3884
3885
0
    return( -1 );
3886
0
  }
3887
0
  internal_handle = (libmodi_internal_handle_t *) handle;
3888
3889
0
  if( internal_handle->file_io_handle == NULL )
3890
0
  {
3891
0
    libcerror_error_set(
3892
0
     error,
3893
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3894
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3895
0
     "%s: invalid handle - missing file IO handle.",
3896
0
     function );
3897
3898
0
    return( -1 );
3899
0
  }
3900
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
3901
0
  if( libcthreads_read_write_lock_grab_for_read(
3902
0
       internal_handle->read_write_lock,
3903
0
       error ) != 1 )
3904
0
  {
3905
0
    libcerror_error_set(
3906
0
     error,
3907
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3908
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3909
0
     "%s: unable to grab read/write lock for reading.",
3910
0
     function );
3911
3912
0
    return( -1 );
3913
0
  }
3914
0
#endif
3915
0
  if( libfdata_stream_get_offset(
3916
0
       internal_handle->data_stream,
3917
0
       offset,
3918
0
       error ) != 1 )
3919
0
  {
3920
0
    libcerror_error_set(
3921
0
     error,
3922
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3923
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3924
0
     "%s: unable to retrieve offset.",
3925
0
     function );
3926
3927
0
    result = -1;
3928
0
  }
3929
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
3930
0
  if( libcthreads_read_write_lock_release_for_read(
3931
0
       internal_handle->read_write_lock,
3932
0
       error ) != 1 )
3933
0
  {
3934
0
    libcerror_error_set(
3935
0
     error,
3936
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3937
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3938
0
     "%s: unable to release read/write lock for reading.",
3939
0
     function );
3940
3941
0
    return( -1 );
3942
0
  }
3943
0
#endif
3944
0
  return( result );
3945
0
}
3946
3947
/* Sets the maximum number of (concurrent) open file handles
3948
 * Returns 1 if successful or -1 on error
3949
 */
3950
int libmodi_handle_set_maximum_number_of_open_handles(
3951
     libmodi_handle_t *handle,
3952
     int maximum_number_of_open_handles,
3953
     libcerror_error_t **error )
3954
0
{
3955
0
  libmodi_internal_handle_t *internal_handle = NULL;
3956
0
  static char *function                      = "libmodi_handle_set_maximum_number_of_open_handles";
3957
0
  int result                                 = 1;
3958
3959
0
  if( handle == NULL )
3960
0
  {
3961
0
    libcerror_error_set(
3962
0
     error,
3963
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3964
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3965
0
     "%s: invalid handle.",
3966
0
     function );
3967
3968
0
    return( -1 );
3969
0
  }
3970
0
  internal_handle = (libmodi_internal_handle_t *) handle;
3971
3972
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
3973
0
  if( libcthreads_read_write_lock_grab_for_write(
3974
0
       internal_handle->read_write_lock,
3975
0
       error ) != 1 )
3976
0
  {
3977
0
    libcerror_error_set(
3978
0
     error,
3979
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3980
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3981
0
     "%s: unable to grab read/write lock for writing.",
3982
0
     function );
3983
3984
0
    return( -1 );
3985
0
  }
3986
0
#endif
3987
0
  if( internal_handle->band_data_file_io_pool != NULL )
3988
0
  {
3989
0
    result = libbfio_pool_set_maximum_number_of_open_handles(
3990
0
              internal_handle->band_data_file_io_pool,
3991
0
              maximum_number_of_open_handles,
3992
0
              error );
3993
3994
0
    if( result != 1 )
3995
0
    {
3996
0
      libcerror_error_set(
3997
0
       error,
3998
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3999
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4000
0
       "%s: unable to set maximum number of open handles in band data file IO pool.",
4001
0
       function );
4002
0
    }
4003
0
  }
4004
0
  if( result == 1 )
4005
0
  {
4006
0
    internal_handle->maximum_number_of_open_handles = maximum_number_of_open_handles;
4007
0
  }
4008
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
4009
0
  if( libcthreads_read_write_lock_release_for_write(
4010
0
       internal_handle->read_write_lock,
4011
0
       error ) != 1 )
4012
0
  {
4013
0
    libcerror_error_set(
4014
0
     error,
4015
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4016
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4017
0
     "%s: unable to release read/write lock for writing.",
4018
0
     function );
4019
4020
0
    return( -1 );
4021
0
  }
4022
0
#endif
4023
0
  return( result );
4024
0
}
4025
4026
/* Sets the path to the band data files
4027
 * Returns 1 if successful or -1 on error
4028
 */
4029
int libmodi_handle_set_band_data_files_path(
4030
     libmodi_handle_t *handle,
4031
     const char *path,
4032
     size_t path_length,
4033
     libcerror_error_t **error )
4034
0
{
4035
0
  libmodi_internal_handle_t *internal_handle = NULL;
4036
0
  static char *function                      = "libmodi_handle_set_band_data_files_path";
4037
0
  int result                                 = 1;
4038
4039
0
  if( handle == NULL )
4040
0
  {
4041
0
    libcerror_error_set(
4042
0
     error,
4043
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4044
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4045
0
     "%s: invalid handle.",
4046
0
     function );
4047
4048
0
    return( -1 );
4049
0
  }
4050
0
  internal_handle = (libmodi_internal_handle_t *) handle;
4051
4052
0
  if( internal_handle->io_handle == NULL )
4053
0
  {
4054
0
    libcerror_error_set(
4055
0
     error,
4056
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4057
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4058
0
     "%s: invalid handle - missing IO handle.",
4059
0
     function );
4060
4061
0
    return( -1 );
4062
0
  }
4063
0
  if( path == NULL )
4064
0
  {
4065
0
    libcerror_error_set(
4066
0
     error,
4067
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4068
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4069
0
     "%s: invalid path.",
4070
0
     function );
4071
4072
0
    return( -1 );
4073
0
  }
4074
0
  if( path_length > (size_t) ( SSIZE_MAX - 1 ) )
4075
0
  {
4076
0
    libcerror_error_set(
4077
0
     error,
4078
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4079
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4080
0
     "%s: invalid path length value exceeds maximum.",
4081
0
     function );
4082
4083
0
    return( -1 );
4084
0
  }
4085
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
4086
0
  if( libcthreads_read_write_lock_grab_for_write(
4087
0
       internal_handle->read_write_lock,
4088
0
       error ) != 1 )
4089
0
  {
4090
0
    libcerror_error_set(
4091
0
     error,
4092
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4093
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4094
0
     "%s: unable to grab read/write lock for writing.",
4095
0
     function );
4096
4097
0
    return( -1 );
4098
0
  }
4099
0
#endif
4100
0
  if( internal_handle->io_handle->image_type == LIBMODI_IMAGE_TYPE_SPARSE_BUNDLE )
4101
0
  {
4102
0
    if( libmodi_internal_handle_set_bands_directory_path(
4103
0
         internal_handle,
4104
0
         path,
4105
0
         path_length,
4106
0
         error ) != 1 )
4107
0
    {
4108
0
      libcerror_error_set(
4109
0
       error,
4110
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4111
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4112
0
       "%s: unable to set bands directory path.",
4113
0
       function );
4114
4115
0
      result = -1;
4116
0
    }
4117
0
  }
4118
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
4119
0
  if( libcthreads_read_write_lock_release_for_write(
4120
0
       internal_handle->read_write_lock,
4121
0
       error ) != 1 )
4122
0
  {
4123
0
    libcerror_error_set(
4124
0
     error,
4125
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4126
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4127
0
     "%s: unable to release read/write lock for writing.",
4128
0
     function );
4129
4130
0
    return( -1 );
4131
0
  }
4132
0
#endif
4133
0
  return( result );
4134
0
}
4135
4136
#if defined( HAVE_WIDE_CHARACTER_TYPE )
4137
4138
/* Sets the path to the band data files
4139
 * Returns 1 if successful or -1 on error
4140
 */
4141
int libmodi_handle_set_band_data_files_path_wide(
4142
     libmodi_handle_t *handle,
4143
     const wchar_t *path,
4144
     size_t path_length,
4145
     libcerror_error_t **error )
4146
{
4147
  libmodi_internal_handle_t *internal_handle = NULL;
4148
  static char *function                      = "libmodi_handle_set_band_data_files_path_wide";
4149
  int result                                 = 1;
4150
4151
  if( handle == NULL )
4152
  {
4153
    libcerror_error_set(
4154
     error,
4155
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4156
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4157
     "%s: invalid handle.",
4158
     function );
4159
4160
    return( -1 );
4161
  }
4162
  internal_handle = (libmodi_internal_handle_t *) handle;
4163
4164
  if( internal_handle->io_handle == NULL )
4165
  {
4166
    libcerror_error_set(
4167
     error,
4168
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4169
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4170
     "%s: invalid handle - missing IO handle.",
4171
     function );
4172
4173
    return( -1 );
4174
  }
4175
  if( path == NULL )
4176
  {
4177
    libcerror_error_set(
4178
     error,
4179
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4180
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4181
     "%s: invalid path.",
4182
     function );
4183
4184
    return( -1 );
4185
  }
4186
  if( path_length > (size_t) ( SSIZE_MAX - 1 ) )
4187
  {
4188
    libcerror_error_set(
4189
     error,
4190
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4191
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4192
     "%s: invalid path length value exceeds maximum.",
4193
     function );
4194
4195
    return( -1 );
4196
  }
4197
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
4198
  if( libcthreads_read_write_lock_grab_for_write(
4199
       internal_handle->read_write_lock,
4200
       error ) != 1 )
4201
  {
4202
    libcerror_error_set(
4203
     error,
4204
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4205
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4206
     "%s: unable to grab read/write lock for writing.",
4207
     function );
4208
4209
    return( -1 );
4210
  }
4211
#endif
4212
  if( internal_handle->io_handle->image_type == LIBMODI_IMAGE_TYPE_SPARSE_BUNDLE )
4213
  {
4214
    if( libmodi_internal_handle_set_bands_directory_path_wide(
4215
         internal_handle,
4216
         path,
4217
         path_length,
4218
         error ) != 1 )
4219
    {
4220
      libcerror_error_set(
4221
       error,
4222
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4223
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4224
       "%s: unable to set bands directory path.",
4225
       function );
4226
4227
      result = -1;
4228
    }
4229
  }
4230
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
4231
  if( libcthreads_read_write_lock_release_for_write(
4232
       internal_handle->read_write_lock,
4233
       error ) != 1 )
4234
  {
4235
    libcerror_error_set(
4236
     error,
4237
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4238
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4239
     "%s: unable to release read/write lock for writing.",
4240
     function );
4241
4242
    return( -1 );
4243
  }
4244
#endif
4245
  return( result );
4246
}
4247
4248
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
4249
4250
/* Retrieves the media size
4251
 * Returns the 1 if succesful or -1 on error
4252
 */
4253
int libmodi_handle_get_media_size(
4254
     libmodi_handle_t *handle,
4255
     size64_t *media_size,
4256
     libcerror_error_t **error )
4257
0
{
4258
0
  libmodi_internal_handle_t *internal_handle = NULL;
4259
0
  static char *function                      = "libmodi_handle_get_media_size";
4260
4261
0
  if( handle == NULL )
4262
0
  {
4263
0
    libcerror_error_set(
4264
0
     error,
4265
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4266
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4267
0
     "%s: invalid handle.",
4268
0
     function );
4269
4270
0
    return( -1 );
4271
0
  }
4272
0
  internal_handle = (libmodi_internal_handle_t *) handle;
4273
4274
0
  if( internal_handle->io_handle == NULL )
4275
0
  {
4276
0
    libcerror_error_set(
4277
0
     error,
4278
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4279
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4280
0
     "%s: invalid handle - missing IO handle.",
4281
0
     function );
4282
4283
0
    return( -1 );
4284
0
  }
4285
0
  if( internal_handle->file_io_handle == NULL )
4286
0
  {
4287
0
    libcerror_error_set(
4288
0
     error,
4289
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4290
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4291
0
     "%s: invalid handle - missing file IO handle.",
4292
0
     function );
4293
4294
0
    return( -1 );
4295
0
  }
4296
0
  if( media_size == NULL )
4297
0
  {
4298
0
    libcerror_error_set(
4299
0
     error,
4300
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4301
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4302
0
     "%s: invalid media size.",
4303
0
     function );
4304
4305
0
    return( -1 );
4306
0
  }
4307
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
4308
0
  if( libcthreads_read_write_lock_grab_for_read(
4309
0
       internal_handle->read_write_lock,
4310
0
       error ) != 1 )
4311
0
  {
4312
0
    libcerror_error_set(
4313
0
     error,
4314
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4315
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4316
0
     "%s: unable to grab read/write lock for reading.",
4317
0
     function );
4318
4319
0
    return( -1 );
4320
0
  }
4321
0
#endif
4322
0
  *media_size = internal_handle->io_handle->media_size;
4323
4324
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
4325
0
  if( libcthreads_read_write_lock_release_for_read(
4326
0
       internal_handle->read_write_lock,
4327
0
       error ) != 1 )
4328
0
  {
4329
0
    libcerror_error_set(
4330
0
     error,
4331
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4332
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4333
0
     "%s: unable to release read/write lock for reading.",
4334
0
     function );
4335
4336
0
    return( -1 );
4337
0
  }
4338
0
#endif
4339
0
  return( 1 );
4340
0
}
4341
4342
/* Retrieves the image type
4343
 * Returns the 1 if succesful or -1 on error
4344
 */
4345
int libmodi_handle_get_image_type(
4346
     libmodi_handle_t *handle,
4347
     int *image_type,
4348
     libcerror_error_t **error )
4349
0
{
4350
0
  libmodi_internal_handle_t *internal_handle = NULL;
4351
0
  static char *function                      = "libmodi_handle_get_image_type";
4352
4353
0
  if( handle == NULL )
4354
0
  {
4355
0
    libcerror_error_set(
4356
0
     error,
4357
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4358
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4359
0
     "%s: invalid handle.",
4360
0
     function );
4361
4362
0
    return( -1 );
4363
0
  }
4364
0
  internal_handle = (libmodi_internal_handle_t *) handle;
4365
4366
0
  if( internal_handle->io_handle == NULL )
4367
0
  {
4368
0
    libcerror_error_set(
4369
0
     error,
4370
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4371
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4372
0
     "%s: invalid handle - missing IO handle.",
4373
0
     function );
4374
4375
0
    return( -1 );
4376
0
  }
4377
0
  if( internal_handle->file_io_handle == NULL )
4378
0
  {
4379
0
    libcerror_error_set(
4380
0
     error,
4381
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4382
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4383
0
     "%s: invalid handle - missing file IO handle.",
4384
0
     function );
4385
4386
0
    return( -1 );
4387
0
  }
4388
0
  if( image_type == NULL )
4389
0
  {
4390
0
    libcerror_error_set(
4391
0
     error,
4392
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4393
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4394
0
     "%s: invalid image type.",
4395
0
     function );
4396
4397
0
    return( -1 );
4398
0
  }
4399
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
4400
0
  if( libcthreads_read_write_lock_grab_for_read(
4401
0
       internal_handle->read_write_lock,
4402
0
       error ) != 1 )
4403
0
  {
4404
0
    libcerror_error_set(
4405
0
     error,
4406
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4407
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4408
0
     "%s: unable to grab read/write lock for reading.",
4409
0
     function );
4410
4411
0
    return( -1 );
4412
0
  }
4413
0
#endif
4414
0
  *image_type = internal_handle->io_handle->image_type;
4415
4416
0
#if defined( HAVE_LIBMODI_MULTI_THREAD_SUPPORT )
4417
0
  if( libcthreads_read_write_lock_release_for_read(
4418
0
       internal_handle->read_write_lock,
4419
0
       error ) != 1 )
4420
0
  {
4421
0
    libcerror_error_set(
4422
0
     error,
4423
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4424
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4425
0
     "%s: unable to release read/write lock for reading.",
4426
0
     function );
4427
4428
0
    return( -1 );
4429
0
  }
4430
0
#endif
4431
0
  return( 1 );
4432
0
}
4433