Coverage Report

Created: 2024-02-25 07:19

/src/libodraw/libodraw/libodraw_handle.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Handle functions
3
 *
4
 * Copyright (C) 2010-2023, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <narrow_string.h>
25
#include <system_string.h>
26
#include <types.h>
27
#include <wide_string.h>
28
29
#include "libodraw_codepage.h"
30
#include "libodraw_cue_parser.h"
31
#include "libodraw_data_file.h"
32
#include "libodraw_data_file_descriptor.h"
33
#include "libodraw_debug.h"
34
#include "libodraw_definitions.h"
35
#include "libodraw_io_handle.h"
36
#include "libodraw_handle.h"
37
#include "libodraw_libbfio.h"
38
#include "libodraw_libcdata.h"
39
#include "libodraw_libcerror.h"
40
#include "libodraw_libclocale.h"
41
#include "libodraw_libcnotify.h"
42
#include "libodraw_libcpath.h"
43
#include "libodraw_libuna.h"
44
#include "libodraw_sector_range.h"
45
#include "libodraw_track_value.h"
46
#include "libodraw_types.h"
47
48
extern \
49
int libodraw_cue_parser_parse_buffer(
50
     libodraw_handle_t *handle,
51
     const uint8_t *buffer,
52
     size_t buffer_size,
53
     libcerror_error_t **error );
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 libodraw_handle_initialize(
60
     libodraw_handle_t **handle,
61
     libcerror_error_t **error )
62
1.51k
{
63
1.51k
  libodraw_internal_handle_t *internal_handle = NULL;
64
1.51k
  static char *function                       = "libodraw_handle_initialize";
65
66
1.51k
  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
1.51k
  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
1.51k
  internal_handle = memory_allocate_structure(
89
1.51k
                     libodraw_internal_handle_t );
90
91
1.51k
  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
    return( -1 );
101
0
  }
102
1.51k
  if( memory_set(
103
1.51k
       internal_handle,
104
1.51k
       0,
105
1.51k
       sizeof( libodraw_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
1.51k
  if( libcdata_array_initialize(
120
1.51k
       &( internal_handle->data_file_descriptors_array ),
121
1.51k
       0,
122
1.51k
       error ) != 1 )
123
0
  {
124
0
    libcerror_error_set(
125
0
     error,
126
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
127
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
128
0
     "%s: unable to create data file descriptors array.",
129
0
     function );
130
131
0
    goto on_error;
132
0
  }
133
1.51k
  if( libcdata_array_initialize(
134
1.51k
       &( internal_handle->sessions_array ),
135
1.51k
       0,
136
1.51k
       error ) != 1 )
137
0
  {
138
0
    libcerror_error_set(
139
0
     error,
140
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
141
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
142
0
     "%s: unable to create sessions array.",
143
0
     function );
144
145
0
    goto on_error;
146
0
  }
147
1.51k
  if( libcdata_array_initialize(
148
1.51k
       &( internal_handle->run_outs_array ),
149
1.51k
       0,
150
1.51k
       error ) != 1 )
151
0
  {
152
0
    libcerror_error_set(
153
0
     error,
154
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
155
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
156
0
     "%s: unable to create run-outs array.",
157
0
     function );
158
159
0
    goto on_error;
160
0
  }
161
1.51k
  if( libcdata_array_initialize(
162
1.51k
       &( internal_handle->lead_outs_array ),
163
1.51k
       0,
164
1.51k
       error ) != 1 )
165
0
  {
166
0
    libcerror_error_set(
167
0
     error,
168
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
169
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
170
0
     "%s: unable to create lead-outs array.",
171
0
     function );
172
173
0
    goto on_error;
174
0
  }
175
1.51k
  if( libcdata_array_initialize(
176
1.51k
       &( internal_handle->tracks_array ),
177
1.51k
       0,
178
1.51k
       error ) != 1 )
179
0
  {
180
0
    libcerror_error_set(
181
0
     error,
182
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
183
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
184
0
     "%s: unable to create tracks array.",
185
0
     function );
186
187
0
    goto on_error;
188
0
  }
189
1.51k
  if( libodraw_io_handle_initialize(
190
1.51k
       &( internal_handle->io_handle ),
191
1.51k
       error ) != 1 )
192
0
  {
193
0
    libcerror_error_set(
194
0
     error,
195
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
196
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
197
0
     "%s: unable to create IO handle.",
198
0
     function );
199
200
0
    goto on_error;
201
0
  }
202
1.51k
  internal_handle->maximum_number_of_open_handles = LIBBFIO_POOL_UNLIMITED_NUMBER_OF_OPEN_HANDLES;
203
204
1.51k
  *handle = (libodraw_handle_t *) internal_handle;
205
206
1.51k
  return( 1 );
207
208
0
on_error:
209
0
  if( internal_handle != NULL )
210
0
  {
211
0
    if( internal_handle->tracks_array != NULL )
212
0
    {
213
0
      libcdata_array_free(
214
0
       &( internal_handle->tracks_array ),
215
0
       NULL,
216
0
       NULL );
217
0
    }
218
0
    if( internal_handle->lead_outs_array != NULL )
219
0
    {
220
0
      libcdata_array_free(
221
0
       &( internal_handle->lead_outs_array ),
222
0
       NULL,
223
0
       NULL );
224
0
    }
225
0
    if( internal_handle->run_outs_array != NULL )
226
0
    {
227
0
      libcdata_array_free(
228
0
       &( internal_handle->run_outs_array ),
229
0
       NULL,
230
0
       NULL );
231
0
    }
232
0
    if( internal_handle->sessions_array != NULL )
233
0
    {
234
0
      libcdata_array_free(
235
0
       &( internal_handle->sessions_array ),
236
0
       NULL,
237
0
       NULL );
238
0
    }
239
0
    if( internal_handle->data_file_descriptors_array != NULL )
240
0
    {
241
0
      libcdata_array_free(
242
0
       &( internal_handle->data_file_descriptors_array ),
243
0
       NULL,
244
0
       NULL );
245
0
    }
246
0
    memory_free(
247
0
     internal_handle );
248
0
  }
249
0
  return( -1 );
250
1.51k
}
251
252
/* Frees a handle
253
 * Returns 1 if successful or -1 on error
254
 */
255
int libodraw_handle_free(
256
     libodraw_handle_t **handle,
257
     libcerror_error_t **error )
258
1.51k
{
259
1.51k
  libodraw_internal_handle_t *internal_handle = NULL;
260
1.51k
  static char *function                       = "libodraw_handle_free";
261
1.51k
  int result                                  = 1;
262
263
1.51k
  if( handle == NULL )
264
0
  {
265
0
    libcerror_error_set(
266
0
     error,
267
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
268
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
269
0
     "%s: invalid handle.",
270
0
     function );
271
272
0
    return( -1 );
273
0
  }
274
1.51k
  if( *handle != NULL )
275
1.51k
  {
276
1.51k
    internal_handle = (libodraw_internal_handle_t *) *handle;
277
278
1.51k
    if( ( internal_handle->toc_file_io_handle != NULL )
279
1.51k
     || ( internal_handle->data_file_io_pool != NULL ) )
280
0
    {
281
0
      if( libodraw_handle_close(
282
0
           *handle,
283
0
           error ) != 0 )
284
0
      {
285
0
        libcerror_error_set(
286
0
         error,
287
0
         LIBCERROR_ERROR_DOMAIN_IO,
288
0
         LIBCERROR_IO_ERROR_CLOSE_FAILED,
289
0
         "%s: unable to close handle.",
290
0
         function );
291
292
0
        result = -1;
293
0
      }
294
0
    }
295
1.51k
    *handle = NULL;
296
297
1.51k
    if( libcdata_array_free(
298
1.51k
         &( internal_handle->data_file_descriptors_array ),
299
1.51k
         (int (*)(intptr_t **, libcerror_error_t **)) &libodraw_data_file_descriptor_free,
300
1.51k
         error ) != 1 )
301
0
    {
302
0
      libcerror_error_set(
303
0
       error,
304
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
305
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
306
0
       "%s: unable to free files array.",
307
0
       function );
308
309
0
      result = -1;
310
0
    }
311
1.51k
    if( libcdata_array_free(
312
1.51k
         &( internal_handle->sessions_array ),
313
1.51k
         (int (*)(intptr_t **, libcerror_error_t **)) &libodraw_sector_range_free,
314
1.51k
         error ) != 1 )
315
0
    {
316
0
      libcerror_error_set(
317
0
       error,
318
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
319
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
320
0
       "%s: unable to free sessions array.",
321
0
       function );
322
323
0
      result = -1;
324
0
    }
325
1.51k
    if( libcdata_array_free(
326
1.51k
         &( internal_handle->run_outs_array ),
327
1.51k
         (int (*)(intptr_t **, libcerror_error_t **)) &libodraw_sector_range_free,
328
1.51k
         error ) != 1 )
329
0
    {
330
0
      libcerror_error_set(
331
0
       error,
332
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
333
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
334
0
       "%s: unable to free run-outs array.",
335
0
       function );
336
337
0
      result = -1;
338
0
    }
339
1.51k
    if( libcdata_array_free(
340
1.51k
         &( internal_handle->lead_outs_array ),
341
1.51k
         (int (*)(intptr_t **, libcerror_error_t **)) &libodraw_sector_range_free,
342
1.51k
         error ) != 1 )
343
0
    {
344
0
      libcerror_error_set(
345
0
       error,
346
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
347
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
348
0
       "%s: unable to free lead-outs array.",
349
0
       function );
350
351
0
      result = -1;
352
0
    }
353
1.51k
    if( libcdata_array_free(
354
1.51k
         &( internal_handle->tracks_array ),
355
1.51k
         (int (*)(intptr_t **, libcerror_error_t **)) &libodraw_track_value_free,
356
1.51k
         error ) != 1 )
357
0
    {
358
0
      libcerror_error_set(
359
0
       error,
360
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
361
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
362
0
       "%s: unable to free tracks array.",
363
0
       function );
364
365
0
      result = -1;
366
0
    }
367
1.51k
    if( libodraw_io_handle_free(
368
1.51k
         &( internal_handle->io_handle ),
369
1.51k
         error ) != 1 )
370
0
    {
371
0
      libcerror_error_set(
372
0
       error,
373
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
374
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
375
0
       "%s: unable to free IO handle.",
376
0
       function );
377
378
0
      result = -1;
379
0
    }
380
1.51k
    memory_free(
381
1.51k
     internal_handle );
382
1.51k
  }
383
1.51k
  return( result );
384
1.51k
}
385
386
/* Signals the handle to abort its current activity
387
 * Returns 1 if successful or -1 on error
388
 */
389
int libodraw_handle_signal_abort(
390
     libodraw_handle_t *handle,
391
     libcerror_error_t **error )
392
0
{
393
0
  libodraw_internal_handle_t *internal_handle = NULL;
394
0
  static char *function                       = "libodraw_handle_signal_abort";
395
396
0
  if( handle == NULL )
397
0
  {
398
0
    libcerror_error_set(
399
0
     error,
400
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
401
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
402
0
     "%s: invalid handle.",
403
0
     function );
404
405
0
    return( -1 );
406
0
  }
407
0
  internal_handle = (libodraw_internal_handle_t *) handle;
408
409
0
  if( internal_handle->io_handle == NULL )
410
0
  {
411
0
    libcerror_error_set(
412
0
     error,
413
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
414
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
415
0
     "%s: invalid handle - missing IO handle.",
416
0
     function );
417
418
0
    return( -1 );
419
0
  }
420
0
  internal_handle->io_handle->abort = 1;
421
422
0
  return( 1 );
423
0
}
424
425
/* Opens a handle using a table of contents (TOC) file
426
 * Returns 1 if successful or -1 on error
427
 */
428
int libodraw_handle_open(
429
     libodraw_handle_t *handle,
430
     const char *filename,
431
     int access_flags,
432
     libcerror_error_t **error )
433
0
{
434
0
  libbfio_handle_t *file_io_handle            = NULL;
435
0
  libodraw_internal_handle_t *internal_handle = NULL;
436
0
  char *basename_end                          = NULL;
437
0
  static char *function                       = "libodraw_handle_open";
438
0
  size_t basename_length                      = 0;
439
0
  size_t filename_length                      = 0;
440
441
0
  if( handle == NULL )
442
0
  {
443
0
    libcerror_error_set(
444
0
     error,
445
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
446
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
447
0
     "%s: invalid handle.",
448
0
     function );
449
450
0
    return( -1 );
451
0
  }
452
0
  internal_handle = (libodraw_internal_handle_t *) handle;
453
454
0
  if( internal_handle->basename != NULL )
455
0
  {
456
0
    libcerror_error_set(
457
0
     error,
458
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
459
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
460
0
     "%s: invalid handle - basename already set.",
461
0
     function );
462
463
0
    return( -1 );
464
0
  }
465
0
  if( filename == NULL )
466
0
  {
467
0
    libcerror_error_set(
468
0
     error,
469
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
470
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
471
0
     "%s: invalid filename.",
472
0
     function );
473
474
0
    return( -1 );
475
0
  }
476
0
  if( ( ( access_flags & LIBODRAW_ACCESS_FLAG_READ ) == 0 )
477
0
   && ( ( access_flags & LIBODRAW_ACCESS_FLAG_WRITE ) == 0 ) )
478
0
  {
479
0
    libcerror_error_set(
480
0
     error,
481
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
482
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
483
0
     "%s: unsupported access flags.",
484
0
     function );
485
486
0
    return( -1 );
487
0
  }
488
0
  if( ( access_flags & LIBODRAW_ACCESS_FLAG_WRITE ) != 0 )
489
0
  {
490
0
    libcerror_error_set(
491
0
     error,
492
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
493
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
494
0
     "%s: write access currently not supported.",
495
0
     function );
496
497
0
    return( -1 );
498
0
  }
499
0
  filename_length = narrow_string_length(
500
0
                     filename );
501
502
0
  basename_end = narrow_string_search_character_reverse(
503
0
                  filename,
504
0
                  (int) LIBCPATH_SEPARATOR,
505
0
                  filename_length + 1 );
506
507
0
  if( basename_end != NULL )
508
0
  {
509
0
    basename_length = (size_t) ( basename_end - filename ) + 1;
510
0
  }
511
0
  if( basename_length > 0 )
512
0
  {
513
0
    if( libodraw_internal_handle_set_basename(
514
0
         internal_handle,
515
0
         filename,
516
0
         basename_length,
517
0
         error ) != 1 )
518
0
    {
519
0
      libcerror_error_set(
520
0
       error,
521
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
522
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
523
0
       "%s: unable to set basename.",
524
0
       function );
525
526
0
      goto on_error;
527
0
    }
528
0
  }
529
0
  if( libbfio_file_initialize(
530
0
       &file_io_handle,
531
0
       error ) != 1 )
532
0
  {
533
0
    libcerror_error_set(
534
0
     error,
535
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
536
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
537
0
     "%s: unable to create file IO handle.",
538
0
     function );
539
540
0
    goto on_error;
541
0
  }
542
#if defined( HAVE_DEBUG_OUTPUT )
543
  if( libbfio_handle_set_track_offsets_read(
544
       file_io_handle,
545
       1,
546
       error ) != 1 )
547
  {
548
    libcerror_error_set(
549
     error,
550
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
551
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
552
     "%s: unable to set track offsets read in file IO handle.",
553
     function );
554
555
    goto on_error;
556
  }
557
#endif
558
0
  if( libbfio_file_set_name(
559
0
       file_io_handle,
560
0
       filename,
561
0
       filename_length + 1,
562
0
       error ) != 1 )
563
0
  {
564
0
    libcerror_error_set(
565
0
     error,
566
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
567
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
568
0
     "%s: unable to set filename in file IO handle.",
569
0
     function );
570
571
0
    goto on_error;
572
0
  }
573
0
  if( libodraw_handle_open_file_io_handle(
574
0
       handle,
575
0
       file_io_handle,
576
0
       access_flags,
577
0
       error ) != 1 )
578
0
  {
579
0
    libcerror_error_set(
580
0
     error,
581
0
     LIBCERROR_ERROR_DOMAIN_IO,
582
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
583
0
     "%s: unable to open file: %s.",
584
0
     function,
585
0
     filename );
586
587
0
    goto on_error;
588
0
  }
589
0
  internal_handle->toc_file_io_handle_created_in_library = 1;
590
591
0
  return( 1 );
592
593
0
on_error:
594
0
  if( file_io_handle != NULL )
595
0
  {
596
0
    libbfio_handle_free(
597
0
     &file_io_handle,
598
0
     NULL );
599
0
  }
600
0
  if( internal_handle->basename != NULL )
601
0
  {
602
0
    memory_free(
603
0
     internal_handle->basename );
604
605
0
    internal_handle->basename = NULL;
606
0
  }
607
0
  internal_handle->basename_size = 0;
608
609
0
  return( -1 );
610
0
}
611
612
#if defined( HAVE_WIDE_CHARACTER_TYPE )
613
614
/* Opens a handle using a table of contents (TOC) file
615
 * Returns 1 if successful or -1 on error
616
 */
617
int libodraw_handle_open_wide(
618
     libodraw_handle_t *handle,
619
     const wchar_t *filename,
620
     int access_flags,
621
     libcerror_error_t **error )
622
{
623
  libbfio_handle_t *file_io_handle            = NULL;
624
  libodraw_internal_handle_t *internal_handle = NULL;
625
  wchar_t *basename_end                       = NULL;
626
  static char *function                       = "libodraw_handle_open_wide";
627
  size_t basename_length                      = 0;
628
  size_t filename_length                      = 0;
629
630
  if( handle == NULL )
631
  {
632
    libcerror_error_set(
633
     error,
634
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
635
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
636
     "%s: invalid handle.",
637
     function );
638
639
    return( -1 );
640
  }
641
  internal_handle = (libodraw_internal_handle_t *) handle;
642
643
  if( internal_handle->basename != NULL )
644
  {
645
    libcerror_error_set(
646
     error,
647
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
648
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
649
     "%s: invalid handle - basename already set.",
650
     function );
651
652
    return( -1 );
653
  }
654
  if( filename == NULL )
655
  {
656
    libcerror_error_set(
657
     error,
658
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
659
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
660
     "%s: invalid filename.",
661
     function );
662
663
    return( -1 );
664
  }
665
  if( ( ( access_flags & LIBODRAW_ACCESS_FLAG_READ ) == 0 )
666
   && ( ( access_flags & LIBODRAW_ACCESS_FLAG_WRITE ) == 0 ) )
667
  {
668
    libcerror_error_set(
669
     error,
670
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
671
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
672
     "%s: unsupported access flags.",
673
     function );
674
675
    return( -1 );
676
  }
677
  if( ( access_flags & LIBODRAW_ACCESS_FLAG_WRITE ) != 0 )
678
  {
679
    libcerror_error_set(
680
     error,
681
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
682
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
683
     "%s: write access currently not supported.",
684
     function );
685
686
    return( -1 );
687
  }
688
  filename_length = wide_string_length(
689
                     filename );
690
691
/* TODO does this work for UTF-16 ? */
692
  basename_end = wide_string_search_character_reverse(
693
                  filename,
694
                  (wint_t) LIBCPATH_SEPARATOR,
695
                  filename_length + 1 );
696
697
  if( basename_end != NULL )
698
  {
699
    basename_length = (size_t) ( basename_end - filename ) + 1;
700
  }
701
  if( basename_length > 0 )
702
  {
703
    if( libodraw_internal_handle_set_basename_wide(
704
         internal_handle,
705
         filename,
706
         basename_length,
707
         error ) != 1 )
708
    {
709
      libcerror_error_set(
710
       error,
711
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
712
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
713
       "%s: unable to set basename.",
714
       function );
715
716
      goto on_error;
717
    }
718
  }
719
  if( libbfio_file_initialize(
720
       &file_io_handle,
721
       error ) != 1 )
722
  {
723
    libcerror_error_set(
724
     error,
725
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
726
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
727
     "%s: unable to create file IO handle.",
728
     function );
729
730
    goto on_error;
731
  }
732
#if defined( HAVE_DEBUG_OUTPUT )
733
  if( libbfio_handle_set_track_offsets_read(
734
       file_io_handle,
735
       1,
736
       error ) != 1 )
737
  {
738
    libcerror_error_set(
739
     error,
740
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
741
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
742
     "%s: unable to set track offsets read in file IO handle.",
743
     function );
744
745
    goto on_error;
746
  }
747
#endif
748
  if( libbfio_file_set_name_wide(
749
       file_io_handle,
750
       filename,
751
       wide_string_length(
752
        filename ) + 1,
753
       error ) != 1 )
754
  {
755
    libcerror_error_set(
756
     error,
757
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
758
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
759
     "%s: unable to set filename in file IO handle.",
760
     function );
761
762
    goto on_error;
763
  }
764
  if( libodraw_handle_open_file_io_handle(
765
       handle,
766
       file_io_handle,
767
       access_flags,
768
       error ) != 1 )
769
  {
770
    libcerror_error_set(
771
     error,
772
     LIBCERROR_ERROR_DOMAIN_IO,
773
     LIBCERROR_IO_ERROR_OPEN_FAILED,
774
     "%s: unable to open file: %ls.",
775
     function,
776
     filename );
777
778
    goto on_error;
779
  }
780
  internal_handle->toc_file_io_handle_created_in_library = 1;
781
782
  return( 1 );
783
784
on_error:
785
  if( file_io_handle != NULL )
786
  {
787
    libbfio_handle_free(
788
     &file_io_handle,
789
     NULL );
790
  }
791
  if( internal_handle->basename != NULL )
792
  {
793
    memory_free(
794
     internal_handle->basename );
795
796
    internal_handle->basename = NULL;
797
  }
798
  internal_handle->basename_size = 0;
799
800
  return( -1 );
801
}
802
803
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
804
805
/* Opens a handle using a Basic File IO (bfio) handle of a table of contents (TOC) file
806
 * Returns 1 if successful or -1 on error
807
 */
808
int libodraw_handle_open_file_io_handle(
809
     libodraw_handle_t *handle,
810
     libbfio_handle_t *file_io_handle,
811
     int access_flags,
812
     libcerror_error_t **error )
813
1.51k
{
814
1.51k
  libodraw_internal_handle_t *internal_handle = NULL;
815
1.51k
  static char *function                       = "libodraw_handle_open_file_io_handle";
816
1.51k
  uint8_t file_io_handle_opened_in_library    = 0;
817
1.51k
  int bfio_access_flags                       = 0;
818
1.51k
  int file_io_handle_is_open                  = 0;
819
820
1.51k
  if( handle == NULL )
821
0
  {
822
0
    libcerror_error_set(
823
0
     error,
824
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
825
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
826
0
     "%s: invalid handle.",
827
0
     function );
828
829
0
    return( -1 );
830
0
  }
831
1.51k
  internal_handle = (libodraw_internal_handle_t *) handle;
832
833
1.51k
  if( internal_handle->toc_file_io_handle != NULL )
834
0
  {
835
0
    libcerror_error_set(
836
0
     error,
837
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
838
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
839
0
     "%s: invalid handle - file IO handle already set.",
840
0
     function );
841
842
0
    return( -1 );
843
0
  }
844
1.51k
  if( file_io_handle == NULL )
845
0
  {
846
0
    libcerror_error_set(
847
0
     error,
848
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
849
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
850
0
     "%s: invalid file IO handle.",
851
0
     function );
852
853
0
    return( -1 );
854
0
  }
855
1.51k
  if( ( ( access_flags & LIBODRAW_ACCESS_FLAG_READ ) == 0 )
856
1.51k
   && ( ( access_flags & LIBODRAW_ACCESS_FLAG_WRITE ) == 0 ) )
857
0
  {
858
0
    libcerror_error_set(
859
0
     error,
860
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
861
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
862
0
     "%s: unsupported access flags.",
863
0
     function );
864
865
0
    return( -1 );
866
0
  }
867
1.51k
  if( ( access_flags & LIBODRAW_ACCESS_FLAG_WRITE ) != 0 )
868
0
  {
869
0
    libcerror_error_set(
870
0
     error,
871
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
872
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
873
0
     "%s: write access currently not supported.",
874
0
     function );
875
876
0
    return( -1 );
877
0
  }
878
1.51k
  if( ( access_flags & LIBODRAW_ACCESS_FLAG_READ ) != 0 )
879
1.51k
  {
880
1.51k
    bfio_access_flags = LIBBFIO_ACCESS_FLAG_READ;
881
1.51k
  }
882
1.51k
  file_io_handle_is_open = libbfio_handle_is_open(
883
1.51k
                            file_io_handle,
884
1.51k
                            error );
885
886
1.51k
  if( file_io_handle_is_open == -1 )
887
0
  {
888
0
    libcerror_error_set(
889
0
     error,
890
0
     LIBCERROR_ERROR_DOMAIN_IO,
891
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
892
0
     "%s: unable to open file.",
893
0
     function );
894
895
0
    goto on_error;
896
0
  }
897
1.51k
  else if( file_io_handle_is_open == 0 )
898
1.51k
  {
899
1.51k
    if( libbfio_handle_open(
900
1.51k
         file_io_handle,
901
1.51k
         bfio_access_flags,
902
1.51k
         error ) != 1 )
903
0
    {
904
0
      libcerror_error_set(
905
0
       error,
906
0
       LIBCERROR_ERROR_DOMAIN_IO,
907
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
908
0
       "%s: unable to open file IO handle.",
909
0
       function );
910
911
0
      goto on_error;
912
0
    }
913
1.51k
    file_io_handle_opened_in_library = 1;
914
1.51k
  }
915
1.51k
  if( libodraw_handle_open_read(
916
1.51k
       internal_handle,
917
1.51k
       file_io_handle,
918
1.51k
       error ) != 1 )
919
751
  {
920
751
    libcerror_error_set(
921
751
     error,
922
751
     LIBCERROR_ERROR_DOMAIN_IO,
923
751
     LIBCERROR_IO_ERROR_READ_FAILED,
924
751
     "%s: unable to read from handle.",
925
751
     function );
926
927
751
    goto on_error;
928
751
  }
929
765
  internal_handle->access_flags                         = access_flags;
930
765
  internal_handle->toc_file_io_handle                   = file_io_handle;
931
765
  internal_handle->toc_file_io_handle_opened_in_library = file_io_handle_opened_in_library;
932
933
765
  return( 1 );
934
935
751
on_error:
936
751
  if( ( file_io_handle_is_open == 0 )
937
751
   && ( file_io_handle_opened_in_library != 0 ) )
938
751
  {
939
751
    libbfio_handle_close(
940
751
     file_io_handle,
941
751
     error );
942
751
  }
943
751
  return( -1 );
944
1.51k
}
945
946
/* Opens the data files
947
 * If the data filenames were not set explicitly this function assumes the data files
948
 * are in the same location as the table of contents (TOC) file
949
 * Returns 1 if successful or -1 on error
950
 */
951
int libodraw_handle_open_data_files(
952
     libodraw_handle_t *handle,
953
     libcerror_error_t **error )
954
0
{
955
0
  libodraw_data_file_descriptor_t *data_file_descriptor = NULL;
956
0
  libodraw_internal_handle_t *internal_handle           = NULL;
957
0
  system_character_t *data_file_location                = NULL;
958
0
  system_character_t *data_file_name_start              = NULL;
959
0
  static char *function                                 = "libodraw_handle_open_data_files";
960
0
  size_t data_file_location_size                        = 0;
961
0
  size_t data_file_name_size                            = 0;
962
0
  int data_file_descriptor_index                        = 0;
963
0
  int number_of_data_file_descriptors                   = 0;
964
0
  int result                                            = 0;
965
966
0
  if( handle == NULL )
967
0
  {
968
0
    libcerror_error_set(
969
0
     error,
970
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
971
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
972
0
     "%s: invalid handle.",
973
0
     function );
974
975
0
    return( -1 );
976
0
  }
977
0
  internal_handle = (libodraw_internal_handle_t *) handle;
978
979
0
  if( internal_handle->toc_file_io_handle == NULL )
980
0
  {
981
0
    libcerror_error_set(
982
0
     error,
983
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
984
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
985
0
     "%s: invalid handle - missing TOC file IO handle.",
986
0
     function );
987
988
0
    return( -1 );
989
0
  }
990
0
  if( libcdata_array_get_number_of_entries(
991
0
       internal_handle->data_file_descriptors_array,
992
0
       &number_of_data_file_descriptors,
993
0
       error ) != 1 )
994
0
  {
995
0
    libcerror_error_set(
996
0
     error,
997
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
998
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
999
0
     "%s: unable to retrieve number of data file descriptors.",
1000
0
     function );
1001
1002
0
    return( -1 );
1003
0
  }
1004
0
  for( data_file_descriptor_index = 0;
1005
0
       data_file_descriptor_index < number_of_data_file_descriptors;
1006
0
       data_file_descriptor_index++ )
1007
0
  {
1008
0
    if( libcdata_array_get_entry_by_index(
1009
0
         internal_handle->data_file_descriptors_array,
1010
0
         data_file_descriptor_index,
1011
0
         (intptr_t **) &data_file_descriptor,
1012
0
         error ) != 1 )
1013
0
    {
1014
0
      libcerror_error_set(
1015
0
       error,
1016
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1017
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1018
0
       "%s: unable to retrieve data file descriptor: %d.",
1019
0
       function,
1020
0
       data_file_descriptor_index );
1021
1022
0
      goto on_error;
1023
0
    }
1024
0
    if( data_file_descriptor == NULL )
1025
0
    {
1026
0
      libcerror_error_set(
1027
0
       error,
1028
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1029
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1030
0
       "%s: missing data file descriptor: %d.",
1031
0
       function,
1032
0
       data_file_descriptor_index );
1033
1034
0
      goto on_error;
1035
0
    }
1036
0
    if( ( data_file_descriptor->name == NULL )
1037
0
     || ( data_file_descriptor->name_size == 0 ) )
1038
0
    {
1039
0
      libcerror_error_set(
1040
0
       error,
1041
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1042
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1043
0
       "%s: invalid data file descriptor: %d - missing name.",
1044
0
       function,
1045
0
       data_file_descriptor_index );
1046
1047
0
      goto on_error;
1048
0
    }
1049
0
    if( data_file_descriptor->name_set == 0 )
1050
0
    {
1051
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
1052
      data_file_name_start = wide_string_search_character_reverse(
1053
                              data_file_descriptor->name,
1054
                              (wint_t) LIBCPATH_SEPARATOR,
1055
                              data_file_descriptor->name_size );
1056
#else
1057
0
      data_file_name_start = narrow_string_search_character_reverse(
1058
0
                              data_file_descriptor->name,
1059
0
                              (int) LIBCPATH_SEPARATOR,
1060
0
                              data_file_descriptor->name_size );
1061
0
#endif
1062
0
    }
1063
0
    if( data_file_name_start != NULL )
1064
0
    {
1065
      /* Ignore the path separator itself
1066
       */
1067
0
      data_file_name_start++;
1068
1069
/* TODO does this work for UTF-16 ? */
1070
0
      data_file_name_size = (size_t) ( data_file_name_start - data_file_descriptor->name );
1071
0
    }
1072
0
    else
1073
0
    {
1074
0
      data_file_name_start = data_file_descriptor->name;
1075
0
      data_file_name_size  = data_file_descriptor->name_size;
1076
0
    }
1077
0
    if( ( data_file_descriptor->name_set == 0 )
1078
0
     && ( internal_handle->basename != NULL ) )
1079
0
    {
1080
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
1081
      if( libcpath_path_join_wide(
1082
           &data_file_location,
1083
           &data_file_location_size,
1084
           internal_handle->basename,
1085
           internal_handle->basename_size - 1,
1086
           data_file_name_start,
1087
           data_file_name_size - 1,
1088
           error ) != 1 )
1089
#else
1090
0
      if( libcpath_path_join(
1091
0
           &data_file_location,
1092
0
           &data_file_location_size,
1093
0
           internal_handle->basename,
1094
0
           internal_handle->basename_size - 1,
1095
0
           data_file_name_start,
1096
0
           data_file_name_size - 1,
1097
0
           error ) != 1 )
1098
0
#endif
1099
0
      {
1100
0
        libcerror_error_set(
1101
0
         error,
1102
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1103
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1104
0
         "%s: unable to create data file location.",
1105
0
         function );
1106
1107
0
        goto on_error;
1108
0
      }
1109
0
    }
1110
0
    else
1111
0
    {
1112
0
      data_file_location      = data_file_name_start;
1113
0
      data_file_location_size = data_file_name_size;
1114
0
    }
1115
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
1116
    result = libodraw_handle_open_data_file_wide(
1117
        internal_handle,
1118
        data_file_descriptor_index,
1119
        data_file_location,
1120
        error );
1121
#else
1122
0
    result = libodraw_handle_open_data_file(
1123
0
        internal_handle,
1124
0
        data_file_descriptor_index,
1125
0
        data_file_location,
1126
0
        error );
1127
0
#endif
1128
0
    if( result != 1 )
1129
0
    {
1130
0
      libcerror_error_set(
1131
0
       error,
1132
0
       LIBCERROR_ERROR_DOMAIN_IO,
1133
0
       LIBCERROR_IO_ERROR_OPEN_FAILED,
1134
0
       "%s: unable to open data file: %" PRIs_SYSTEM ".",
1135
0
       function,
1136
0
       data_file_location );
1137
1138
0
      goto on_error;
1139
0
    }
1140
0
    if( ( data_file_location != NULL )
1141
0
     && ( data_file_location != data_file_name_start ) )
1142
0
    {
1143
0
      memory_free(
1144
0
       data_file_location );
1145
0
    }
1146
0
    data_file_name_start = NULL;
1147
0
    data_file_location   = NULL;
1148
0
  }
1149
0
  if( libodraw_handle_set_media_values(
1150
0
       internal_handle,
1151
0
       error ) != 1 )
1152
0
  {
1153
0
    libcerror_error_set(
1154
0
     error,
1155
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1156
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1157
0
     "%s: unable to set media values.",
1158
0
     function );
1159
1160
0
    goto on_error;
1161
0
  }
1162
0
  return( 1 );
1163
1164
0
on_error:
1165
0
  if( ( data_file_location != NULL )
1166
0
   && ( data_file_location != data_file_name_start ) )
1167
0
  {
1168
0
    memory_free(
1169
0
     data_file_location );
1170
0
  }
1171
0
  return( -1 );
1172
0
}
1173
1174
/* Opens the data files using a Basic File IO (bfio) pool
1175
 * This function assumes the data files are in same order as defined by the table of contents (TOC) file
1176
 * Returns 1 if successful or -1 on error
1177
 */
1178
int libodraw_handle_open_data_files_file_io_pool(
1179
     libodraw_handle_t *handle,
1180
     libbfio_pool_t *file_io_pool,
1181
     libcerror_error_t **error )
1182
0
{
1183
0
  libodraw_internal_handle_t *internal_handle = NULL;
1184
0
  static char *function                       = "libodraw_handle_open_data_files_file_io_pool";
1185
1186
0
  if( handle == NULL )
1187
0
  {
1188
0
    libcerror_error_set(
1189
0
     error,
1190
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1191
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1192
0
     "%s: invalid handle.",
1193
0
     function );
1194
1195
0
    return( -1 );
1196
0
  }
1197
0
  internal_handle = (libodraw_internal_handle_t *) handle;
1198
1199
0
  if( internal_handle->toc_file_io_handle == NULL )
1200
0
  {
1201
0
    libcerror_error_set(
1202
0
     error,
1203
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1204
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1205
0
     "%s: invalid handle - missing TOC file IO handle.",
1206
0
     function );
1207
1208
0
    return( -1 );
1209
0
  }
1210
0
  if( internal_handle->data_file_io_pool != NULL )
1211
0
  {
1212
0
    libcerror_error_set(
1213
0
     error,
1214
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1215
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1216
0
     "%s: invalid handle - data file IO pool already exists.",
1217
0
     function );
1218
1219
0
    return( -1 );
1220
0
  }
1221
0
  if( file_io_pool == NULL )
1222
0
  {
1223
0
    libcerror_error_set(
1224
0
     error,
1225
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1226
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1227
0
     "%s: invalid file IO pool.",
1228
0
     function );
1229
1230
0
    return( -1 );
1231
0
  }
1232
0
  internal_handle->data_file_io_pool = file_io_pool;
1233
1234
0
  if( libodraw_handle_set_media_values(
1235
0
       internal_handle,
1236
0
       error ) != 1 )
1237
0
  {
1238
0
    libcerror_error_set(
1239
0
     error,
1240
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1241
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1242
0
     "%s: unable to set media values.",
1243
0
     function );
1244
1245
0
    return( -1 );
1246
0
  }
1247
0
  return( 1 );
1248
0
}
1249
1250
/* Opens a specific data file
1251
 * Returns 1 if successful or -1 on error
1252
 */
1253
int libodraw_handle_open_data_file(
1254
     libodraw_internal_handle_t *internal_handle,
1255
     int data_file_index,
1256
     const char *filename,
1257
     libcerror_error_t **error )
1258
0
{
1259
0
  libbfio_handle_t *file_io_handle = NULL;
1260
0
  static char *function            = "libodraw_handle_open_data_file";
1261
1262
0
  if( internal_handle == NULL )
1263
0
  {
1264
0
    libcerror_error_set(
1265
0
     error,
1266
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1267
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1268
0
     "%s: invalid handle.",
1269
0
     function );
1270
1271
0
    return( -1 );
1272
0
  }
1273
0
  if( internal_handle->toc_file_io_handle == NULL )
1274
0
  {
1275
0
    libcerror_error_set(
1276
0
     error,
1277
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1278
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1279
0
     "%s: invalid handle - missing TOC file IO handle.",
1280
0
     function );
1281
1282
0
    return( -1 );
1283
0
  }
1284
0
  if( filename == NULL )
1285
0
  {
1286
0
    libcerror_error_set(
1287
0
     error,
1288
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1289
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1290
0
     "%s: invalid filename.",
1291
0
     function );
1292
1293
0
    return( -1 );
1294
0
  }
1295
0
  if( libbfio_file_initialize(
1296
0
       &file_io_handle,
1297
0
       error ) != 1 )
1298
0
  {
1299
0
    libcerror_error_set(
1300
0
     error,
1301
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1302
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1303
0
     "%s: unable to create file IO handle.",
1304
0
     function );
1305
1306
0
    goto on_error;
1307
0
  }
1308
#if defined( HAVE_DEBUG_OUTPUT )
1309
  if( libbfio_handle_set_track_offsets_read(
1310
       file_io_handle,
1311
       1,
1312
       error ) != 1 )
1313
  {
1314
    libcerror_error_set(
1315
     error,
1316
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1317
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1318
     "%s: unable to set track offsets read in file IO handle.",
1319
     function );
1320
1321
    goto on_error;
1322
  }
1323
#endif
1324
0
  if( libbfio_file_set_name(
1325
0
       file_io_handle,
1326
0
       filename,
1327
0
       narrow_string_length(
1328
0
        filename ) + 1,
1329
0
       error ) != 1 )
1330
0
  {
1331
0
    libcerror_error_set(
1332
0
     error,
1333
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1334
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1335
0
     "%s: unable to set filename in file IO handle.",
1336
0
     function );
1337
1338
0
    goto on_error;
1339
0
  }
1340
0
  if( libodraw_handle_open_data_file_io_handle(
1341
0
       internal_handle,
1342
0
       data_file_index,
1343
0
       file_io_handle,
1344
0
       error ) != 1 )
1345
0
  {
1346
0
    libcerror_error_set(
1347
0
     error,
1348
0
     LIBCERROR_ERROR_DOMAIN_IO,
1349
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
1350
0
     "%s: unable to open data file: %s.",
1351
0
     function,
1352
0
     filename );
1353
1354
0
    goto on_error;
1355
0
  }
1356
0
  return( 1 );
1357
1358
0
on_error:
1359
0
  if( file_io_handle != NULL )
1360
0
  {
1361
0
    libbfio_handle_free(
1362
0
     &file_io_handle,
1363
0
     NULL );
1364
0
  }
1365
0
  return( -1 );
1366
0
}
1367
1368
#if defined( HAVE_WIDE_CHARACTER_TYPE )
1369
1370
/* Opens a specific data file
1371
 * Returns 1 if successful or -1 on error
1372
 */
1373
int libodraw_handle_open_data_file_wide(
1374
     libodraw_internal_handle_t *internal_handle,
1375
     int data_file_index,
1376
     const wchar_t *filename,
1377
     libcerror_error_t **error )
1378
{
1379
  libbfio_handle_t *file_io_handle = NULL;
1380
  static char *function            = "libodraw_handle_open_data_file_wide";
1381
1382
  if( internal_handle == NULL )
1383
  {
1384
    libcerror_error_set(
1385
     error,
1386
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1387
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1388
     "%s: invalid handle.",
1389
     function );
1390
1391
    return( -1 );
1392
  }
1393
  if( internal_handle->toc_file_io_handle == NULL )
1394
  {
1395
    libcerror_error_set(
1396
     error,
1397
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1398
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1399
     "%s: invalid handle - missing TOC file IO handle.",
1400
     function );
1401
1402
    return( -1 );
1403
  }
1404
  if( filename == NULL )
1405
  {
1406
    libcerror_error_set(
1407
     error,
1408
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1409
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1410
     "%s: invalid filename.",
1411
     function );
1412
1413
    return( -1 );
1414
  }
1415
  if( libbfio_file_initialize(
1416
       &file_io_handle,
1417
       error ) != 1 )
1418
  {
1419
    libcerror_error_set(
1420
     error,
1421
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1422
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1423
     "%s: unable to create file IO handle.",
1424
     function );
1425
1426
    goto on_error;
1427
  }
1428
#if defined( HAVE_DEBUG_OUTPUT )
1429
  if( libbfio_handle_set_track_offsets_read(
1430
       file_io_handle,
1431
       1,
1432
       error ) != 1 )
1433
  {
1434
    libcerror_error_set(
1435
     error,
1436
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1437
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1438
     "%s: unable to set track offsets read in file IO handle.",
1439
     function );
1440
1441
    goto on_error;
1442
  }
1443
#endif
1444
  if( libbfio_file_set_name_wide(
1445
       file_io_handle,
1446
       filename,
1447
       wide_string_length(
1448
        filename ) + 1,
1449
       error ) != 1 )
1450
  {
1451
    libcerror_error_set(
1452
     error,
1453
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1454
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1455
     "%s: unable to set filename in file IO handle.",
1456
     function );
1457
1458
    goto on_error;
1459
  }
1460
  if( libodraw_handle_open_data_file_io_handle(
1461
       internal_handle,
1462
       data_file_index,
1463
       file_io_handle,
1464
       error ) != 1 )
1465
  {
1466
    libcerror_error_set(
1467
     error,
1468
     LIBCERROR_ERROR_DOMAIN_IO,
1469
     LIBCERROR_IO_ERROR_OPEN_FAILED,
1470
     "%s: unable to open data file: %ls.",
1471
     function,
1472
     filename );
1473
1474
    goto on_error;
1475
  }
1476
  return( 1 );
1477
1478
on_error:
1479
  if( file_io_handle != NULL )
1480
  {
1481
    libbfio_handle_free(
1482
     &file_io_handle,
1483
     NULL );
1484
  }
1485
  return( -1 );
1486
}
1487
1488
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
1489
1490
/* Opens a data file using a Basic File IO (bfio) handle
1491
 * Returns 1 if successful or -1 on error
1492
 */
1493
int libodraw_handle_open_data_file_io_handle(
1494
     libodraw_internal_handle_t *internal_handle,
1495
     int data_file_index,
1496
     libbfio_handle_t *file_io_handle,
1497
     libcerror_error_t **error )
1498
0
{
1499
0
  static char *function               = "libodraw_handle_open_data_file_io_handle";
1500
0
  int bfio_access_flags               = 0;
1501
0
  int number_of_data_file_descriptors = 0;
1502
1503
0
  if( internal_handle == NULL )
1504
0
  {
1505
0
    libcerror_error_set(
1506
0
     error,
1507
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1508
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1509
0
     "%s: invalid handle.",
1510
0
     function );
1511
1512
0
    return( -1 );
1513
0
  }
1514
0
  if( internal_handle->toc_file_io_handle == NULL )
1515
0
  {
1516
0
    libcerror_error_set(
1517
0
     error,
1518
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1519
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1520
0
     "%s: invalid handle - missing TOC file IO handle.",
1521
0
     function );
1522
1523
0
    return( -1 );
1524
0
  }
1525
0
  if( file_io_handle == NULL )
1526
0
  {
1527
0
    libcerror_error_set(
1528
0
     error,
1529
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1530
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1531
0
     "%s: invalid file IO handle.",
1532
0
     function );
1533
1534
0
    return( -1 );
1535
0
  }
1536
0
  if( ( ( internal_handle->access_flags & LIBODRAW_ACCESS_FLAG_READ ) == 0 )
1537
0
   && ( ( internal_handle->access_flags & LIBODRAW_ACCESS_FLAG_WRITE ) == 0 ) )
1538
0
  {
1539
0
    libcerror_error_set(
1540
0
     error,
1541
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1542
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1543
0
     "%s: unsupported access flags.",
1544
0
     function );
1545
1546
0
    return( -1 );
1547
0
  }
1548
0
  if( ( internal_handle->access_flags & LIBODRAW_ACCESS_FLAG_WRITE ) != 0 )
1549
0
  {
1550
0
    libcerror_error_set(
1551
0
     error,
1552
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1553
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1554
0
     "%s: write access currently not supported.",
1555
0
     function );
1556
1557
0
    return( -1 );
1558
0
  }
1559
0
  if( internal_handle->data_file_io_pool == NULL )
1560
0
  {
1561
0
    if( libcdata_array_get_number_of_entries(
1562
0
         internal_handle->data_file_descriptors_array,
1563
0
         &number_of_data_file_descriptors,
1564
0
         error ) != 1 )
1565
0
    {
1566
0
      libcerror_error_set(
1567
0
       error,
1568
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1569
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1570
0
       "%s: unable to retrieve number of data file descriptors.",
1571
0
       function );
1572
1573
0
      return( -1 );
1574
0
    }
1575
0
    if( libbfio_pool_initialize(
1576
0
         &( internal_handle->data_file_io_pool ),
1577
0
         number_of_data_file_descriptors,
1578
0
         internal_handle->maximum_number_of_open_handles,
1579
0
         error ) != 1 )
1580
0
    {
1581
0
      libcerror_error_set(
1582
0
       error,
1583
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1584
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1585
0
       "%s: unable to create data file file IO pool.",
1586
0
       function );
1587
1588
0
      return( -1 );
1589
0
    }
1590
0
    internal_handle->data_file_io_pool_created_in_library = 1;
1591
0
  }
1592
0
  if( ( internal_handle->access_flags & LIBODRAW_ACCESS_FLAG_READ ) != 0 )
1593
0
  {
1594
0
    bfio_access_flags = LIBBFIO_ACCESS_FLAG_READ;
1595
0
  }
1596
0
  if( libbfio_handle_open(
1597
0
       file_io_handle,
1598
0
       bfio_access_flags,
1599
0
       error ) != 1 )
1600
0
  {
1601
0
    libcerror_error_set(
1602
0
     error,
1603
0
     LIBCERROR_ERROR_DOMAIN_IO,
1604
0
     LIBCERROR_IO_ERROR_OPEN_FAILED,
1605
0
     "%s: unable to open file IO handle.",
1606
0
     function );
1607
1608
0
    return( -1 );
1609
0
  }
1610
  /* This function currently does not allow the file_io_handle to be set more than once
1611
   */
1612
0
  if( libbfio_pool_set_handle(
1613
0
       internal_handle->data_file_io_pool,
1614
0
       data_file_index,
1615
0
       file_io_handle,
1616
0
       bfio_access_flags,
1617
0
       error ) != 1 )
1618
0
  {
1619
0
    libcerror_error_set(
1620
0
     error,
1621
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1622
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1623
0
     "%s: unable to set file IO handle: %d in pool.",
1624
0
     function,
1625
0
     data_file_index );
1626
1627
0
    return( -1 );
1628
0
  }
1629
0
  return( 1 );
1630
0
}
1631
1632
/* Closes a handle
1633
 * Returns 0 if successful or -1 on error
1634
 */
1635
int libodraw_handle_close(
1636
     libodraw_handle_t *handle,
1637
     libcerror_error_t **error )
1638
765
{
1639
765
  libodraw_internal_handle_t *internal_handle = NULL;
1640
765
  static char *function                       = "libodraw_handle_close";
1641
765
  int result                                  = 0;
1642
1643
765
  if( handle == NULL )
1644
0
  {
1645
0
    libcerror_error_set(
1646
0
     error,
1647
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1648
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1649
0
     "%s: invalid handle.",
1650
0
     function );
1651
1652
0
    return( -1 );
1653
0
  }
1654
765
  internal_handle = (libodraw_internal_handle_t *) handle;
1655
1656
765
  if( internal_handle->toc_file_io_handle == NULL )
1657
0
  {
1658
0
    libcerror_error_set(
1659
0
     error,
1660
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1661
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1662
0
     "%s: invalid handle - missing TOC file IO handle.",
1663
0
     function );
1664
1665
0
    return( -1 );
1666
0
  }
1667
#if defined( HAVE_DEBUG_OUTPUT )
1668
  if( libcnotify_verbose != 0 )
1669
  {
1670
    if( internal_handle->toc_file_io_handle_created_in_library != 0 )
1671
    {
1672
      if( libodraw_debug_print_read_offsets(
1673
           internal_handle->toc_file_io_handle,
1674
           error ) != 1 )
1675
      {
1676
        libcerror_error_set(
1677
         error,
1678
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1679
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1680
         "%s: unable to print the read offsets.",
1681
         function );
1682
1683
        result = -1;
1684
      }
1685
    }
1686
  }
1687
#endif
1688
765
  if( internal_handle->toc_file_io_handle_opened_in_library != 0 )
1689
765
  {
1690
765
    if( libbfio_handle_close(
1691
765
         internal_handle->toc_file_io_handle,
1692
765
         error ) != 0 )
1693
0
    {
1694
0
      libcerror_error_set(
1695
0
       error,
1696
0
       LIBCERROR_ERROR_DOMAIN_IO,
1697
0
       LIBCERROR_IO_ERROR_CLOSE_FAILED,
1698
0
       "%s: unable to close TOC file IO handle.",
1699
0
       function );
1700
1701
0
      result = -1;
1702
0
    }
1703
765
    internal_handle->toc_file_io_handle_opened_in_library = 0;
1704
765
  }
1705
765
  if( internal_handle->toc_file_io_handle_created_in_library != 0 )
1706
0
  {
1707
0
    if( libbfio_handle_free(
1708
0
         &( internal_handle->toc_file_io_handle ),
1709
0
         error ) != 1 )
1710
0
    {
1711
0
      libcerror_error_set(
1712
0
       error,
1713
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1714
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1715
0
       "%s: unable to free TOC file IO handle.",
1716
0
       function );
1717
1718
0
      result = -1;
1719
0
    }
1720
0
    internal_handle->toc_file_io_handle_created_in_library = 0;
1721
0
  }
1722
765
  internal_handle->toc_file_io_handle = NULL;
1723
1724
765
  if( internal_handle->data_file_io_pool != 0 )
1725
0
  {
1726
0
    if( internal_handle->data_file_io_pool != NULL )
1727
0
    {
1728
0
      if( libbfio_pool_close_all(
1729
0
           internal_handle->data_file_io_pool,
1730
0
           error ) != 0 )
1731
0
      {
1732
0
        libcerror_error_set(
1733
0
         error,
1734
0
         LIBCERROR_ERROR_DOMAIN_IO,
1735
0
         LIBCERROR_IO_ERROR_GENERIC,
1736
0
         "%s: unable close data files IO pool.",
1737
0
         function );
1738
1739
0
        result = -1;
1740
0
      }
1741
0
      if( libbfio_pool_free(
1742
0
           &( internal_handle->data_file_io_pool ),
1743
0
           error ) != 1 )
1744
0
      {
1745
0
        libcerror_error_set(
1746
0
         error,
1747
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1748
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1749
0
         "%s: unable to free data files IO pool.",
1750
0
         function );
1751
1752
0
        result = -1;
1753
0
      }
1754
0
    }
1755
0
    internal_handle->data_file_io_pool_created_in_library = 0;
1756
0
  }
1757
765
  internal_handle->data_file_io_pool = NULL;
1758
1759
765
  internal_handle->current_offset    = 0;
1760
765
  internal_handle->current_run_out   = 0;
1761
765
  internal_handle->current_lead_out  = 0;
1762
765
  internal_handle->current_track     = 0;
1763
765
  internal_handle->media_size        = 0;
1764
765
  internal_handle->number_of_sectors = 0;
1765
1766
765
  if( libodraw_io_handle_clear(
1767
765
       internal_handle->io_handle,
1768
765
       error ) != 1 )
1769
0
  {
1770
0
    libcerror_error_set(
1771
0
     error,
1772
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1773
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1774
0
     "%s: unable to clear IO handle.",
1775
0
     function );
1776
1777
0
    result = -1;
1778
0
  }
1779
765
  if( libcdata_array_empty(
1780
765
       internal_handle->data_file_descriptors_array,
1781
765
       (int (*)(intptr_t **, libcerror_error_t **)) &libodraw_data_file_descriptor_free,
1782
765
       error ) != 1 )
1783
0
  {
1784
0
    libcerror_error_set(
1785
0
     error,
1786
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1787
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1788
0
     "%s: unable to empty data file descriptors array.",
1789
0
     function );
1790
1791
0
    result = -1;
1792
0
  }
1793
765
  if( libcdata_array_empty(
1794
765
       internal_handle->sessions_array,
1795
765
       (int (*)(intptr_t **, libcerror_error_t **)) &libodraw_sector_range_free,
1796
765
       error ) != 1 )
1797
0
  {
1798
0
    libcerror_error_set(
1799
0
     error,
1800
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1801
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1802
0
     "%s: unable to empty sessions array.",
1803
0
     function );
1804
1805
0
    result = -1;
1806
0
  }
1807
765
  if( libcdata_array_empty(
1808
765
       internal_handle->run_outs_array,
1809
765
       (int (*)(intptr_t **, libcerror_error_t **)) &libodraw_sector_range_free,
1810
765
       error ) != 1 )
1811
0
  {
1812
0
    libcerror_error_set(
1813
0
     error,
1814
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1815
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1816
0
     "%s: unable to empty run-outs array.",
1817
0
     function );
1818
1819
0
    result = -1;
1820
0
  }
1821
765
  if( libcdata_array_empty(
1822
765
       internal_handle->lead_outs_array,
1823
765
       (int (*)(intptr_t **, libcerror_error_t **)) &libodraw_sector_range_free,
1824
765
       error ) != 1 )
1825
0
  {
1826
0
    libcerror_error_set(
1827
0
     error,
1828
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1829
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1830
0
     "%s: unable to empty lead-outs array.",
1831
0
     function );
1832
1833
0
    result = -1;
1834
0
  }
1835
765
  if( libcdata_array_empty(
1836
765
       internal_handle->tracks_array,
1837
765
       (int (*)(intptr_t **, libcerror_error_t **)) &libodraw_track_value_free,
1838
765
       error ) != 1 )
1839
0
  {
1840
0
    libcerror_error_set(
1841
0
     error,
1842
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1843
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1844
0
     "%s: unable to empty tracks array.",
1845
0
     function );
1846
1847
0
    result = -1;
1848
0
  }
1849
765
  if( internal_handle->basename != NULL )
1850
0
  {
1851
0
    memory_free(
1852
0
     internal_handle->basename );
1853
1854
0
    internal_handle->basename = NULL;
1855
0
  }
1856
765
  internal_handle->basename_size = 0;
1857
1858
765
  return( result );
1859
765
}
1860
1861
/* Opens a handle for reading
1862
 * Returns 1 if successful or -1 on error
1863
 */
1864
int libodraw_handle_open_read(
1865
     libodraw_internal_handle_t *internal_handle,
1866
     libbfio_handle_t *file_io_handle,
1867
     libcerror_error_t **error )
1868
1.51k
{
1869
1.51k
  uint8_t *buffer       = NULL;
1870
1.51k
  static char *function = "libodraw_handle_open_read";
1871
1.51k
  size64_t file_size    = 0;
1872
1.51k
  size_t buffer_size    = 0;
1873
1.51k
  ssize_t read_count    = 0;
1874
1.51k
  int result            = 1;
1875
1876
1.51k
  if( internal_handle == NULL )
1877
0
  {
1878
0
    libcerror_error_set(
1879
0
     error,
1880
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1881
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1882
0
     "%s: invalid handle.",
1883
0
     function );
1884
1885
0
    return( -1 );
1886
0
  }
1887
1.51k
  if( internal_handle->io_handle == NULL )
1888
0
  {
1889
0
    libcerror_error_set(
1890
0
     error,
1891
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1892
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1893
0
     "%s: invalid handle - missing IO handle.",
1894
0
     function );
1895
1896
0
    return( -1 );
1897
0
  }
1898
1.51k
  if( libcdata_array_empty(
1899
1.51k
       internal_handle->data_file_descriptors_array,
1900
1.51k
       (int (*)(intptr_t **, libcerror_error_t **)) &libodraw_track_value_free,
1901
1.51k
       error ) != 1 )
1902
0
  {
1903
0
    libcerror_error_set(
1904
0
     error,
1905
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1906
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1907
0
     "%s: unable to empty data file descriptors array.",
1908
0
     function );
1909
1910
0
    goto on_error;
1911
0
  }
1912
1.51k
  if( libcdata_array_empty(
1913
1.51k
       internal_handle->sessions_array,
1914
1.51k
       (int (*)(intptr_t **, libcerror_error_t **)) &libodraw_sector_range_free,
1915
1.51k
       error ) != 1 )
1916
0
  {
1917
0
    libcerror_error_set(
1918
0
     error,
1919
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1920
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1921
0
     "%s: unable to empty sessions array.",
1922
0
     function );
1923
1924
0
    goto on_error;
1925
0
  }
1926
1.51k
  if( libcdata_array_empty(
1927
1.51k
       internal_handle->run_outs_array,
1928
1.51k
       (int (*)(intptr_t **, libcerror_error_t **)) &libodraw_sector_range_free,
1929
1.51k
       error ) != 1 )
1930
0
  {
1931
0
    libcerror_error_set(
1932
0
     error,
1933
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1934
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1935
0
     "%s: unable to empty run-outs array.",
1936
0
     function );
1937
1938
0
    goto on_error;
1939
0
  }
1940
1.51k
  if( libcdata_array_empty(
1941
1.51k
       internal_handle->lead_outs_array,
1942
1.51k
       (int (*)(intptr_t **, libcerror_error_t **)) &libodraw_sector_range_free,
1943
1.51k
       error ) != 1 )
1944
0
  {
1945
0
    libcerror_error_set(
1946
0
     error,
1947
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1948
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1949
0
     "%s: unable to empty lead-outs array.",
1950
0
     function );
1951
1952
0
    goto on_error;
1953
0
  }
1954
1.51k
  if( libcdata_array_empty(
1955
1.51k
       internal_handle->tracks_array,
1956
1.51k
       (int (*)(intptr_t **, libcerror_error_t **)) &libodraw_track_value_free,
1957
1.51k
       error ) != 1 )
1958
0
  {
1959
0
    libcerror_error_set(
1960
0
     error,
1961
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1962
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1963
0
     "%s: unable to empty tracks array.",
1964
0
     function );
1965
1966
0
    goto on_error;
1967
0
  }
1968
1.51k
  if( internal_handle->io_handle->abort != 0 )
1969
0
  {
1970
0
    internal_handle->io_handle->abort = 0;
1971
0
  }
1972
#if defined( HAVE_DEBUG_OUTPUT )
1973
  if( libcnotify_verbose != 0 )
1974
  {
1975
    libcnotify_printf(
1976
     "Reading file:\n" );
1977
  }
1978
#endif
1979
1.51k
  if( libbfio_handle_get_size(
1980
1.51k
       file_io_handle,
1981
1.51k
       &file_size,
1982
1.51k
       error ) != 1 )
1983
0
  {
1984
0
    libcerror_error_set(
1985
0
     error,
1986
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1987
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1988
0
     "%s: unable to retrieve TOC file size.",
1989
0
     function );
1990
1991
0
    goto on_error;
1992
0
  }
1993
1.51k
  if( file_size > (size64_t) SSIZE_MAX )
1994
0
  {
1995
0
    libcerror_error_set(
1996
0
     error,
1997
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1998
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
1999
0
     "%s: invalid file size value exceeds maximum.",
2000
0
     function );
2001
2002
0
    goto on_error;
2003
0
  }
2004
  /* Lex wants 2 zero bytes at the end of the buffer
2005
   */
2006
1.51k
  buffer_size = (size_t) file_size + 2;
2007
2008
1.51k
  buffer = (uint8_t *) memory_allocate(
2009
1.51k
                        sizeof( uint8_t ) * buffer_size );
2010
2011
1.51k
  if( buffer == NULL )
2012
0
  {
2013
0
    libcerror_error_set(
2014
0
     error,
2015
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2016
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
2017
0
     "%s: unable to create buffer.",
2018
0
     function );
2019
2020
0
    goto on_error;
2021
0
  }
2022
#if defined( HAVE_DEBUG_OUTPUT )
2023
  if( libcnotify_verbose != 0 )
2024
  {
2025
    libcnotify_printf(
2026
     "%s: reading TOC file header at offset: 0 (0x00000000)\n",
2027
     function );
2028
  }
2029
#endif
2030
1.51k
  read_count = libbfio_handle_read_buffer_at_offset(
2031
1.51k
                file_io_handle,
2032
1.51k
                buffer,
2033
1.51k
                (size_t) file_size,
2034
1.51k
                0,
2035
1.51k
                error );
2036
2037
1.51k
  if( read_count != (ssize_t) file_size )
2038
0
  {
2039
0
    libcerror_error_set(
2040
0
     error,
2041
0
     LIBCERROR_ERROR_DOMAIN_IO,
2042
0
     LIBCERROR_IO_ERROR_READ_FAILED,
2043
0
     "%s: unable to read TOC file data at offset: 0 (0x00000000).",
2044
0
     function );
2045
2046
0
    goto on_error;
2047
0
  }
2048
#if defined( HAVE_DEBUG_OUTPUT )
2049
  if( libcnotify_verbose != 0 )
2050
  {
2051
    libcnotify_printf(
2052
     "%s: file data:\n",
2053
     function );
2054
    libcnotify_print_data(
2055
     buffer,
2056
     (size_t) file_size,
2057
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
2058
  }
2059
#endif
2060
  /* Lex wants 2 zero bytes at the end of the buffer
2061
   */
2062
1.51k
  buffer[ buffer_size - 2 ] = 0;
2063
1.51k
  buffer[ buffer_size - 1 ] = 0;
2064
2065
1.51k
  result = libodraw_cue_parser_parse_buffer(
2066
1.51k
            (libodraw_handle_t *) internal_handle,
2067
1.51k
            buffer,
2068
1.51k
            buffer_size,
2069
1.51k
            error );
2070
2071
1.51k
  if( result == -1 )
2072
751
  {
2073
751
    libcerror_error_set(
2074
751
     error,
2075
751
     LIBCERROR_ERROR_DOMAIN_IO,
2076
751
     LIBCERROR_IO_ERROR_READ_FAILED,
2077
751
     "%s: unable to parse file data.",
2078
751
     function );
2079
2080
751
    goto on_error;
2081
751
  }
2082
765
  memory_free(
2083
765
   buffer );
2084
2085
765
  buffer = NULL;
2086
2087
765
  if( internal_handle->io_handle->abort != 0 )
2088
0
  {
2089
0
    internal_handle->io_handle->abort = 0;
2090
0
  }
2091
765
  return( result );
2092
2093
751
on_error:
2094
751
  if( buffer != NULL )
2095
751
  {
2096
751
    memory_free(
2097
751
     buffer );
2098
751
  }
2099
751
  return( -1 );
2100
1.51k
}
2101
2102
/* Reads a buffer
2103
 * Returns the number of bytes read or -1 on error
2104
 */
2105
ssize_t libodraw_handle_read_buffer(
2106
         libodraw_handle_t *handle,
2107
         void *buffer,
2108
         size_t buffer_size,
2109
         libcerror_error_t **error )
2110
0
{
2111
0
  libodraw_internal_handle_t *internal_handle = NULL;
2112
0
  libodraw_sector_range_t *sector_range       = NULL;
2113
0
  libodraw_track_value_t *track_value         = NULL;
2114
0
  static char *function                       = "libodraw_handle_read_buffer";
2115
0
  size_t buffer_offset                        = 0;
2116
0
  ssize_t read_count                          = 0;
2117
0
  uint64_t current_sector                     = 0;
2118
0
  int in_known_range                          = 0;
2119
0
  int number_of_lead_outs                     = 0;
2120
0
  int number_of_run_outs                      = 0;
2121
2122
0
  if( handle == NULL )
2123
0
  {
2124
0
    libcerror_error_set(
2125
0
     error,
2126
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2127
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2128
0
     "%s: invalid handle.",
2129
0
     function );
2130
2131
0
    return( -1 );
2132
0
  }
2133
0
  internal_handle = (libodraw_internal_handle_t *) handle;
2134
2135
0
  if( internal_handle->io_handle == NULL )
2136
0
  {
2137
0
    libcerror_error_set(
2138
0
     error,
2139
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2140
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2141
0
     "%s: invalid handle - missing IO handle.",
2142
0
     function );
2143
2144
0
    return( -1 );
2145
0
  }
2146
0
  if( internal_handle->io_handle->bytes_per_sector == 0 )
2147
0
  {
2148
0
    libcerror_error_set(
2149
0
     error,
2150
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2151
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2152
0
     "%s: invalid handle - invalid IO handle - missing bytes per sector.",
2153
0
     function );
2154
2155
0
    return( -1 );
2156
0
  }
2157
0
  if( internal_handle->current_offset < 0 )
2158
0
  {
2159
0
    libcerror_error_set(
2160
0
     error,
2161
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2162
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2163
0
     "%s: invalid handle - invalid IO handle - current offset value out of bounds.",
2164
0
     function );
2165
2166
0
    return( -1 );
2167
0
  }
2168
0
  if( libcdata_array_get_number_of_entries(
2169
0
       internal_handle->run_outs_array,
2170
0
       &number_of_run_outs,
2171
0
       error ) != 1 )
2172
0
  {
2173
0
    libcerror_error_set(
2174
0
     error,
2175
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2176
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2177
0
     "%s: unable to retrieve number of elements in run-outs array.",
2178
0
     function );
2179
2180
0
    return( -1 );
2181
0
  }
2182
0
  if( libcdata_array_get_number_of_entries(
2183
0
       internal_handle->lead_outs_array,
2184
0
       &number_of_lead_outs,
2185
0
       error ) != 1 )
2186
0
  {
2187
0
    libcerror_error_set(
2188
0
     error,
2189
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2190
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2191
0
     "%s: unable to retrieve number of elements in lead-outs array.",
2192
0
     function );
2193
2194
0
    return( -1 );
2195
0
  }
2196
0
  if( (size64_t) internal_handle->current_offset >= internal_handle->media_size )
2197
0
  {
2198
0
    return( 0 );
2199
0
  }
2200
0
  current_sector = (uint64_t) ( internal_handle->current_offset / internal_handle->io_handle->bytes_per_sector );
2201
2202
0
  if( current_sector > (uint64_t) UINT32_MAX )
2203
0
  {
2204
0
    libcerror_error_set(
2205
0
     error,
2206
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2207
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2208
0
     "%s: current sector value out of bounds.",
2209
0
     function );
2210
2211
0
    return( -1 );
2212
0
  }
2213
0
  while( buffer_offset < buffer_size )
2214
0
  {
2215
0
    in_known_range = 0;
2216
2217
0
    if( libcdata_array_get_entry_by_index(
2218
0
         internal_handle->tracks_array,
2219
0
         internal_handle->current_track,
2220
0
         (intptr_t **) &track_value,
2221
0
         error ) != 1 )
2222
0
    {
2223
0
      libcerror_error_set(
2224
0
       error,
2225
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2226
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2227
0
       "%s: unable to retrieve track value: %d from array.",
2228
0
       function,
2229
0
       internal_handle->current_track );
2230
2231
0
      return( -1 );
2232
0
    }
2233
0
    if( track_value == NULL )
2234
0
    {
2235
0
      libcerror_error_set(
2236
0
       error,
2237
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2238
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2239
0
       "%s: missing track value: %d.",
2240
0
       function,
2241
0
       internal_handle->current_track );
2242
2243
0
      return( -1 );
2244
0
    }
2245
    /* TODO currently assumes that current track start sector is always relative to the start of the media */
2246
0
    if( ( current_sector >= track_value->start_sector )
2247
0
     && ( current_sector < track_value->end_sector ) )
2248
0
    {
2249
0
      in_known_range = 1;
2250
2251
0
      read_count = libodraw_handle_read_buffer_from_track(
2252
0
                    internal_handle,
2253
0
                    (uint8_t *) &( ( (uint8_t *) buffer )[ buffer_offset ] ),
2254
0
                    buffer_size - buffer_offset,
2255
0
                    error );
2256
2257
0
      if( read_count == -1 )
2258
0
      {
2259
0
        libcerror_error_set(
2260
0
         error,
2261
0
         LIBCERROR_ERROR_DOMAIN_IO,
2262
0
         LIBCERROR_IO_ERROR_READ_FAILED,
2263
0
         "%s: unable to read buffer from track: %d.",
2264
0
         function,
2265
0
         internal_handle->current_track );
2266
2267
0
        return( -1 );
2268
0
      }
2269
0
      buffer_offset += read_count;
2270
2271
0
      internal_handle->current_offset += (off64_t) read_count;
2272
2273
0
      current_sector = (uint64_t) ( internal_handle->current_offset / internal_handle->io_handle->bytes_per_sector );
2274
2275
0
      if( current_sector > (uint64_t) UINT32_MAX )
2276
0
      {
2277
0
        libcerror_error_set(
2278
0
         error,
2279
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2280
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2281
0
         "%s: current sector value out of bounds.",
2282
0
         function );
2283
2284
0
        return( -1 );
2285
0
      }
2286
0
      if( current_sector >= track_value->end_sector )
2287
0
      {
2288
0
        internal_handle->current_track += 1;
2289
0
      }
2290
0
    }
2291
0
    if( buffer_offset >= buffer_size )
2292
0
    {
2293
0
      break;
2294
0
    }
2295
0
    if( (size64_t) internal_handle->current_offset >= internal_handle->media_size )
2296
0
    {
2297
0
      break;
2298
0
    }
2299
0
    if( internal_handle->current_run_out < number_of_run_outs )
2300
0
    {
2301
0
      if( libcdata_array_get_entry_by_index(
2302
0
           internal_handle->run_outs_array,
2303
0
           internal_handle->current_run_out,
2304
0
           (intptr_t **) &sector_range,
2305
0
           error ) != 1 )
2306
0
      {
2307
0
        libcerror_error_set(
2308
0
         error,
2309
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2310
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2311
0
         "%s: unable to retrieve run-out sector range: %d from array.",
2312
0
         function,
2313
0
         internal_handle->current_run_out );
2314
2315
0
        return( -1 );
2316
0
      }
2317
0
      if( sector_range == NULL )
2318
0
      {
2319
0
        libcerror_error_set(
2320
0
         error,
2321
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2322
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2323
0
         "%s: missing run-out sector range: %d.",
2324
0
         function,
2325
0
         internal_handle->current_run_out );
2326
2327
0
        return( -1 );
2328
0
      }
2329
      /* TODO currently assumes that current run-out start sector is always relative to the start of the media */
2330
0
      if( ( current_sector >= sector_range->start_sector )
2331
0
       && ( current_sector < sector_range->end_sector ) )
2332
0
      {
2333
0
        in_known_range = 1;
2334
2335
0
        read_count = libodraw_handle_read_buffer_from_run_out(
2336
0
                internal_handle,
2337
0
                (uint8_t *) &( ( (uint8_t *) buffer )[ buffer_offset ] ),
2338
0
                buffer_size - buffer_offset,
2339
0
                error );
2340
2341
0
        if( read_count == -1 )
2342
0
        {
2343
0
          libcerror_error_set(
2344
0
           error,
2345
0
           LIBCERROR_ERROR_DOMAIN_IO,
2346
0
           LIBCERROR_IO_ERROR_READ_FAILED,
2347
0
           "%s: unable to read buffer from run-out: %d.",
2348
0
           function,
2349
0
           internal_handle->current_run_out );
2350
2351
0
          return( -1 );
2352
0
        }
2353
0
        buffer_offset += read_count;
2354
2355
0
        internal_handle->current_offset += (off64_t) read_count;
2356
2357
0
        current_sector = (uint64_t) ( internal_handle->current_offset / internal_handle->io_handle->bytes_per_sector );
2358
2359
0
        if( current_sector > (uint64_t) UINT32_MAX )
2360
0
        {
2361
0
          libcerror_error_set(
2362
0
           error,
2363
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2364
0
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2365
0
           "%s: current sector value out of bounds.",
2366
0
           function );
2367
2368
0
          return( -1 );
2369
0
        }
2370
0
        if( current_sector >= sector_range->end_sector )
2371
0
        {
2372
0
          internal_handle->current_run_out += 1;
2373
0
        }
2374
0
      }
2375
0
      if( buffer_offset >= buffer_size )
2376
0
      {
2377
0
        break;
2378
0
      }
2379
0
      if( (size64_t) internal_handle->current_offset >= internal_handle->media_size )
2380
0
      {
2381
0
        break;
2382
0
      }
2383
0
    }
2384
0
    if( internal_handle->current_lead_out < number_of_lead_outs )
2385
0
    {
2386
0
      if( libcdata_array_get_entry_by_index(
2387
0
           internal_handle->lead_outs_array,
2388
0
           internal_handle->current_lead_out,
2389
0
           (intptr_t **) &sector_range,
2390
0
           error ) != 1 )
2391
0
      {
2392
0
        libcerror_error_set(
2393
0
         error,
2394
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2395
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2396
0
         "%s: unable to retrieve lead-out sector range: %d from array.",
2397
0
         function,
2398
0
         internal_handle->current_lead_out );
2399
2400
0
        return( -1 );
2401
0
      }
2402
0
      if( sector_range == NULL )
2403
0
      {
2404
0
        libcerror_error_set(
2405
0
         error,
2406
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2407
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2408
0
         "%s: missing lead-out sector range: %d.",
2409
0
         function,
2410
0
         internal_handle->current_lead_out );
2411
2412
0
        return( -1 );
2413
0
      }
2414
      /* TODO currently assumes that current lead-out start sector is always relative to the start of the media */
2415
0
      if( ( current_sector >= sector_range->start_sector )
2416
0
       && ( current_sector < sector_range->end_sector ) )
2417
0
      {
2418
0
        in_known_range = 1;
2419
2420
0
        read_count = libodraw_handle_read_buffer_from_lead_out(
2421
0
                internal_handle,
2422
0
                (uint8_t *) &( ( (uint8_t *) buffer )[ buffer_offset ] ),
2423
0
                buffer_size - buffer_offset,
2424
0
                error );
2425
2426
0
        if( read_count == -1 )
2427
0
        {
2428
0
          libcerror_error_set(
2429
0
           error,
2430
0
           LIBCERROR_ERROR_DOMAIN_IO,
2431
0
           LIBCERROR_IO_ERROR_READ_FAILED,
2432
0
           "%s: unable to read buffer from lead-out: %d.",
2433
0
           function,
2434
0
           internal_handle->current_lead_out );
2435
2436
0
          return( -1 );
2437
0
        }
2438
0
        buffer_offset += read_count;
2439
2440
0
        internal_handle->current_offset += (off64_t) read_count;
2441
2442
0
        current_sector = (uint64_t) ( internal_handle->current_offset / internal_handle->io_handle->bytes_per_sector );
2443
2444
0
        if( current_sector > (uint64_t) UINT32_MAX )
2445
0
        {
2446
0
          libcerror_error_set(
2447
0
           error,
2448
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
2449
0
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2450
0
           "%s: current sector value out of bounds.",
2451
0
           function );
2452
2453
0
          return( -1 );
2454
0
        }
2455
0
        if( current_sector >= sector_range->end_sector )
2456
0
        {
2457
0
          internal_handle->current_lead_out += 1;
2458
0
        }
2459
0
      }
2460
0
      if( buffer_offset >= buffer_size )
2461
0
      {
2462
0
        break;
2463
0
      }
2464
0
      if( (size64_t) internal_handle->current_offset >= internal_handle->media_size )
2465
0
      {
2466
0
        break;
2467
0
      }
2468
0
    }
2469
0
    if( in_known_range == 0 )
2470
0
    {
2471
0
      read_count = libodraw_handle_read_buffer_from_unspecified_sector(
2472
0
                    internal_handle,
2473
0
                    (uint8_t *) &( ( (uint8_t *) buffer )[ buffer_offset ] ),
2474
0
                    buffer_size - buffer_offset,
2475
0
                    error );
2476
2477
0
      if( read_count == -1 )
2478
0
      {
2479
0
        libcerror_error_set(
2480
0
         error,
2481
0
         LIBCERROR_ERROR_DOMAIN_IO,
2482
0
         LIBCERROR_IO_ERROR_READ_FAILED,
2483
0
         "%s: unable to read buffer from unspecified.",
2484
0
         function );
2485
2486
0
        return( -1 );
2487
0
      }
2488
0
      buffer_offset += read_count;
2489
2490
0
      internal_handle->current_offset += (off64_t) read_count;
2491
2492
0
      current_sector = (uint64_t) ( internal_handle->current_offset / internal_handle->io_handle->bytes_per_sector );
2493
2494
0
      if( current_sector > (uint64_t) UINT32_MAX )
2495
0
      {
2496
0
        libcerror_error_set(
2497
0
         error,
2498
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2499
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2500
0
         "%s: current sector value out of bounds.",
2501
0
         function );
2502
2503
0
        return( -1 );
2504
0
      }
2505
0
      if( current_sector >= track_value->end_sector )
2506
0
      {
2507
0
        internal_handle->current_track += 1;
2508
0
      }
2509
0
      if( buffer_offset >= buffer_size )
2510
0
      {
2511
0
        break;
2512
0
      }
2513
0
      if( (size64_t) internal_handle->current_offset >= internal_handle->media_size )
2514
0
      {
2515
0
        break;
2516
0
      }
2517
0
    }
2518
0
    if( internal_handle->io_handle->abort != 0 )
2519
0
    {
2520
0
      break;
2521
0
    }
2522
0
  }
2523
0
  return( (size_t) buffer_offset );
2524
0
}
2525
2526
/* Reads a buffer from run-out
2527
 * Returns the number of bytes read or -1 on error
2528
 */
2529
ssize_t libodraw_handle_read_buffer_from_run_out(
2530
         libodraw_internal_handle_t *internal_handle,
2531
         uint8_t *buffer,
2532
         size_t buffer_size,
2533
         libcerror_error_t **error )
2534
0
{
2535
0
  libodraw_track_value_t *track_value   = NULL;
2536
0
  libodraw_sector_range_t *sector_range = NULL;
2537
0
  uint8_t *read_buffer                  = NULL;
2538
0
  uint8_t *sector_data                  = NULL;
2539
0
  static char *function                 = "libodraw_handle_read_buffer_from_run_out";
2540
0
  off64_t current_sector_offset         = 0;
2541
0
  off64_t run_out_data_offset           = 0;
2542
0
  size64_t data_file_number_of_sectors  = 0;
2543
0
  size64_t data_file_size               = 0;
2544
0
  size64_t required_number_of_sectors   = 0;
2545
0
  uint64_t current_sector               = 0;
2546
0
  uint64_t run_out_data_start_sector    = 0;
2547
0
  size_t read_number_of_sectors         = 0;
2548
0
  size_t read_size                      = 0;
2549
0
  ssize_t read_count                    = 0;
2550
2551
0
  if( internal_handle == NULL )
2552
0
  {
2553
0
    libcerror_error_set(
2554
0
     error,
2555
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2556
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2557
0
     "%s: invalid handle.",
2558
0
     function );
2559
2560
0
    return( -1 );
2561
0
  }
2562
0
  if( internal_handle->io_handle == NULL )
2563
0
  {
2564
0
    libcerror_error_set(
2565
0
     error,
2566
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2567
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2568
0
     "%s: invalid handle - missing IO handle.",
2569
0
     function );
2570
2571
0
    return( -1 );
2572
0
  }
2573
0
  if( internal_handle->io_handle->bytes_per_sector == 0 )
2574
0
  {
2575
0
    libcerror_error_set(
2576
0
     error,
2577
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2578
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2579
0
     "%s: invalid handle - invalid IO handle - missing bytes per sector.",
2580
0
     function );
2581
2582
0
    return( -1 );
2583
0
  }
2584
0
  if( libcdata_array_get_entry_by_index(
2585
0
       internal_handle->run_outs_array,
2586
0
       internal_handle->current_run_out,
2587
0
       (intptr_t **) &sector_range,
2588
0
       error ) != 1 )
2589
0
  {
2590
0
    libcerror_error_set(
2591
0
     error,
2592
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2593
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2594
0
     "%s: unable to retrieve run-out sector range: %d from array.",
2595
0
     function,
2596
0
     internal_handle->current_run_out );
2597
2598
0
    goto on_error;
2599
0
  }
2600
0
  if( sector_range == NULL )
2601
0
  {
2602
0
    libcerror_error_set(
2603
0
     error,
2604
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2605
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2606
0
     "%s: missing run-out sector range: %d.",
2607
0
     function,
2608
0
     internal_handle->current_run_out );
2609
2610
0
    goto on_error;
2611
0
  }
2612
0
  current_sector = (uint64_t) ( internal_handle->current_offset / internal_handle->io_handle->bytes_per_sector );
2613
2614
0
  if( current_sector > (uint64_t) UINT32_MAX )
2615
0
  {
2616
0
    libcerror_error_set(
2617
0
     error,
2618
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2619
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2620
0
     "%s: current sector value out of bounds.",
2621
0
     function );
2622
2623
0
    return( -1 );
2624
0
  }
2625
  /* TODO currently assumes that current run-out start sector is always relative to the start of the media */
2626
0
  if( ( current_sector < sector_range->start_sector )
2627
0
   || ( current_sector >= sector_range->end_sector ) )
2628
0
  {
2629
0
    libcerror_error_set(
2630
0
     error,
2631
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2632
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2633
0
     "%s: current sector value out of bounds.",
2634
0
     function );
2635
2636
0
    goto on_error;
2637
0
  }
2638
#if defined( HAVE_DEBUG_OUTPUT )
2639
  if( libcnotify_verbose != 0 )
2640
  {
2641
    libcnotify_printf(
2642
     "%s: reading data from run-out: %d at sector(s): %" PRIu64 " - %" PRIu64 "\n",
2643
     function,
2644
     internal_handle->current_run_out,
2645
     sector_range->start_sector,
2646
     sector_range->end_sector );
2647
  }
2648
#endif
2649
  /* Retrieves the track that corresponds to the run-out
2650
   */
2651
0
  if( libcdata_array_get_entry_by_index(
2652
0
       internal_handle->tracks_array,
2653
0
       internal_handle->current_track - 1,
2654
0
       (intptr_t **) &track_value,
2655
0
       error ) != 1 )
2656
0
  {
2657
0
    libcerror_error_set(
2658
0
     error,
2659
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2660
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2661
0
     "%s: unable to retrieve track value: %d from array.",
2662
0
     function,
2663
0
     internal_handle->current_track - 1 );
2664
2665
0
    goto on_error;
2666
0
  }
2667
0
  if( track_value == NULL )
2668
0
  {
2669
0
    libcerror_error_set(
2670
0
     error,
2671
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2672
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2673
0
     "%s: missing track value: %d.",
2674
0
     function,
2675
0
     internal_handle->current_track - 1 );
2676
2677
0
    goto on_error;
2678
0
  }
2679
0
  if( track_value->end_sector != sector_range->start_sector )
2680
0
  {
2681
0
    libcerror_error_set(
2682
0
     error,
2683
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2684
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2685
0
     "%s: sector range start sector value out of bounds.",
2686
0
     function );
2687
2688
0
    goto on_error;
2689
0
  }
2690
0
  current_sector_offset = internal_handle->current_offset
2691
0
                        - (off64_t) ( current_sector * internal_handle->io_handle->bytes_per_sector );
2692
2693
0
  if( ( current_sector_offset < 0 )
2694
0
   || ( current_sector_offset >= internal_handle->io_handle->bytes_per_sector ) )
2695
0
  {
2696
0
    libcerror_error_set(
2697
0
     error,
2698
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2699
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2700
0
     "%s: invalid current sector offset value out of bounds.",
2701
0
     function );
2702
2703
0
    goto on_error;
2704
0
  }
2705
0
  read_number_of_sectors = buffer_size / internal_handle->io_handle->bytes_per_sector;
2706
2707
0
  if( ( buffer_size % internal_handle->io_handle->bytes_per_sector ) != 0 )
2708
0
  {
2709
0
    read_number_of_sectors += 1;
2710
0
  }
2711
0
  if( ( (uint64_t) read_number_of_sectors + current_sector ) > sector_range->end_sector )
2712
0
  {
2713
0
    read_number_of_sectors = (size_t) ( sector_range->end_sector - current_sector );
2714
0
  }
2715
0
  if( libbfio_pool_get_size(
2716
0
       internal_handle->data_file_io_pool,
2717
0
       track_value->data_file_index,
2718
0
       &data_file_size,
2719
0
       error ) != 1 )
2720
0
  {
2721
0
    libcerror_error_set(
2722
0
     error,
2723
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2724
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2725
0
     "%s: unable to retrieve data file: %d size.",
2726
0
     function,
2727
0
     track_value->data_file_index );
2728
2729
0
    goto on_error;
2730
0
  }
2731
0
  data_file_number_of_sectors = data_file_size / track_value->bytes_per_sector;
2732
2733
  /* Determine if the required number of sectors are available in the data file
2734
   */
2735
0
  required_number_of_sectors = track_value->data_file_start_sector
2736
0
                             + track_value->number_of_sectors
2737
0
                             + sector_range->number_of_sectors;
2738
2739
0
  if( required_number_of_sectors > data_file_number_of_sectors )
2740
0
  {
2741
0
    read_size = ( read_number_of_sectors * internal_handle->io_handle->bytes_per_sector )
2742
0
              - (size_t) current_sector_offset;
2743
2744
0
    if( read_size > buffer_size )
2745
0
    {
2746
0
      read_size = buffer_size;
2747
0
    }
2748
    /* Fill the buffer with 0 byte values if the run-out data is
2749
     * not available in the data file
2750
     */
2751
0
    if( memory_set(
2752
0
         buffer,
2753
0
         0,
2754
0
         read_size ) == NULL )
2755
0
    {
2756
0
      libcerror_error_set(
2757
0
       error,
2758
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
2759
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
2760
0
       "%s: unable to copy run-out data to buffer.",
2761
0
       function );
2762
2763
0
      goto on_error;
2764
0
    }
2765
0
    read_count = (ssize_t) read_size;
2766
0
  }
2767
0
  else
2768
0
  {
2769
0
    run_out_data_start_sector = current_sector
2770
0
                              - sector_range->start_sector
2771
0
                              + track_value->number_of_sectors;
2772
2773
0
    run_out_data_offset = track_value->data_file_offset
2774
0
                        + ( run_out_data_start_sector * track_value->bytes_per_sector );
2775
2776
0
    read_size = read_number_of_sectors * track_value->bytes_per_sector;
2777
2778
0
    if( track_value->bytes_per_sector != internal_handle->io_handle->bytes_per_sector )
2779
0
    {
2780
/* TODO use sector data cache ? */
2781
0
      sector_data = (uint8_t *) memory_allocate(
2782
0
                                 sizeof( uint8_t ) * read_size );
2783
2784
0
      if( sector_data == NULL )
2785
0
      {
2786
0
        libcerror_error_set(
2787
0
         error,
2788
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
2789
0
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
2790
0
         "%s: unable to create sector data.",
2791
0
         function );
2792
2793
0
        goto on_error;
2794
0
      }
2795
0
      read_buffer = sector_data;
2796
0
    }
2797
0
    else
2798
0
    {
2799
0
      read_buffer          = buffer;
2800
0
      read_size           -= (size_t) current_sector_offset;
2801
0
      run_out_data_offset += current_sector_offset;
2802
2803
0
      if( read_size > buffer_size )
2804
0
      {
2805
0
        read_size = buffer_size;
2806
0
      }
2807
0
    }
2808
0
    if( libbfio_pool_seek_offset(
2809
0
         internal_handle->data_file_io_pool,
2810
0
         track_value->data_file_index,
2811
0
         run_out_data_offset,
2812
0
         SEEK_SET,
2813
0
         error ) == -1 )
2814
0
    {
2815
0
      libcerror_error_set(
2816
0
       error,
2817
0
       LIBCERROR_ERROR_DOMAIN_IO,
2818
0
       LIBCERROR_IO_ERROR_SEEK_FAILED,
2819
0
       "%s: unable to seek data file: %d offset: %" PRIi64 ".",
2820
0
       function,
2821
0
       track_value->data_file_index,
2822
0
       run_out_data_offset );
2823
2824
0
      goto on_error;
2825
0
    }
2826
0
    read_count = libbfio_pool_read_buffer(
2827
0
            internal_handle->data_file_io_pool,
2828
0
            track_value->data_file_index,
2829
0
            read_buffer,
2830
0
            read_size,
2831
0
            error );
2832
2833
0
    if( read_count != (ssize_t) read_size )
2834
0
    {
2835
0
      libcerror_error_set(
2836
0
       error,
2837
0
       LIBCERROR_ERROR_DOMAIN_IO,
2838
0
       LIBCERROR_IO_ERROR_READ_FAILED,
2839
0
       "%s: unable to read buffer from data file: %d.",
2840
0
       function,
2841
0
       track_value->data_file_index );
2842
2843
0
      goto on_error;
2844
0
    }
2845
0
    if( track_value->bytes_per_sector != internal_handle->io_handle->bytes_per_sector )
2846
0
    {
2847
0
      read_count = libodraw_io_handle_copy_sector_data_to_buffer(
2848
0
              internal_handle->io_handle,
2849
0
              sector_data,
2850
0
              read_size,
2851
0
                    track_value->bytes_per_sector,
2852
0
              LIBODRAW_TRACK_TYPE_UNKNOWN,
2853
0
              buffer,
2854
0
              buffer_size,
2855
0
              (uint32_t) current_sector,
2856
0
              (uint32_t) current_sector_offset,
2857
0
              error );
2858
2859
0
      if( read_count < 0 )
2860
0
      {
2861
0
        libcerror_error_set(
2862
0
         error,
2863
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2864
0
         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2865
0
         "%s: unable to copy sector data to buffer.",
2866
0
         function );
2867
2868
0
        goto on_error;
2869
0
      }
2870
0
      memory_free(
2871
0
       sector_data );
2872
2873
0
      sector_data = NULL;
2874
0
    }
2875
0
  }
2876
0
  return( read_count );
2877
2878
0
on_error:
2879
0
  if( sector_data != NULL )
2880
0
  {
2881
0
    memory_free(
2882
0
     sector_data );
2883
0
  }
2884
0
  return( -1 );
2885
0
}
2886
2887
/* Reads a buffer from lead-out
2888
 * Returns the number of bytes read or -1 on error
2889
 */
2890
ssize_t libodraw_handle_read_buffer_from_lead_out(
2891
         libodraw_internal_handle_t *internal_handle,
2892
         uint8_t *buffer,
2893
         size_t buffer_size,
2894
         libcerror_error_t **error )
2895
0
{
2896
0
  libodraw_track_value_t *track_value   = NULL;
2897
0
  libodraw_sector_range_t *sector_range = NULL;
2898
0
  uint8_t *read_buffer                  = NULL;
2899
0
  uint8_t *sector_data                  = NULL;
2900
0
  static char *function                 = "libodraw_handle_read_buffer_from_lead_out";
2901
0
  off64_t current_sector_offset         = 0;
2902
0
  off64_t lead_out_data_offset          = 0;
2903
0
  size64_t data_file_number_of_sectors  = 0;
2904
0
  size64_t data_file_size               = 0;
2905
0
  size64_t required_number_of_sectors   = 0;
2906
0
  uint64_t current_sector               = 0;
2907
0
  uint64_t lead_out_data_start_sector   = 0;
2908
0
  size_t read_number_of_sectors         = 0;
2909
0
  size_t read_size                      = 0;
2910
0
  ssize_t read_count                    = 0;
2911
2912
0
  if( internal_handle == NULL )
2913
0
  {
2914
0
    libcerror_error_set(
2915
0
     error,
2916
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2917
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2918
0
     "%s: invalid handle.",
2919
0
     function );
2920
2921
0
    return( -1 );
2922
0
  }
2923
0
  if( internal_handle->io_handle == NULL )
2924
0
  {
2925
0
    libcerror_error_set(
2926
0
     error,
2927
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2928
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2929
0
     "%s: invalid handle - missing IO handle.",
2930
0
     function );
2931
2932
0
    return( -1 );
2933
0
  }
2934
0
  if( internal_handle->io_handle->bytes_per_sector == 0 )
2935
0
  {
2936
0
    libcerror_error_set(
2937
0
     error,
2938
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2939
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2940
0
     "%s: invalid handle - invalid IO handle - missing bytes per sector.",
2941
0
     function );
2942
2943
0
    return( -1 );
2944
0
  }
2945
0
  if( libcdata_array_get_entry_by_index(
2946
0
       internal_handle->lead_outs_array,
2947
0
       internal_handle->current_lead_out,
2948
0
       (intptr_t **) &sector_range,
2949
0
       error ) != 1 )
2950
0
  {
2951
0
    libcerror_error_set(
2952
0
     error,
2953
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2954
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2955
0
     "%s: unable to retrieve lead-out sector range: %d from array.",
2956
0
     function,
2957
0
     internal_handle->current_lead_out );
2958
2959
0
    goto on_error;
2960
0
  }
2961
0
  if( sector_range == NULL )
2962
0
  {
2963
0
    libcerror_error_set(
2964
0
     error,
2965
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2966
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2967
0
     "%s: missing lead-out sector range: %d.",
2968
0
     function,
2969
0
     internal_handle->current_lead_out );
2970
2971
0
    goto on_error;
2972
0
  }
2973
0
  current_sector = (uint64_t) ( internal_handle->current_offset / internal_handle->io_handle->bytes_per_sector );
2974
2975
0
  if( current_sector > (uint64_t) UINT32_MAX )
2976
0
  {
2977
0
    libcerror_error_set(
2978
0
     error,
2979
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2980
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2981
0
     "%s: current sector value out of bounds.",
2982
0
     function );
2983
2984
0
    return( -1 );
2985
0
  }
2986
  /* TODO currently assumes that current lead-out start sector is always relative to the start of the media */
2987
0
  if( ( current_sector < sector_range->start_sector )
2988
0
   || ( current_sector >= sector_range->end_sector ) )
2989
0
  {
2990
0
    libcerror_error_set(
2991
0
     error,
2992
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2993
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2994
0
     "%s: current sector value out of bounds.",
2995
0
     function );
2996
2997
0
    goto on_error;
2998
0
  }
2999
#if defined( HAVE_DEBUG_OUTPUT )
3000
  if( libcnotify_verbose != 0 )
3001
  {
3002
    libcnotify_printf(
3003
     "%s: reading data from lead-out: %d at sector(s): %" PRIu64 " - %" PRIu64 "\n",
3004
     function,
3005
     internal_handle->current_lead_out,
3006
     sector_range->start_sector,
3007
     sector_range->end_sector );
3008
  }
3009
#endif
3010
  /* Retrieves the track that corresponds to the lead-out
3011
   */
3012
0
  if( libcdata_array_get_entry_by_index(
3013
0
       internal_handle->tracks_array,
3014
0
       internal_handle->current_track - 1,
3015
0
       (intptr_t **) &track_value,
3016
0
       error ) != 1 )
3017
0
  {
3018
0
    libcerror_error_set(
3019
0
     error,
3020
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3021
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3022
0
     "%s: unable to retrieve track value: %d from array.",
3023
0
     function,
3024
0
     internal_handle->current_track - 1 );
3025
3026
0
    goto on_error;
3027
0
  }
3028
0
  if( track_value == NULL )
3029
0
  {
3030
0
    libcerror_error_set(
3031
0
     error,
3032
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3033
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3034
0
     "%s: missing track value: %d.",
3035
0
     function,
3036
0
     internal_handle->current_track - 1 );
3037
3038
0
    goto on_error;
3039
0
  }
3040
0
  if( track_value->end_sector != sector_range->start_sector )
3041
0
  {
3042
0
    libcerror_error_set(
3043
0
     error,
3044
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3045
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3046
0
     "%s: sector range start sector value out of bounds.",
3047
0
     function );
3048
3049
0
    goto on_error;
3050
0
  }
3051
0
  current_sector_offset = internal_handle->current_offset
3052
0
                        - (off64_t) ( current_sector * internal_handle->io_handle->bytes_per_sector );
3053
3054
0
  if( ( current_sector_offset < 0 )
3055
0
   || ( current_sector_offset >= internal_handle->io_handle->bytes_per_sector ) )
3056
0
  {
3057
0
    libcerror_error_set(
3058
0
     error,
3059
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3060
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3061
0
     "%s: invalid current sector offset value out of bounds.",
3062
0
     function );
3063
3064
0
    goto on_error;
3065
0
  }
3066
0
  read_number_of_sectors = buffer_size / internal_handle->io_handle->bytes_per_sector;
3067
3068
0
  if( ( buffer_size % internal_handle->io_handle->bytes_per_sector ) != 0 )
3069
0
  {
3070
0
    read_number_of_sectors += 1;
3071
0
  }
3072
0
  if( ( (uint64_t) read_number_of_sectors + current_sector ) > sector_range->end_sector )
3073
0
  {
3074
0
    read_number_of_sectors = (size_t) ( sector_range->end_sector - current_sector );
3075
0
  }
3076
0
  if( libbfio_pool_get_size(
3077
0
       internal_handle->data_file_io_pool,
3078
0
       track_value->data_file_index,
3079
0
       &data_file_size,
3080
0
       error ) != 1 )
3081
0
  {
3082
0
    libcerror_error_set(
3083
0
     error,
3084
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3085
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3086
0
     "%s: unable to retrieve data file: %d size.",
3087
0
     function,
3088
0
     track_value->data_file_index );
3089
3090
0
    goto on_error;
3091
0
  }
3092
0
  data_file_number_of_sectors = data_file_size / track_value->bytes_per_sector;
3093
3094
  /* Determine if the required number of sectors are available in the data file
3095
   */
3096
0
  required_number_of_sectors = track_value->data_file_start_sector
3097
0
                             + track_value->number_of_sectors
3098
0
                             + sector_range->number_of_sectors;
3099
3100
0
  if( required_number_of_sectors > data_file_number_of_sectors )
3101
0
  {
3102
0
    read_size = ( read_number_of_sectors * internal_handle->io_handle->bytes_per_sector )
3103
0
              - (size_t) current_sector_offset;
3104
3105
0
    if( read_size > buffer_size )
3106
0
    {
3107
0
      read_size = buffer_size;
3108
0
    }
3109
    /* Fill the buffer with 0 byte values if the lead-out data is
3110
     * not available in the data file
3111
     */
3112
0
    if( memory_set(
3113
0
         buffer,
3114
0
         0,
3115
0
         read_size ) == NULL )
3116
0
    {
3117
0
      libcerror_error_set(
3118
0
       error,
3119
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
3120
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
3121
0
       "%s: unable to copy lead-out data to buffer.",
3122
0
       function );
3123
3124
0
      goto on_error;
3125
0
    }
3126
0
    read_count = (ssize_t) read_size;
3127
0
  }
3128
0
  else
3129
0
  {
3130
0
    lead_out_data_start_sector = current_sector
3131
0
                               - sector_range->start_sector
3132
0
                               + track_value->number_of_sectors;
3133
3134
0
    lead_out_data_offset = track_value->data_file_offset
3135
0
                         + ( lead_out_data_start_sector * track_value->bytes_per_sector );
3136
3137
0
    read_size = read_number_of_sectors * track_value->bytes_per_sector;
3138
3139
0
    if( track_value->bytes_per_sector != internal_handle->io_handle->bytes_per_sector )
3140
0
    {
3141
/* TODO use sector data cache ? */
3142
0
      sector_data = (uint8_t *) memory_allocate(
3143
0
                                 sizeof( uint8_t ) * read_size );
3144
3145
0
      if( sector_data == NULL )
3146
0
      {
3147
0
        libcerror_error_set(
3148
0
         error,
3149
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
3150
0
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
3151
0
         "%s: unable to create sector data.",
3152
0
         function );
3153
3154
0
        goto on_error;
3155
0
      }
3156
0
      read_buffer = sector_data;
3157
0
    }
3158
0
    else
3159
0
    {
3160
0
      read_buffer           = buffer;
3161
0
      read_size            -= (size_t) current_sector_offset;
3162
0
      lead_out_data_offset += current_sector_offset;
3163
3164
0
      if( read_size > buffer_size )
3165
0
      {
3166
0
        read_size = buffer_size;
3167
0
      }
3168
0
    }
3169
0
    if( libbfio_pool_seek_offset(
3170
0
         internal_handle->data_file_io_pool,
3171
0
         track_value->data_file_index,
3172
0
         lead_out_data_offset,
3173
0
         SEEK_SET,
3174
0
         error ) == -1 )
3175
0
    {
3176
0
      libcerror_error_set(
3177
0
       error,
3178
0
       LIBCERROR_ERROR_DOMAIN_IO,
3179
0
       LIBCERROR_IO_ERROR_SEEK_FAILED,
3180
0
       "%s: unable to seek data file: %d offset: %" PRIi64 ".",
3181
0
       function,
3182
0
       track_value->data_file_index,
3183
0
       lead_out_data_offset );
3184
3185
0
      goto on_error;
3186
0
    }
3187
0
    read_count = libbfio_pool_read_buffer(
3188
0
            internal_handle->data_file_io_pool,
3189
0
            track_value->data_file_index,
3190
0
            read_buffer,
3191
0
            read_size,
3192
0
            error );
3193
3194
0
    if( read_count != (ssize_t) read_size )
3195
0
    {
3196
0
      libcerror_error_set(
3197
0
       error,
3198
0
       LIBCERROR_ERROR_DOMAIN_IO,
3199
0
       LIBCERROR_IO_ERROR_READ_FAILED,
3200
0
       "%s: unable to read buffer from data file: %d.",
3201
0
       function,
3202
0
       track_value->data_file_index );
3203
3204
0
      goto on_error;
3205
0
    }
3206
0
    if( track_value->bytes_per_sector != internal_handle->io_handle->bytes_per_sector )
3207
0
    {
3208
0
      read_count = libodraw_io_handle_copy_sector_data_to_buffer(
3209
0
              internal_handle->io_handle,
3210
0
              sector_data,
3211
0
              read_size,
3212
0
                    track_value->bytes_per_sector,
3213
0
              LIBODRAW_TRACK_TYPE_UNKNOWN,
3214
0
              buffer,
3215
0
              buffer_size,
3216
0
              (uint32_t) current_sector,
3217
0
              (uint32_t) current_sector_offset,
3218
0
              error );
3219
3220
0
      if( read_count < 0 )
3221
0
      {
3222
0
        libcerror_error_set(
3223
0
         error,
3224
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3225
0
         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
3226
0
         "%s: unable to copy sector data to buffer.",
3227
0
         function );
3228
3229
0
        goto on_error;
3230
0
      }
3231
0
      memory_free(
3232
0
       sector_data );
3233
3234
0
      sector_data = NULL;
3235
0
    }
3236
0
  }
3237
0
  return( read_count );
3238
3239
0
on_error:
3240
0
  if( sector_data != NULL )
3241
0
  {
3242
0
    memory_free(
3243
0
     sector_data );
3244
0
  }
3245
0
  return( -1 );
3246
0
}
3247
3248
/* Reads a buffer from a sector in an unspecified range
3249
 * Returns the number of bytes read or -1 on error
3250
 */
3251
ssize_t libodraw_handle_read_buffer_from_unspecified_sector(
3252
         libodraw_internal_handle_t *internal_handle,
3253
         uint8_t *buffer,
3254
         size_t buffer_size,
3255
         libcerror_error_t **error )
3256
0
{
3257
0
  libodraw_track_value_t *track_value    = NULL;
3258
0
  uint8_t *read_buffer                   = NULL;
3259
0
  uint8_t *sector_data                   = NULL;
3260
0
  static char *function                  = "libodraw_handle_read_buffer_from_unspecified_sector";
3261
0
  off64_t current_sector_offset          = 0;
3262
0
  off64_t unspecified_data_offset        = 0;
3263
0
  size64_t data_file_number_of_sectors   = 0;
3264
0
  size64_t data_file_size                = 0;
3265
0
  size64_t required_number_of_sectors    = 0;
3266
0
  uint64_t current_sector                = 0;
3267
0
  uint64_t unspecified_data_start_sector = 0;
3268
0
  size_t read_size                       = 0;
3269
0
  ssize_t read_count                     = 0;
3270
3271
0
  if( internal_handle == NULL )
3272
0
  {
3273
0
    libcerror_error_set(
3274
0
     error,
3275
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3276
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3277
0
     "%s: invalid handle.",
3278
0
     function );
3279
3280
0
    return( -1 );
3281
0
  }
3282
0
  if( internal_handle->io_handle == NULL )
3283
0
  {
3284
0
    libcerror_error_set(
3285
0
     error,
3286
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3287
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3288
0
     "%s: invalid handle - missing IO handle.",
3289
0
     function );
3290
3291
0
    return( -1 );
3292
0
  }
3293
0
  if( internal_handle->io_handle->bytes_per_sector == 0 )
3294
0
  {
3295
0
    libcerror_error_set(
3296
0
     error,
3297
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3298
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3299
0
     "%s: invalid handle - invalid IO handle - missing bytes per sector.",
3300
0
     function );
3301
3302
0
    return( -1 );
3303
0
  }
3304
0
  current_sector = (uint64_t) ( internal_handle->current_offset / internal_handle->io_handle->bytes_per_sector );
3305
3306
0
  if( current_sector > (uint64_t) UINT32_MAX )
3307
0
  {
3308
0
    libcerror_error_set(
3309
0
     error,
3310
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3311
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3312
0
     "%s: current sector value out of bounds.",
3313
0
     function );
3314
3315
0
    return( -1 );
3316
0
  }
3317
#if defined( HAVE_DEBUG_OUTPUT )
3318
  if( libcnotify_verbose != 0 )
3319
  {
3320
    libcnotify_printf(
3321
     "%s: reading data from unspecified range.\n",
3322
     function );
3323
  }
3324
#endif
3325
  /* Retrieves the track that corresponds to the unspecified range
3326
   */
3327
0
  if( libcdata_array_get_entry_by_index(
3328
0
       internal_handle->tracks_array,
3329
0
       internal_handle->current_track - 1,
3330
0
       (intptr_t **) &track_value,
3331
0
       error ) != 1 )
3332
0
  {
3333
0
    libcerror_error_set(
3334
0
     error,
3335
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3336
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3337
0
     "%s: unable to retrieve track value: %d from array.",
3338
0
     function,
3339
0
     internal_handle->current_track - 1 );
3340
3341
0
    goto on_error;
3342
0
  }
3343
0
  if( track_value == NULL )
3344
0
  {
3345
0
    libcerror_error_set(
3346
0
     error,
3347
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3348
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3349
0
     "%s: missing track value: %d.",
3350
0
     function,
3351
0
     internal_handle->current_track - 1 );
3352
3353
0
    goto on_error;
3354
0
  }
3355
0
  current_sector_offset = internal_handle->current_offset
3356
0
                        - (off64_t) ( current_sector * internal_handle->io_handle->bytes_per_sector );
3357
3358
0
  if( ( current_sector_offset < 0 )
3359
0
   || ( current_sector_offset >= internal_handle->io_handle->bytes_per_sector ) )
3360
0
  {
3361
0
    libcerror_error_set(
3362
0
     error,
3363
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3364
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3365
0
     "%s: invalid current sector offset value out of bounds.",
3366
0
     function );
3367
3368
0
    goto on_error;
3369
0
  }
3370
0
  if( libbfio_pool_get_size(
3371
0
       internal_handle->data_file_io_pool,
3372
0
       track_value->data_file_index,
3373
0
       &data_file_size,
3374
0
       error ) != 1 )
3375
0
  {
3376
0
    libcerror_error_set(
3377
0
     error,
3378
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3379
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3380
0
     "%s: unable to retrieve data file: %d size.",
3381
0
     function,
3382
0
     track_value->data_file_index );
3383
3384
0
    goto on_error;
3385
0
  }
3386
0
  data_file_number_of_sectors = data_file_size / track_value->bytes_per_sector;
3387
3388
0
  unspecified_data_start_sector = current_sector
3389
0
                                - track_value->end_sector;
3390
3391
  /* Determine if the required number of sectors are available in the data file
3392
   */
3393
0
  required_number_of_sectors = track_value->data_file_start_sector
3394
0
                             + track_value->number_of_sectors
3395
0
                             + unspecified_data_start_sector
3396
0
                             + 1;
3397
3398
0
  if( required_number_of_sectors > data_file_number_of_sectors )
3399
0
  {
3400
0
    read_size = internal_handle->io_handle->bytes_per_sector
3401
0
              - (size_t) current_sector_offset;
3402
3403
0
    if( read_size > buffer_size )
3404
0
    {
3405
0
      read_size = buffer_size;
3406
0
    }
3407
    /* Fill the buffer with 0 byte values if the unspecified data is
3408
     * not available in the data file
3409
     */
3410
0
    if( memory_set(
3411
0
         buffer,
3412
0
         0,
3413
0
         read_size ) == NULL )
3414
0
    {
3415
0
      libcerror_error_set(
3416
0
       error,
3417
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
3418
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
3419
0
       "%s: unable to copy unspecified data to buffer.",
3420
0
       function );
3421
3422
0
      goto on_error;
3423
0
    }
3424
0
    read_count = (ssize_t) read_size;
3425
0
  }
3426
0
  else
3427
0
  {
3428
0
    unspecified_data_offset = track_value->data_file_offset
3429
0
                            + ( unspecified_data_start_sector * track_value->bytes_per_sector );
3430
3431
0
    read_size = track_value->bytes_per_sector;
3432
3433
0
    if( track_value->bytes_per_sector != internal_handle->io_handle->bytes_per_sector )
3434
0
    {
3435
/* TODO use sector data cache ? */
3436
0
      sector_data = (uint8_t *) memory_allocate(
3437
0
                                 sizeof( uint8_t ) * read_size );
3438
3439
0
      if( sector_data == NULL )
3440
0
      {
3441
0
        libcerror_error_set(
3442
0
         error,
3443
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
3444
0
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
3445
0
         "%s: unable to create sector data.",
3446
0
         function );
3447
3448
0
        goto on_error;
3449
0
      }
3450
0
      read_buffer = sector_data;
3451
0
    }
3452
0
    else
3453
0
    {
3454
0
      read_buffer              = buffer;
3455
0
      read_size               -= (size_t) current_sector_offset;
3456
0
      unspecified_data_offset += current_sector_offset;
3457
3458
0
      if( read_size > buffer_size )
3459
0
      {
3460
0
        read_size = buffer_size;
3461
0
      }
3462
0
    }
3463
0
    if( libbfio_pool_seek_offset(
3464
0
         internal_handle->data_file_io_pool,
3465
0
         track_value->data_file_index,
3466
0
         unspecified_data_offset,
3467
0
         SEEK_SET,
3468
0
         error ) == -1 )
3469
0
    {
3470
0
      libcerror_error_set(
3471
0
       error,
3472
0
       LIBCERROR_ERROR_DOMAIN_IO,
3473
0
       LIBCERROR_IO_ERROR_SEEK_FAILED,
3474
0
       "%s: unable to seek data file: %d offset: %" PRIi64 ".",
3475
0
       function,
3476
0
       track_value->data_file_index,
3477
0
       unspecified_data_offset );
3478
3479
0
      goto on_error;
3480
0
    }
3481
0
    read_count = libbfio_pool_read_buffer(
3482
0
            internal_handle->data_file_io_pool,
3483
0
            track_value->data_file_index,
3484
0
            read_buffer,
3485
0
            read_size,
3486
0
            error );
3487
3488
0
    if( read_count != (ssize_t) read_size )
3489
0
    {
3490
0
      libcerror_error_set(
3491
0
       error,
3492
0
       LIBCERROR_ERROR_DOMAIN_IO,
3493
0
       LIBCERROR_IO_ERROR_READ_FAILED,
3494
0
       "%s: unable to read buffer from data file: %d.",
3495
0
       function,
3496
0
       track_value->data_file_index );
3497
3498
0
      goto on_error;
3499
0
    }
3500
0
    if( track_value->bytes_per_sector != internal_handle->io_handle->bytes_per_sector )
3501
0
    {
3502
0
      read_count = libodraw_io_handle_copy_sector_data_to_buffer(
3503
0
              internal_handle->io_handle,
3504
0
              sector_data,
3505
0
              read_size,
3506
0
                    track_value->bytes_per_sector,
3507
0
              LIBODRAW_TRACK_TYPE_UNKNOWN,
3508
0
              buffer,
3509
0
              buffer_size,
3510
0
              (uint32_t) current_sector,
3511
0
              (uint32_t) current_sector_offset,
3512
0
              error );
3513
3514
0
      if( read_count < 0 )
3515
0
      {
3516
0
        libcerror_error_set(
3517
0
         error,
3518
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3519
0
         LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
3520
0
         "%s: unable to copy sector data to buffer.",
3521
0
         function );
3522
3523
0
        goto on_error;
3524
0
      }
3525
0
      memory_free(
3526
0
       sector_data );
3527
3528
0
      sector_data = NULL;
3529
0
    }
3530
0
  }
3531
0
  return( read_count );
3532
3533
0
on_error:
3534
0
  if( sector_data != NULL )
3535
0
  {
3536
0
    memory_free(
3537
0
     sector_data );
3538
0
  }
3539
0
  return( -1 );
3540
0
}
3541
3542
/* Reads a buffer from track
3543
 * Returns the number of bytes read or -1 on error
3544
 */
3545
ssize_t libodraw_handle_read_buffer_from_track(
3546
         libodraw_internal_handle_t *internal_handle,
3547
         uint8_t *buffer,
3548
         size_t buffer_size,
3549
         libcerror_error_t **error )
3550
0
{
3551
0
  libodraw_track_value_t *track_value = NULL;
3552
0
  uint8_t *read_buffer                = NULL;
3553
0
  uint8_t *sector_data                = NULL;
3554
0
  static char *function               = "libodraw_handle_read_buffer_from_track";
3555
0
  off64_t current_sector_offset       = 0;
3556
0
  off64_t track_data_offset           = 0;
3557
0
  uint64_t current_sector             = 0;
3558
0
  uint64_t track_data_start_sector    = 0;
3559
0
  size_t read_number_of_sectors       = 0;
3560
0
  size_t read_size                    = 0;
3561
0
  ssize_t read_count                  = 0;
3562
3563
0
  if( internal_handle == NULL )
3564
0
  {
3565
0
    libcerror_error_set(
3566
0
     error,
3567
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3568
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3569
0
     "%s: invalid handle.",
3570
0
     function );
3571
3572
0
    return( -1 );
3573
0
  }
3574
0
  if( internal_handle->io_handle == NULL )
3575
0
  {
3576
0
    libcerror_error_set(
3577
0
     error,
3578
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3579
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3580
0
     "%s: invalid handle - missing IO handle.",
3581
0
     function );
3582
3583
0
    return( -1 );
3584
0
  }
3585
0
  if( internal_handle->io_handle->bytes_per_sector == 0 )
3586
0
  {
3587
0
    libcerror_error_set(
3588
0
     error,
3589
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3590
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3591
0
     "%s: invalid handle - invalid IO handle - missing bytes per sector.",
3592
0
     function );
3593
3594
0
    return( -1 );
3595
0
  }
3596
0
  if( libcdata_array_get_entry_by_index(
3597
0
       internal_handle->tracks_array,
3598
0
       internal_handle->current_track,
3599
0
       (intptr_t **) &track_value,
3600
0
       error ) != 1 )
3601
0
  {
3602
0
    libcerror_error_set(
3603
0
     error,
3604
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3605
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3606
0
     "%s: unable to retrieve track value: %d from array.",
3607
0
     function,
3608
0
     internal_handle->current_track );
3609
3610
0
    goto on_error;
3611
0
  }
3612
0
  if( track_value == NULL )
3613
0
  {
3614
0
    libcerror_error_set(
3615
0
     error,
3616
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3617
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3618
0
     "%s: missing track value: %d.",
3619
0
     function,
3620
0
     internal_handle->current_track );
3621
3622
0
    goto on_error;
3623
0
  }
3624
0
  current_sector = (uint64_t) ( internal_handle->current_offset / internal_handle->io_handle->bytes_per_sector );
3625
3626
0
  if( current_sector > (uint64_t) UINT32_MAX )
3627
0
  {
3628
0
    libcerror_error_set(
3629
0
     error,
3630
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3631
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3632
0
     "%s: current sector value out of bounds.",
3633
0
     function );
3634
3635
0
    return( -1 );
3636
0
  }
3637
  /* TODO currently assumes that current track start sector is always relative to the start of the media */
3638
0
  if( ( current_sector < track_value->start_sector )
3639
0
   || ( current_sector >= track_value->end_sector ) )
3640
0
  {
3641
0
    libcerror_error_set(
3642
0
     error,
3643
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3644
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3645
0
     "%s: current sector value out of bounds.",
3646
0
     function );
3647
3648
0
    goto on_error;
3649
0
  }
3650
#if defined( HAVE_DEBUG_OUTPUT )
3651
  if( libcnotify_verbose != 0 )
3652
  {
3653
    libcnotify_printf(
3654
     "%s: reading data from track: %d at sector(s): %" PRIu64 " - %" PRIu64 "\n",
3655
     function,
3656
     internal_handle->current_track,
3657
     track_value->start_sector,
3658
     track_value->end_sector );
3659
  }
3660
#endif
3661
0
  current_sector_offset = internal_handle->current_offset
3662
0
                        - (off64_t) ( current_sector * internal_handle->io_handle->bytes_per_sector );
3663
3664
0
  if( ( current_sector_offset < 0 )
3665
0
   || ( current_sector_offset >= internal_handle->io_handle->bytes_per_sector ) )
3666
0
  {
3667
0
    libcerror_error_set(
3668
0
     error,
3669
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3670
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3671
0
     "%s: invalid current sector offset value out of bounds.",
3672
0
     function );
3673
3674
0
    goto on_error;
3675
0
  }
3676
0
  track_data_start_sector = current_sector - track_value->start_sector;
3677
3678
0
  track_data_offset = track_value->data_file_offset
3679
0
                    + ( track_data_start_sector * track_value->bytes_per_sector );
3680
3681
0
  read_number_of_sectors = buffer_size / internal_handle->io_handle->bytes_per_sector;
3682
3683
0
  if( ( buffer_size % internal_handle->io_handle->bytes_per_sector ) != 0 )
3684
0
  {
3685
0
    read_number_of_sectors += 1;
3686
0
  }
3687
0
  if( ( (uint64_t) read_number_of_sectors + current_sector ) > track_value->end_sector )
3688
0
  {
3689
0
    read_number_of_sectors = (size_t) ( track_value->end_sector - current_sector );
3690
0
  }
3691
0
  read_size = read_number_of_sectors * track_value->bytes_per_sector;
3692
3693
0
  if( track_value->bytes_per_sector != internal_handle->io_handle->bytes_per_sector )
3694
0
  {
3695
/* TODO handle more track types */
3696
0
    if( ( track_value->type != LIBODRAW_TRACK_TYPE_AUDIO )
3697
0
     && ( track_value->type != LIBODRAW_TRACK_TYPE_MODE1_2048 )
3698
0
     && ( track_value->type != LIBODRAW_TRACK_TYPE_MODE1_2352 )
3699
0
     && ( track_value->type != LIBODRAW_TRACK_TYPE_MODE2_2048 )
3700
0
     && ( track_value->type != LIBODRAW_TRACK_TYPE_MODE2_2336 )
3701
0
     && ( track_value->type != LIBODRAW_TRACK_TYPE_MODE2_2352 ) )
3702
0
    {
3703
0
      libcerror_error_set(
3704
0
       error,
3705
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3706
0
       LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3707
0
       "%s: unsupported track type.",
3708
0
       function );
3709
3710
0
      goto on_error;
3711
0
    }
3712
/* TODO use sector data cache ? */
3713
0
    sector_data = (uint8_t *) memory_allocate(
3714
0
                               sizeof( uint8_t ) * read_size );
3715
3716
0
    if( sector_data == NULL )
3717
0
    {
3718
0
      libcerror_error_set(
3719
0
       error,
3720
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
3721
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
3722
0
       "%s: unable to create sector data.",
3723
0
       function );
3724
3725
0
      goto on_error;
3726
0
    }
3727
0
    read_buffer = sector_data;
3728
0
  }
3729
0
  else
3730
0
  {
3731
0
    read_buffer        = buffer;
3732
0
    read_size         -= (size_t) current_sector_offset;
3733
0
    track_data_offset += current_sector_offset;
3734
3735
0
    if( read_size > buffer_size )
3736
0
    {
3737
0
      read_size = buffer_size;
3738
0
    }
3739
0
  }
3740
0
  if( libbfio_pool_seek_offset(
3741
0
       internal_handle->data_file_io_pool,
3742
0
       track_value->data_file_index,
3743
0
       track_data_offset,
3744
0
       SEEK_SET,
3745
0
       error ) == -1 )
3746
0
  {
3747
0
    libcerror_error_set(
3748
0
     error,
3749
0
     LIBCERROR_ERROR_DOMAIN_IO,
3750
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
3751
0
     "%s: unable to seek data file: %d offset: %" PRIi64 ".",
3752
0
     function,
3753
0
     track_value->data_file_index,
3754
0
     track_data_offset );
3755
3756
0
    goto on_error;
3757
0
  }
3758
0
  read_count = libbfio_pool_read_buffer(
3759
0
          internal_handle->data_file_io_pool,
3760
0
          track_value->data_file_index,
3761
0
          read_buffer,
3762
0
          read_size,
3763
0
          error );
3764
3765
0
  if( read_count != (ssize_t) read_size )
3766
0
  {
3767
0
    libcerror_error_set(
3768
0
     error,
3769
0
     LIBCERROR_ERROR_DOMAIN_IO,
3770
0
     LIBCERROR_IO_ERROR_READ_FAILED,
3771
0
     "%s: unable to read buffer from data file: %d.",
3772
0
     function,
3773
0
     track_value->data_file_index );
3774
3775
0
    goto on_error;
3776
0
  }
3777
0
  if( track_value->bytes_per_sector != internal_handle->io_handle->bytes_per_sector )
3778
0
  {
3779
0
    read_count = libodraw_io_handle_copy_sector_data_to_buffer(
3780
0
                  internal_handle->io_handle,
3781
0
                  sector_data,
3782
0
                  read_size,
3783
0
                  track_value->bytes_per_sector,
3784
0
                  track_value->type,
3785
0
                  buffer,
3786
0
                  buffer_size,
3787
0
            (uint32_t) current_sector,
3788
0
                  (uint32_t) current_sector_offset,
3789
0
                  error );
3790
3791
0
    if( read_count < 0 )
3792
0
    {
3793
0
      libcerror_error_set(
3794
0
       error,
3795
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3796
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
3797
0
       "%s: unable to copy sector data to buffer.",
3798
0
       function );
3799
3800
0
      goto on_error;
3801
0
    }
3802
0
    memory_free(
3803
0
     sector_data );
3804
3805
0
    sector_data = NULL;
3806
0
  }
3807
0
  return( read_count );
3808
3809
0
on_error:
3810
0
  if( sector_data != NULL )
3811
0
  {
3812
0
    memory_free(
3813
0
     sector_data );
3814
0
  }
3815
0
  return( -1 );
3816
0
}
3817
3818
/* Reads (media) data at a specific offset
3819
 * Returns the number of bytes read or -1 on error
3820
 */
3821
ssize_t libodraw_handle_read_buffer_at_offset(
3822
         libodraw_handle_t *handle,
3823
         void *buffer,
3824
         size_t buffer_size,
3825
         off64_t offset,
3826
         libcerror_error_t **error )
3827
0
{
3828
0
  static char *function = "libodraw_handle_read_buffer_at_offset";
3829
0
  ssize_t read_count    = 0;
3830
3831
0
  if( libodraw_handle_seek_offset(
3832
0
       handle,
3833
0
       offset,
3834
0
       SEEK_SET,
3835
0
       error ) == -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
    return( -1 );
3845
0
  }
3846
0
  read_count = libodraw_handle_read_buffer(
3847
0
                handle,
3848
0
                buffer,
3849
0
                buffer_size,
3850
0
                error );
3851
3852
0
  if( read_count <= -1 )
3853
0
  {
3854
0
    libcerror_error_set(
3855
0
     error,
3856
0
     LIBCERROR_ERROR_DOMAIN_IO,
3857
0
     LIBCERROR_IO_ERROR_READ_FAILED,
3858
0
     "%s: unable to read buffer.",
3859
0
     function );
3860
3861
0
    return( -1 );
3862
0
  }
3863
0
  return( read_count );
3864
0
}
3865
3866
/* Seeks a certain offset of the (media) data
3867
 * This function is not multi-thread safe acquire write lock before call
3868
 * Returns the offset if seek is successful or -1 on error
3869
 */
3870
off64_t libodraw_internal_handle_seek_offset(
3871
         libodraw_internal_handle_t *internal_handle,
3872
         off64_t offset,
3873
         int whence,
3874
         libcerror_error_t **error )
3875
0
{
3876
0
  libodraw_sector_range_t *lead_out_sector_range = NULL;
3877
0
  libodraw_sector_range_t *run_out_sector_range  = NULL;
3878
0
  libodraw_track_value_t *track_value            = NULL;
3879
0
  static char *function                          = "libodraw_internal_handle_seek_offset";
3880
0
  off64_t lead_out_offset                        = 0;
3881
0
  off64_t run_out_offset                         = 0;
3882
0
  off64_t track_offset                           = 0;
3883
0
  int current_lead_out                           = 0;
3884
0
  int current_run_out                            = 0;
3885
0
  int current_track                              = 0;
3886
3887
0
  if( internal_handle == NULL )
3888
0
  {
3889
0
    libcerror_error_set(
3890
0
     error,
3891
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3892
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3893
0
     "%s: invalid handle.",
3894
0
     function );
3895
3896
0
    return( -1 );
3897
0
  }
3898
0
  if( internal_handle->io_handle == NULL )
3899
0
  {
3900
0
    libcerror_error_set(
3901
0
     error,
3902
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3903
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3904
0
     "%s: invalid handle - missing IO handle.",
3905
0
     function );
3906
3907
0
    return( -1 );
3908
0
  }
3909
0
  if( ( whence != SEEK_CUR )
3910
0
   && ( whence != SEEK_END )
3911
0
   && ( whence != SEEK_SET ) )
3912
0
  {
3913
0
    libcerror_error_set(
3914
0
     error,
3915
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3916
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3917
0
     "%s: unsupported whence.",
3918
0
     function );
3919
3920
0
    return( -1 );
3921
0
  }
3922
0
  if( whence == SEEK_CUR )
3923
0
  {
3924
0
    offset += internal_handle->current_offset;
3925
0
  }
3926
0
  else if( whence == SEEK_END )
3927
0
  {
3928
0
    offset += (off64_t) internal_handle->media_size;
3929
0
  }
3930
0
  if( offset < 0 )
3931
0
  {
3932
0
    libcerror_error_set(
3933
0
     error,
3934
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3935
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3936
0
     "%s: invalid offset value out of bounds.",
3937
0
     function );
3938
3939
0
    return( -1 );
3940
0
  }
3941
0
  if( offset < (off64_t) internal_handle->media_size )
3942
0
  {
3943
0
    if( libodraw_handle_get_run_out_at_offset(
3944
0
         internal_handle,
3945
0
         offset,
3946
0
         &current_run_out,
3947
0
         &run_out_sector_range,
3948
0
         &run_out_offset,
3949
0
         error ) == -1 )
3950
0
    {
3951
0
      libcerror_error_set(
3952
0
       error,
3953
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3954
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3955
0
       "%s: unable to retrieve run-out at offset: %" PRIi64 ".",
3956
0
       function,
3957
0
       offset );
3958
3959
0
      return( -1 );
3960
0
    }
3961
0
    if( libodraw_handle_get_lead_out_at_offset(
3962
0
         internal_handle,
3963
0
         offset,
3964
0
         &current_lead_out,
3965
0
         &lead_out_sector_range,
3966
0
         &lead_out_offset,
3967
0
         error ) == -1 )
3968
0
    {
3969
0
      libcerror_error_set(
3970
0
       error,
3971
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3972
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3973
0
       "%s: unable to retrieve lead-out at offset: %" PRIi64 ".",
3974
0
       function,
3975
0
       offset );
3976
3977
0
      return( -1 );
3978
0
    }
3979
0
    if( libodraw_handle_get_track_at_offset(
3980
0
         internal_handle,
3981
0
         offset,
3982
0
         &current_track,
3983
0
         &track_value,
3984
0
         &track_offset,
3985
0
         error ) == -1 )
3986
0
    {
3987
0
      libcerror_error_set(
3988
0
       error,
3989
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3990
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3991
0
       "%s: unable to retrieve track at offset: %" PRIi64 ".",
3992
0
       function,
3993
0
       offset );
3994
3995
0
      return( -1 );
3996
0
    }
3997
0
  }
3998
0
  else
3999
0
  {
4000
0
    if( libcdata_array_get_number_of_entries(
4001
0
         internal_handle->run_outs_array,
4002
0
         &current_run_out,
4003
0
         error ) != 1 )
4004
0
    {
4005
0
      libcerror_error_set(
4006
0
       error,
4007
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4008
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4009
0
       "%s: unable to retrieve number of elements in run-outs array.",
4010
0
       function );
4011
4012
0
      return( -1 );
4013
0
    }
4014
0
    if( libcdata_array_get_number_of_entries(
4015
0
         internal_handle->lead_outs_array,
4016
0
         &current_lead_out,
4017
0
         error ) != 1 )
4018
0
    {
4019
0
      libcerror_error_set(
4020
0
       error,
4021
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4022
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4023
0
       "%s: unable to retrieve number of elements in lead-outs array.",
4024
0
       function );
4025
4026
0
      return( -1 );
4027
0
    }
4028
0
    if( libcdata_array_get_number_of_entries(
4029
0
         internal_handle->tracks_array,
4030
0
         &current_track,
4031
0
         error ) != 1 )
4032
0
    {
4033
0
      libcerror_error_set(
4034
0
       error,
4035
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4036
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4037
0
       "%s: unable to retrieve number of elements in tracks array.",
4038
0
       function );
4039
4040
0
      return( -1 );
4041
0
    }
4042
0
  }
4043
0
  internal_handle->current_offset   = offset;
4044
0
  internal_handle->current_run_out  = current_run_out;
4045
0
  internal_handle->current_lead_out = current_lead_out;
4046
0
  internal_handle->current_track    = current_track;
4047
4048
0
  return( offset );
4049
0
}
4050
4051
/* Seeks a certain offset of the (media) data
4052
 * Returns the offset if seek is successful or -1 on error
4053
 */
4054
off64_t libodraw_handle_seek_offset(
4055
         libodraw_handle_t *handle,
4056
         off64_t offset,
4057
         int whence,
4058
         libcerror_error_t **error )
4059
0
{
4060
0
  libodraw_internal_handle_t *internal_handle = NULL;
4061
0
  static char *function                       = "libodraw_handle_seek_offset";
4062
4063
0
  if( handle == 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 handle.",
4070
0
     function );
4071
4072
0
    return( -1 );
4073
0
  }
4074
0
  internal_handle = (libodraw_internal_handle_t *) handle;
4075
4076
0
  if( internal_handle->data_file_io_pool == NULL )
4077
0
  {
4078
0
    libcerror_error_set(
4079
0
     error,
4080
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4081
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4082
0
     "%s: invalid handle - missing data file IO pool.",
4083
0
     function );
4084
4085
0
    return( -1 );
4086
0
  }
4087
#if defined( HAVE_LIBODRAW_MULTI_THREAD_SUPPORT )
4088
  if( libcthreads_read_write_lock_grab_for_write(
4089
       internal_handle->read_write_lock,
4090
       error ) != 1 )
4091
  {
4092
    libcerror_error_set(
4093
     error,
4094
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4095
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4096
     "%s: unable to grab read/write lock for writing.",
4097
     function );
4098
4099
    return( -1 );
4100
  }
4101
#endif
4102
0
  offset = libodraw_internal_handle_seek_offset(
4103
0
            internal_handle,
4104
0
            offset,
4105
0
            whence,
4106
0
            error );
4107
4108
0
  if( offset == -1 )
4109
0
  {
4110
0
    libcerror_error_set(
4111
0
     error,
4112
0
     LIBCERROR_ERROR_DOMAIN_IO,
4113
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
4114
0
     "%s: unable to seek offset.",
4115
0
     function );
4116
4117
0
    offset = -1;
4118
0
  }
4119
#if defined( HAVE_LIBODRAW_MULTI_THREAD_SUPPORT )
4120
  if( libcthreads_read_write_lock_release_for_write(
4121
       internal_handle->read_write_lock,
4122
       error ) != 1 )
4123
  {
4124
    libcerror_error_set(
4125
     error,
4126
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4127
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4128
     "%s: unable to release read/write lock for writing.",
4129
     function );
4130
4131
    return( -1 );
4132
  }
4133
#endif
4134
0
  return( offset );
4135
0
}
4136
4137
/* Retrieves a run-out sector range for the specified offset
4138
 * When no matching run-out was found the run_out_index value contains the next run-out index on return
4139
 * Returns 1 if successful, 0 if no matching run-out was found or -1 on error
4140
 */
4141
int libodraw_handle_get_run_out_at_offset(
4142
     libodraw_internal_handle_t *internal_handle,
4143
     off64_t offset,
4144
     int *run_out_index,
4145
     libodraw_sector_range_t **run_out_sector_range,
4146
     off64_t *run_out_offset,
4147
     libcerror_error_t **error )
4148
0
{
4149
0
  static char *function   = "libodraw_handle_get_run_out_at_offset";
4150
0
  uint64_t current_sector = 0;
4151
0
  int number_of_run_outs  = 0;
4152
4153
0
  if( internal_handle == NULL )
4154
0
  {
4155
0
    libcerror_error_set(
4156
0
     error,
4157
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4158
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4159
0
     "%s: invalid handle.",
4160
0
     function );
4161
4162
0
    return( -1 );
4163
0
  }
4164
0
  if( internal_handle->io_handle == NULL )
4165
0
  {
4166
0
    libcerror_error_set(
4167
0
     error,
4168
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4169
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4170
0
     "%s: invalid handle - missing IO handle.",
4171
0
     function );
4172
4173
0
    return( -1 );
4174
0
  }
4175
0
  if( internal_handle->io_handle->bytes_per_sector == 0 )
4176
0
  {
4177
0
    libcerror_error_set(
4178
0
     error,
4179
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4180
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4181
0
     "%s: invalid handle - invalid IO handle - missing bytes per sector.",
4182
0
     function );
4183
4184
0
    return( -1 );
4185
0
  }
4186
0
  if( run_out_index == NULL )
4187
0
  {
4188
0
    libcerror_error_set(
4189
0
     error,
4190
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4191
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4192
0
     "%s: invalid run-out index.",
4193
0
     function );
4194
4195
0
    return( -1 );
4196
0
  }
4197
0
  if( run_out_sector_range == NULL )
4198
0
  {
4199
0
    libcerror_error_set(
4200
0
     error,
4201
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4202
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4203
0
     "%s: invalid run-out sector range.",
4204
0
     function );
4205
4206
0
    return( -1 );
4207
0
  }
4208
0
  if( run_out_offset == NULL )
4209
0
  {
4210
0
    libcerror_error_set(
4211
0
     error,
4212
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4213
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4214
0
     "%s: invalid run-out offset.",
4215
0
     function );
4216
4217
0
    return( -1 );
4218
0
  }
4219
0
  if( libcdata_array_get_number_of_entries(
4220
0
       internal_handle->run_outs_array,
4221
0
       &number_of_run_outs,
4222
0
       error ) != 1 )
4223
0
  {
4224
0
    libcerror_error_set(
4225
0
     error,
4226
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4227
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4228
0
     "%s: unable to retrieve number of elements in run-outs array.",
4229
0
     function );
4230
4231
0
    return( -1 );
4232
0
  }
4233
0
  current_sector = offset / internal_handle->io_handle->bytes_per_sector;
4234
4235
0
  if( current_sector > (uint64_t) UINT32_MAX )
4236
0
  {
4237
0
    libcerror_error_set(
4238
0
     error,
4239
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4240
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4241
0
     "%s: current sector value out of bounds.",
4242
0
     function );
4243
4244
0
    return( -1 );
4245
0
  }
4246
0
  for( *run_out_index = 0;
4247
0
       *run_out_index < number_of_run_outs;
4248
0
       *run_out_index += 1 )
4249
0
  {
4250
0
    if( libcdata_array_get_entry_by_index(
4251
0
         internal_handle->run_outs_array,
4252
0
         *run_out_index,
4253
0
         (intptr_t **) run_out_sector_range,
4254
0
         error ) != 1 )
4255
0
    {
4256
0
      libcerror_error_set(
4257
0
       error,
4258
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4259
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4260
0
       "%s: unable to retrieve run-out sector range: %d from array.",
4261
0
       function,
4262
0
       number_of_run_outs - 1 );
4263
4264
0
      return( -1 );
4265
0
    }
4266
0
    if( *run_out_sector_range == NULL )
4267
0
    {
4268
0
      libcerror_error_set(
4269
0
       error,
4270
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4271
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4272
0
       "%s: missing run-out sector range: %d.",
4273
0
       function,
4274
0
       *run_out_index );
4275
4276
0
      return( -1 );
4277
0
    }
4278
0
    if( ( current_sector >= ( *run_out_sector_range )->start_sector )
4279
0
     && ( current_sector < ( *run_out_sector_range )->end_sector ) )
4280
0
    {
4281
0
      *run_out_offset = offset - ( ( *run_out_sector_range )->start_sector * internal_handle->io_handle->bytes_per_sector );
4282
4283
0
      return( 1 );
4284
0
    }
4285
0
    if( current_sector < ( *run_out_sector_range )->start_sector )
4286
0
    {
4287
0
      break;
4288
0
    }
4289
0
  }
4290
0
  *run_out_sector_range = NULL;
4291
0
  *run_out_offset       = 0;
4292
4293
0
  return( 0 );
4294
0
}
4295
4296
/* Retrieves a lead-out sector range for the specified offset
4297
 * When no matching lead-out was found the lead_out_index value contains the next lead-out index on return
4298
 * Returns 1 if successful, 0 if no matching lead-out was found or -1 on error
4299
 */
4300
int libodraw_handle_get_lead_out_at_offset(
4301
     libodraw_internal_handle_t *internal_handle,
4302
     off64_t offset,
4303
     int *lead_out_index,
4304
     libodraw_sector_range_t **lead_out_sector_range,
4305
     off64_t *lead_out_offset,
4306
     libcerror_error_t **error )
4307
0
{
4308
0
  static char *function   = "libodraw_handle_get_lead_out_at_offset";
4309
0
  uint64_t current_sector = 0;
4310
0
  int number_of_lead_outs = 0;
4311
4312
0
  if( internal_handle == NULL )
4313
0
  {
4314
0
    libcerror_error_set(
4315
0
     error,
4316
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4317
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4318
0
     "%s: invalid handle.",
4319
0
     function );
4320
4321
0
    return( -1 );
4322
0
  }
4323
0
  if( internal_handle->io_handle == NULL )
4324
0
  {
4325
0
    libcerror_error_set(
4326
0
     error,
4327
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4328
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4329
0
     "%s: invalid handle - missing IO handle.",
4330
0
     function );
4331
4332
0
    return( -1 );
4333
0
  }
4334
0
  if( internal_handle->io_handle->bytes_per_sector == 0 )
4335
0
  {
4336
0
    libcerror_error_set(
4337
0
     error,
4338
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4339
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4340
0
     "%s: invalid handle - invalid IO handle - missing bytes per sector.",
4341
0
     function );
4342
4343
0
    return( -1 );
4344
0
  }
4345
0
  if( lead_out_index == NULL )
4346
0
  {
4347
0
    libcerror_error_set(
4348
0
     error,
4349
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4350
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4351
0
     "%s: invalid lead-out index.",
4352
0
     function );
4353
4354
0
    return( -1 );
4355
0
  }
4356
0
  if( lead_out_sector_range == NULL )
4357
0
  {
4358
0
    libcerror_error_set(
4359
0
     error,
4360
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4361
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4362
0
     "%s: invalid lead-out sector range.",
4363
0
     function );
4364
4365
0
    return( -1 );
4366
0
  }
4367
0
  if( lead_out_offset == NULL )
4368
0
  {
4369
0
    libcerror_error_set(
4370
0
     error,
4371
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4372
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4373
0
     "%s: invalid lead-out offset.",
4374
0
     function );
4375
4376
0
    return( -1 );
4377
0
  }
4378
0
  if( libcdata_array_get_number_of_entries(
4379
0
       internal_handle->lead_outs_array,
4380
0
       &number_of_lead_outs,
4381
0
       error ) != 1 )
4382
0
  {
4383
0
    libcerror_error_set(
4384
0
     error,
4385
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4386
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4387
0
     "%s: unable to retrieve number of elements in lead-outs array.",
4388
0
     function );
4389
4390
0
    return( -1 );
4391
0
  }
4392
0
  current_sector = offset / internal_handle->io_handle->bytes_per_sector;
4393
4394
0
  if( current_sector > (uint64_t) UINT32_MAX )
4395
0
  {
4396
0
    libcerror_error_set(
4397
0
     error,
4398
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4399
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4400
0
     "%s: current sector value out of bounds.",
4401
0
     function );
4402
4403
0
    return( -1 );
4404
0
  }
4405
0
  for( *lead_out_index = 0;
4406
0
       *lead_out_index < number_of_lead_outs;
4407
0
       *lead_out_index += 1 )
4408
0
  {
4409
0
    if( libcdata_array_get_entry_by_index(
4410
0
         internal_handle->lead_outs_array,
4411
0
         *lead_out_index,
4412
0
         (intptr_t **) lead_out_sector_range,
4413
0
         error ) != 1 )
4414
0
    {
4415
0
      libcerror_error_set(
4416
0
       error,
4417
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4418
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4419
0
       "%s: unable to retrieve lead-out sector range: %d from array.",
4420
0
       function,
4421
0
       number_of_lead_outs - 1 );
4422
4423
0
      return( -1 );
4424
0
    }
4425
0
    if( *lead_out_sector_range == NULL )
4426
0
    {
4427
0
      libcerror_error_set(
4428
0
       error,
4429
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4430
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4431
0
       "%s: missing lead-out sector range: %d.",
4432
0
       function,
4433
0
       *lead_out_index );
4434
4435
0
      return( -1 );
4436
0
    }
4437
0
    if( ( current_sector >= ( *lead_out_sector_range )->start_sector )
4438
0
     && ( current_sector < ( *lead_out_sector_range )->end_sector ) )
4439
0
    {
4440
0
      *lead_out_offset = offset - ( ( *lead_out_sector_range )->start_sector * internal_handle->io_handle->bytes_per_sector );
4441
4442
0
      return( 1 );
4443
0
    }
4444
0
    if( current_sector < ( *lead_out_sector_range )->start_sector )
4445
0
    {
4446
0
      break;
4447
0
    }
4448
0
  }
4449
0
  *lead_out_sector_range = NULL;
4450
0
  *lead_out_offset       = 0;
4451
4452
0
  return( 0 );
4453
0
}
4454
4455
/* Retrieves a track value for the specified offset
4456
 * When no matching track was found the track_index value contains the next track index on return
4457
 * Returns 1 if successful, 0 if no matching track was found or -1 on error
4458
 */
4459
int libodraw_handle_get_track_at_offset(
4460
     libodraw_internal_handle_t *internal_handle,
4461
     off64_t offset,
4462
     int *track_index,
4463
     libodraw_track_value_t **track_value,
4464
     off64_t *track_offset,
4465
     libcerror_error_t **error )
4466
0
{
4467
0
  static char *function   = "libodraw_handle_get_track_at_offset";
4468
0
  uint64_t current_sector = 0;
4469
0
  int number_of_tracks    = 0;
4470
4471
0
  if( internal_handle == NULL )
4472
0
  {
4473
0
    libcerror_error_set(
4474
0
     error,
4475
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4476
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4477
0
     "%s: invalid handle.",
4478
0
     function );
4479
4480
0
    return( -1 );
4481
0
  }
4482
0
  if( internal_handle->io_handle == NULL )
4483
0
  {
4484
0
    libcerror_error_set(
4485
0
     error,
4486
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4487
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4488
0
     "%s: invalid handle - missing IO handle.",
4489
0
     function );
4490
4491
0
    return( -1 );
4492
0
  }
4493
0
  if( internal_handle->io_handle->bytes_per_sector == 0 )
4494
0
  {
4495
0
    libcerror_error_set(
4496
0
     error,
4497
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4498
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4499
0
     "%s: invalid handle - invalid IO handle - missing bytes per sector.",
4500
0
     function );
4501
4502
0
    return( -1 );
4503
0
  }
4504
0
  if( track_index == NULL )
4505
0
  {
4506
0
    libcerror_error_set(
4507
0
     error,
4508
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4509
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4510
0
     "%s: invalid track index.",
4511
0
     function );
4512
4513
0
    return( -1 );
4514
0
  }
4515
0
  if( track_value == NULL )
4516
0
  {
4517
0
    libcerror_error_set(
4518
0
     error,
4519
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4520
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4521
0
     "%s: invalid track value.",
4522
0
     function );
4523
4524
0
    return( -1 );
4525
0
  }
4526
0
  if( track_offset == NULL )
4527
0
  {
4528
0
    libcerror_error_set(
4529
0
     error,
4530
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4531
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4532
0
     "%s: invalid track offset.",
4533
0
     function );
4534
4535
0
    return( -1 );
4536
0
  }
4537
0
  if( libcdata_array_get_number_of_entries(
4538
0
       internal_handle->tracks_array,
4539
0
       &number_of_tracks,
4540
0
       error ) != 1 )
4541
0
  {
4542
0
    libcerror_error_set(
4543
0
     error,
4544
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4545
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4546
0
     "%s: unable to retrieve number of elements in tracks array.",
4547
0
     function );
4548
4549
0
    return( -1 );
4550
0
  }
4551
0
  current_sector = offset / internal_handle->io_handle->bytes_per_sector;
4552
4553
0
  if( current_sector > (uint64_t) UINT32_MAX )
4554
0
  {
4555
0
    libcerror_error_set(
4556
0
     error,
4557
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4558
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4559
0
     "%s: current sector value out of bounds.",
4560
0
     function );
4561
4562
0
    return( -1 );
4563
0
  }
4564
0
  for( *track_index = 0;
4565
0
       *track_index < number_of_tracks;
4566
0
       *track_index += 1 )
4567
0
  {
4568
0
    if( libcdata_array_get_entry_by_index(
4569
0
         internal_handle->tracks_array,
4570
0
         *track_index,
4571
0
         (intptr_t **) track_value,
4572
0
         error ) != 1 )
4573
0
    {
4574
0
      libcerror_error_set(
4575
0
       error,
4576
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4577
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4578
0
       "%s: unable to retrieve track value: %d from array.",
4579
0
       function,
4580
0
       number_of_tracks - 1 );
4581
4582
0
      return( -1 );
4583
0
    }
4584
0
    if( *track_value == NULL )
4585
0
    {
4586
0
      libcerror_error_set(
4587
0
       error,
4588
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4589
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4590
0
       "%s: missing track value: %d.",
4591
0
       function,
4592
0
       *track_index );
4593
4594
0
      return( -1 );
4595
0
    }
4596
0
    if( ( current_sector >= ( *track_value )->start_sector )
4597
0
     && ( current_sector < ( *track_value )->end_sector ) )
4598
0
    {
4599
0
      *track_offset = offset - ( ( *track_value )->start_sector * internal_handle->io_handle->bytes_per_sector );
4600
4601
0
      return( 1 );
4602
0
    }
4603
0
    if( current_sector < ( *track_value )->start_sector )
4604
0
    {
4605
0
      break;
4606
0
    }
4607
0
  }
4608
0
  *track_value  = NULL;
4609
0
  *track_offset = 0;
4610
4611
0
  return( 0 );
4612
0
}
4613
4614
/* Retrieves the current offset of the (media) data
4615
 * Returns 1 if successful or -1 on error
4616
 */
4617
int libodraw_handle_get_offset(
4618
     libodraw_handle_t *handle,
4619
     off64_t *offset,
4620
     libcerror_error_t **error )
4621
0
{
4622
0
  libodraw_internal_handle_t *internal_handle = NULL;
4623
0
  static char *function                       = "libodraw_handle_get_offset";
4624
4625
0
  if( handle == NULL )
4626
0
  {
4627
0
    libcerror_error_set(
4628
0
     error,
4629
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4630
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4631
0
     "%s: invalid handle.",
4632
0
     function );
4633
4634
0
    return( -1 );
4635
0
  }
4636
0
  internal_handle = (libodraw_internal_handle_t *) handle;
4637
4638
0
  if( internal_handle->io_handle == NULL )
4639
0
  {
4640
0
    libcerror_error_set(
4641
0
     error,
4642
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4643
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4644
0
     "%s: invalid handle - missing IO handle.",
4645
0
     function );
4646
4647
0
    return( -1 );
4648
0
  }
4649
0
  if( offset == NULL )
4650
0
  {
4651
0
    libcerror_error_set(
4652
0
     error,
4653
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4654
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4655
0
     "%s: invalid offset.",
4656
0
     function );
4657
4658
0
    return( -1 );
4659
0
  }
4660
0
  *offset = internal_handle->current_offset;
4661
4662
0
  return( 1 );
4663
0
}
4664
4665
/* Retrieves the size of the basename
4666
 * Returns 1 if successful, 0 if value not present or -1 on error
4667
 */
4668
int libodraw_internal_handle_get_basename_size(
4669
     libodraw_internal_handle_t *internal_handle,
4670
     size_t *basename_size,
4671
     libcerror_error_t **error )
4672
0
{
4673
0
  static char *function = "libodraw_internal_handle_get_basename_size";
4674
4675
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
4676
  int result            = 0;
4677
#endif
4678
4679
0
  if( internal_handle == NULL )
4680
0
  {
4681
0
    libcerror_error_set(
4682
0
     error,
4683
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4684
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4685
0
     "%s: invalid handle.",
4686
0
     function );
4687
4688
0
    return( -1 );
4689
0
  }
4690
0
  if( basename_size == NULL )
4691
0
  {
4692
0
    libcerror_error_set(
4693
0
     error,
4694
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4695
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4696
0
     "%s: invalid basename size.",
4697
0
     function );
4698
4699
0
    return( -1 );
4700
0
  }
4701
0
  if( internal_handle->basename == NULL )
4702
0
  {
4703
0
    return( 0 );
4704
0
  }
4705
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
4706
  if( libclocale_codepage == 0 )
4707
  {
4708
#if SIZEOF_WCHAR_T == 4
4709
    result = libuna_utf8_string_size_from_utf32(
4710
              (libuna_utf32_character_t *) internal_handle->basename,
4711
              internal_handle->basename_size,
4712
              basename_size,
4713
              error );
4714
#elif SIZEOF_WCHAR_T == 2
4715
    result = libuna_utf8_string_size_from_utf16(
4716
              (libuna_utf16_character_t *) internal_handle->basename,
4717
              internal_handle->basename_size,
4718
              basename_size,
4719
              error );
4720
#else
4721
#error Unsupported size of wchar_t
4722
#endif /* SIZEOF_WCHAR_T */
4723
  }
4724
  else
4725
  {
4726
#if SIZEOF_WCHAR_T == 4
4727
    result = libuna_byte_stream_size_from_utf32(
4728
              (libuna_utf32_character_t *) internal_handle->basename,
4729
              internal_handle->basename_size,
4730
              libclocale_codepage,
4731
              basename_size,
4732
              error );
4733
#elif SIZEOF_WCHAR_T == 2
4734
    result = libuna_byte_stream_size_from_utf16(
4735
              (libuna_utf16_character_t *) internal_handle->basename,
4736
              internal_handle->basename_size,
4737
              libclocale_codepage,
4738
              basename_size,
4739
              error );
4740
#else
4741
#error Unsupported size of wchar_t
4742
#endif /* SIZEOF_WCHAR_T */
4743
  }
4744
  if( result != 1 )
4745
  {
4746
    libcerror_error_set(
4747
     error,
4748
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
4749
     LIBCERROR_CONVERSION_ERROR_GENERIC,
4750
     "%s: unable to determine basename size.",
4751
     function );
4752
4753
    return( -1 );
4754
  }
4755
#else
4756
0
  *basename_size = internal_handle->basename_size;
4757
0
#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
4758
4759
0
  return( 1 );
4760
0
}
4761
4762
/* Retrieves the basename
4763
 * Returns 1 if successful, 0 if value not present or -1 on error
4764
 */
4765
int libodraw_internal_handle_get_basename(
4766
     libodraw_internal_handle_t *internal_handle,
4767
     char *basename,
4768
     size_t basename_size,
4769
     libcerror_error_t **error )
4770
0
{
4771
0
  static char *function       = "libodraw_internal_handle_get_basename";
4772
0
  size_t narrow_basename_size = 0;
4773
4774
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
4775
  int result                  = 0;
4776
#endif
4777
4778
0
  if( internal_handle == NULL )
4779
0
  {
4780
0
    libcerror_error_set(
4781
0
     error,
4782
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4783
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4784
0
     "%s: invalid handle.",
4785
0
     function );
4786
4787
0
    return( -1 );
4788
0
  }
4789
0
  if( basename == NULL )
4790
0
  {
4791
0
    libcerror_error_set(
4792
0
     error,
4793
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4794
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4795
0
     "%s: invalid basename.",
4796
0
     function );
4797
4798
0
    return( -1 );
4799
0
  }
4800
0
  if( internal_handle->basename == NULL )
4801
0
  {
4802
0
    return( 0 );
4803
0
  }
4804
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
4805
  if( libclocale_codepage == 0 )
4806
  {
4807
#if SIZEOF_WCHAR_T == 4
4808
    result = libuna_utf8_string_size_from_utf32(
4809
              (libuna_utf32_character_t *) internal_handle->basename,
4810
              internal_handle->basename_size,
4811
              &narrow_basename_size,
4812
              error );
4813
#elif SIZEOF_WCHAR_T == 2
4814
    result = libuna_utf8_string_size_from_utf16(
4815
              (libuna_utf16_character_t *) internal_handle->basename,
4816
              internal_handle->basename_size,
4817
              &narrow_basename_size,
4818
              error );
4819
#else
4820
#error Unsupported size of wchar_t
4821
#endif /* SIZEOF_WCHAR_T */
4822
  }
4823
  else
4824
  {
4825
#if SIZEOF_WCHAR_T == 4
4826
    result = libuna_byte_stream_size_from_utf32(
4827
              (libuna_utf32_character_t *) internal_handle->basename,
4828
              internal_handle->basename_size,
4829
              libclocale_codepage,
4830
              &narrow_basename_size,
4831
              error );
4832
#elif SIZEOF_WCHAR_T == 2
4833
    result = libuna_byte_stream_size_from_utf16(
4834
              (libuna_utf16_character_t *) internal_handle->basename,
4835
              internal_handle->basename_size,
4836
              libclocale_codepage,
4837
              &narrow_basename_size,
4838
              error );
4839
#else
4840
#error Unsupported size of wchar_t
4841
#endif /* SIZEOF_WCHAR_T */
4842
  }
4843
  if( result != 1 )
4844
  {
4845
    libcerror_error_set(
4846
     error,
4847
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
4848
     LIBCERROR_CONVERSION_ERROR_GENERIC,
4849
     "%s: unable to determine narrow basename size.",
4850
     function );
4851
4852
    return( -1 );
4853
  }
4854
#else
4855
0
  narrow_basename_size = internal_handle->basename_size;
4856
0
#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
4857
4858
0
  if( basename_size < narrow_basename_size )
4859
0
  {
4860
0
    libcerror_error_set(
4861
0
     error,
4862
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4863
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
4864
0
     "%s: basename too small.",
4865
0
     function );
4866
4867
0
    return( -1 );
4868
0
  }
4869
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
4870
  if( libclocale_codepage == 0 )
4871
  {
4872
#if SIZEOF_WCHAR_T == 4
4873
    result = libuna_utf8_string_copy_from_utf32(
4874
              (libuna_utf8_character_t *) basename,
4875
              basename_size,
4876
              (libuna_utf32_character_t *) internal_handle->basename,
4877
              internal_handle->basename_size,
4878
              error );
4879
#elif SIZEOF_WCHAR_T == 2
4880
    result = libuna_utf8_string_copy_from_utf16(
4881
              (libuna_utf8_character_t *) basename,
4882
              basename_size,
4883
              (libuna_utf16_character_t *) internal_handle->basename,
4884
              internal_handle->basename_size,
4885
              error );
4886
#else
4887
#error Unsupported size of wchar_t
4888
#endif /* SIZEOF_WCHAR_T */
4889
  }
4890
  else
4891
  {
4892
#if SIZEOF_WCHAR_T == 4
4893
    result = libuna_byte_stream_copy_from_utf32(
4894
              (uint8_t *) basename,
4895
              basename_size,
4896
              libclocale_codepage,
4897
              (libuna_utf32_character_t *) internal_handle->basename,
4898
              internal_handle->basename_size,
4899
              error );
4900
#elif SIZEOF_WCHAR_T == 2
4901
    result = libuna_byte_stream_copy_from_utf16(
4902
              (uint8_t *) basename,
4903
              basename_size,
4904
              libclocale_codepage,
4905
              (libuna_utf16_character_t *) internal_handle->basename,
4906
              internal_handle->basename_size,
4907
              error );
4908
#else
4909
#error Unsupported size of wchar_t
4910
#endif /* SIZEOF_WCHAR_T */
4911
  }
4912
  if( result != 1 )
4913
  {
4914
    libcerror_error_set(
4915
     error,
4916
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
4917
     LIBCERROR_CONVERSION_ERROR_GENERIC,
4918
     "%s: unable to set basename.",
4919
     function );
4920
4921
    return( -1 );
4922
  }
4923
#else
4924
0
  if( system_string_copy(
4925
0
       basename,
4926
0
       internal_handle->basename,
4927
0
       internal_handle->basename_size ) == NULL )
4928
0
  {
4929
0
    libcerror_error_set(
4930
0
     error,
4931
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
4932
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
4933
0
     "%s: unable to set basename.",
4934
0
     function );
4935
4936
0
    return( -1 );
4937
0
  }
4938
0
  basename[ internal_handle->basename_size - 1 ] = 0;
4939
0
#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
4940
4941
0
  return( 1 );
4942
0
}
4943
4944
/* Sets the basename
4945
 * Returns 1 if successful or -1 on error
4946
 */
4947
int libodraw_internal_handle_set_basename(
4948
     libodraw_internal_handle_t *internal_handle,
4949
     const char *basename,
4950
     size_t basename_length,
4951
     libcerror_error_t **error )
4952
0
{
4953
0
  static char *function = "libodraw_internal_handle_set_basename";
4954
4955
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
4956
  int result            = 0;
4957
#endif
4958
4959
0
  if( internal_handle == NULL )
4960
0
  {
4961
0
    libcerror_error_set(
4962
0
     error,
4963
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4964
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4965
0
     "%s: invalid handle.",
4966
0
     function );
4967
4968
0
    return( -1 );
4969
0
  }
4970
0
  if( basename == NULL )
4971
0
  {
4972
0
    libcerror_error_set(
4973
0
     error,
4974
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4975
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4976
0
     "%s: invalid basename.",
4977
0
     function );
4978
4979
0
    return( -1 );
4980
0
  }
4981
0
  if( internal_handle->basename != NULL )
4982
0
  {
4983
0
    memory_free(
4984
0
     internal_handle->basename );
4985
4986
0
    internal_handle->basename      = NULL;
4987
0
    internal_handle->basename_size = 0;
4988
0
  }
4989
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
4990
  if( libclocale_codepage == 0 )
4991
  {
4992
#if SIZEOF_WCHAR_T == 4
4993
    result = libuna_utf32_string_size_from_utf8(
4994
              (libuna_utf8_character_t *) basename,
4995
              basename_length + 1,
4996
              &( internal_handle->basename_size ),
4997
              error );
4998
#elif SIZEOF_WCHAR_T == 2
4999
    result = libuna_utf16_string_size_from_utf8(
5000
              (libuna_utf8_character_t *) basename,
5001
              basename_length + 1,
5002
              &( internal_handle->basename_size ),
5003
              error );
5004
#else
5005
#error Unsupported size of wchar_t
5006
#endif /* SIZEOF_WCHAR_T */
5007
  }
5008
  else
5009
  {
5010
#if SIZEOF_WCHAR_T == 4
5011
    result = libuna_utf32_string_size_from_byte_stream(
5012
              (uint8_t *) basename,
5013
              basename_length + 1,
5014
              libclocale_codepage,
5015
              &( internal_handle->basename_size ),
5016
              error );
5017
#elif SIZEOF_WCHAR_T == 2
5018
    result = libuna_utf16_string_size_from_byte_stream(
5019
              (uint8_t *) basename,
5020
              basename_length + 1,
5021
              libclocale_codepage,
5022
              &( internal_handle->basename_size ),
5023
              error );
5024
#else
5025
#error Unsupported size of wchar_t
5026
#endif /* SIZEOF_WCHAR_T */
5027
  }
5028
  if( result != 1 )
5029
  {
5030
    libcerror_error_set(
5031
     error,
5032
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
5033
     LIBCERROR_CONVERSION_ERROR_GENERIC,
5034
     "%s: unable to determine basename size.",
5035
     function );
5036
5037
    return( -1 );
5038
  }
5039
#else
5040
0
  internal_handle->basename_size = basename_length + 1;
5041
0
#endif
5042
0
  internal_handle->basename = system_string_allocate(
5043
0
                               internal_handle->basename_size );
5044
5045
0
  if( internal_handle->basename == NULL )
5046
0
  {
5047
0
    libcerror_error_set(
5048
0
     error,
5049
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
5050
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
5051
0
     "%s: unable to create basename.",
5052
0
     function );
5053
5054
0
    internal_handle->basename_size = 0;
5055
5056
0
    return( -1 );
5057
0
  }
5058
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
5059
  if( libclocale_codepage == 0 )
5060
  {
5061
#if SIZEOF_WCHAR_T == 4
5062
    result = libuna_utf32_string_copy_from_utf8(
5063
              (libuna_utf32_character_t *) internal_handle->basename,
5064
              internal_handle->basename_size,
5065
              (libuna_utf8_character_t *) basename,
5066
              basename_length + 1,
5067
              error );
5068
#elif SIZEOF_WCHAR_T == 2
5069
    result = libuna_utf16_string_copy_from_utf8(
5070
              (libuna_utf16_character_t *) internal_handle->basename,
5071
              internal_handle->basename_size,
5072
              (libuna_utf8_character_t *) basename,
5073
              basename_length + 1,
5074
              error );
5075
#else
5076
#error Unsupported size of wchar_t
5077
#endif /* SIZEOF_WCHAR_T */
5078
  }
5079
  else
5080
  {
5081
#if SIZEOF_WCHAR_T == 4
5082
    result = libuna_utf32_string_copy_from_byte_stream(
5083
              (libuna_utf32_character_t *) internal_handle->basename,
5084
              internal_handle->basename_size,
5085
              (uint8_t *) basename,
5086
              basename_length + 1,
5087
              libclocale_codepage,
5088
              error );
5089
#elif SIZEOF_WCHAR_T == 2
5090
    result = libuna_utf16_string_copy_from_byte_stream(
5091
              (libuna_utf16_character_t *) internal_handle->basename,
5092
              internal_handle->basename_size,
5093
              (uint8_t *) basename,
5094
              basename_length + 1,
5095
              libclocale_codepage,
5096
              error );
5097
#else
5098
#error Unsupported size of wchar_t
5099
#endif /* SIZEOF_WCHAR_T */
5100
  }
5101
  if( result != 1 )
5102
  {
5103
    libcerror_error_set(
5104
     error,
5105
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
5106
     LIBCERROR_CONVERSION_ERROR_GENERIC,
5107
     "%s: unable to set basename.",
5108
     function );
5109
5110
    memory_free(
5111
     internal_handle->basename );
5112
5113
    internal_handle->basename      = NULL;
5114
    internal_handle->basename_size = 0;
5115
5116
    return( -1 );
5117
  }
5118
#else
5119
0
  if( system_string_copy(
5120
0
       internal_handle->basename,
5121
0
       basename,
5122
0
       basename_length ) == NULL )
5123
0
  {
5124
0
    libcerror_error_set(
5125
0
     error,
5126
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
5127
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
5128
0
     "%s: unable to set basename.",
5129
0
     function );
5130
5131
0
    memory_free(
5132
0
     internal_handle->basename );
5133
5134
0
    internal_handle->basename      = NULL;
5135
0
    internal_handle->basename_size = 0;
5136
5137
0
    return( -1 );
5138
0
  }
5139
0
  internal_handle->basename[ basename_length ] = 0;
5140
0
#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
5141
5142
0
  return( 1 );
5143
0
}
5144
5145
#if defined( HAVE_WIDE_CHARACTER_TYPE )
5146
5147
/* Retrieves the size of the basename
5148
 * Returns 1 if successful, 0 if value not present or -1 on error
5149
 */
5150
int libodraw_internal_handle_get_basename_size_wide(
5151
     libodraw_internal_handle_t *internal_handle,
5152
     size_t *basename_size,
5153
     libcerror_error_t **error )
5154
{
5155
  static char *function = "libodraw_internal_handle_get_basename_size_wide";
5156
5157
#if !defined( HAVE_WIDE_SYSTEM_CHARACTER )
5158
  int result            = 0;
5159
#endif
5160
5161
  if( internal_handle == NULL )
5162
  {
5163
    libcerror_error_set(
5164
     error,
5165
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5166
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5167
     "%s: invalid handle.",
5168
     function );
5169
5170
    return( -1 );
5171
  }
5172
  if( basename_size == NULL )
5173
  {
5174
    libcerror_error_set(
5175
     error,
5176
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5177
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5178
     "%s: invalid basename size.",
5179
     function );
5180
5181
    return( -1 );
5182
  }
5183
  if( internal_handle->basename == NULL )
5184
  {
5185
    return( 0 );
5186
  }
5187
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
5188
  *basename_size = internal_handle->basename_size;
5189
#else
5190
  if( libclocale_codepage == 0 )
5191
  {
5192
#if SIZEOF_WCHAR_T == 4
5193
    result = libuna_utf32_string_size_from_utf8(
5194
              (libuna_utf8_character_t *) internal_handle->basename,
5195
              internal_handle->basename_size,
5196
              basename_size,
5197
              error );
5198
#elif SIZEOF_WCHAR_T == 2
5199
    result = libuna_utf16_string_size_from_utf8(
5200
              (libuna_utf8_character_t *) internal_handle->basename,
5201
              internal_handle->basename_size,
5202
              basename_size,
5203
              error );
5204
#else
5205
#error Unsupported size of wchar_t
5206
#endif /* SIZEOF_WCHAR_T */
5207
  }
5208
  else
5209
  {
5210
#if SIZEOF_WCHAR_T == 4
5211
    result = libuna_utf32_string_size_from_byte_stream(
5212
              (uint8_t *) internal_handle->basename,
5213
              internal_handle->basename_size,
5214
              libclocale_codepage,
5215
              basename_size,
5216
              error );
5217
#elif SIZEOF_WCHAR_T == 2
5218
    result = libuna_utf16_string_size_from_byte_stream(
5219
              (uint8_t *) internal_handle->basename,
5220
              internal_handle->basename_size,
5221
              libclocale_codepage,
5222
              basename_size,
5223
              error );
5224
#else
5225
#error Unsupported size of wchar_t
5226
#endif /* SIZEOF_WCHAR_T */
5227
  }
5228
  if( result != 1 )
5229
  {
5230
    libcerror_error_set(
5231
     error,
5232
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
5233
     LIBCERROR_CONVERSION_ERROR_GENERIC,
5234
     "%s: unable to determine basename size.",
5235
     function );
5236
5237
    return( -1 );
5238
  }
5239
#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
5240
  return( 1 );
5241
}
5242
5243
/* Retrieves the basename
5244
 * Returns 1 if successful, 0 if value not present or -1 on error
5245
 */
5246
int libodraw_internal_handle_get_basename_wide(
5247
     libodraw_internal_handle_t *internal_handle,
5248
     wchar_t *basename,
5249
     size_t basename_size,
5250
     libcerror_error_t **error )
5251
{
5252
  static char *function     = "libodraw_internal_handle_get_basename_wide";
5253
  size_t wide_basename_size = 0;
5254
5255
#if !defined( HAVE_WIDE_SYSTEM_CHARACTER )
5256
  int result                = 0;
5257
#endif
5258
5259
  if( internal_handle == NULL )
5260
  {
5261
    libcerror_error_set(
5262
     error,
5263
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5264
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5265
     "%s: invalid handle.",
5266
     function );
5267
5268
    return( -1 );
5269
  }
5270
  if( basename == NULL )
5271
  {
5272
    libcerror_error_set(
5273
     error,
5274
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5275
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5276
     "%s: invalid basename.",
5277
     function );
5278
5279
    return( -1 );
5280
  }
5281
  if( internal_handle->basename == NULL )
5282
  {
5283
    return( 0 );
5284
  }
5285
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
5286
  wide_basename_size = internal_handle->basename_size;
5287
#else
5288
  if( libclocale_codepage == 0 )
5289
  {
5290
#if SIZEOF_WCHAR_T == 4
5291
    result = libuna_utf32_string_size_from_utf8(
5292
              (libuna_utf8_character_t *) internal_handle->basename,
5293
              internal_handle->basename_size,
5294
              &wide_basename_size,
5295
              error );
5296
#elif SIZEOF_WCHAR_T == 2
5297
    result = libuna_utf16_string_size_from_utf8(
5298
              (libuna_utf8_character_t *) internal_handle->basename,
5299
              internal_handle->basename_size,
5300
              &wide_basename_size,
5301
              error );
5302
#else
5303
#error Unsupported size of wchar_t
5304
#endif /* SIZEOF_WCHAR_T */
5305
  }
5306
  else
5307
  {
5308
#if SIZEOF_WCHAR_T == 4
5309
    result = libuna_utf32_string_size_from_byte_stream(
5310
              (uint8_t *) internal_handle->basename,
5311
              internal_handle->basename_size,
5312
              libclocale_codepage,
5313
              &wide_basename_size,
5314
              error );
5315
#elif SIZEOF_WCHAR_T == 2
5316
    result = libuna_utf16_string_size_from_byte_stream(
5317
              (uint8_t *) internal_handle->basename,
5318
              internal_handle->basename_size,
5319
              libclocale_codepage,
5320
              &wide_basename_size,
5321
              error );
5322
#else
5323
#error Unsupported size of wchar_t
5324
#endif /* SIZEOF_WCHAR_T */
5325
  }
5326
  if( result != 1 )
5327
  {
5328
    libcerror_error_set(
5329
     error,
5330
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
5331
     LIBCERROR_CONVERSION_ERROR_GENERIC,
5332
     "%s: unable to determine basename size.",
5333
     function );
5334
5335
    return( -1 );
5336
  }
5337
#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
5338
  if( basename_size < wide_basename_size )
5339
  {
5340
    libcerror_error_set(
5341
     error,
5342
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5343
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
5344
     "%s: basename too small.",
5345
     function );
5346
5347
    return( -1 );
5348
  }
5349
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
5350
  if( system_string_copy(
5351
       basename,
5352
       internal_handle->basename,
5353
       internal_handle->basename_size ) == NULL )
5354
  {
5355
    libcerror_error_set(
5356
     error,
5357
     LIBCERROR_ERROR_DOMAIN_MEMORY,
5358
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
5359
     "%s: unable to set basename.",
5360
     function );
5361
5362
    return( -1 );
5363
  }
5364
  basename[ internal_handle->basename_size - 1 ] = 0;
5365
#else
5366
  if( libclocale_codepage == 0 )
5367
  {
5368
#if SIZEOF_WCHAR_T == 4
5369
    result = libuna_utf32_string_copy_from_utf8(
5370
              (libuna_utf32_character_t *) basename,
5371
              basename_size,
5372
              (libuna_utf8_character_t *) internal_handle->basename,
5373
              internal_handle->basename_size,
5374
              error );
5375
#elif SIZEOF_WCHAR_T == 2
5376
    result = libuna_utf16_string_copy_from_utf8(
5377
              (libuna_utf16_character_t *) basename,
5378
              basename_size,
5379
              (libuna_utf8_character_t *) internal_handle->basename,
5380
              internal_handle->basename_size,
5381
              error );
5382
#else
5383
#error Unsupported size of wchar_t
5384
#endif /* SIZEOF_WCHAR_T */
5385
  }
5386
  else
5387
  {
5388
#if SIZEOF_WCHAR_T == 4
5389
    result = libuna_utf32_string_copy_from_byte_stream(
5390
              (libuna_utf32_character_t *) basename,
5391
              basename_size,
5392
              (uint8_t *) internal_handle->basename,
5393
              internal_handle->basename_size,
5394
              libclocale_codepage,
5395
              error );
5396
#elif SIZEOF_WCHAR_T == 2
5397
    result = libuna_utf16_string_copy_from_byte_stream(
5398
              (libuna_utf16_character_t *) basename,
5399
              basename_size,
5400
              (uint8_t *) internal_handle->basename,
5401
              internal_handle->basename_size,
5402
              libclocale_codepage,
5403
              error );
5404
#else
5405
#error Unsupported size of wchar_t
5406
#endif /* SIZEOF_WCHAR_T */
5407
  }
5408
  if( result != 1 )
5409
  {
5410
    libcerror_error_set(
5411
     error,
5412
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
5413
     LIBCERROR_CONVERSION_ERROR_GENERIC,
5414
     "%s: unable to set basename.",
5415
     function );
5416
5417
    return( -1 );
5418
  }
5419
#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
5420
  return( 1 );
5421
}
5422
5423
/* Sets the basename
5424
 * Returns 1 if successful or -1 on error
5425
 */
5426
int libodraw_internal_handle_set_basename_wide(
5427
     libodraw_internal_handle_t *internal_handle,
5428
     const wchar_t *basename,
5429
     size_t basename_length,
5430
     libcerror_error_t **error )
5431
{
5432
  static char *function = "libodraw_internal_handle_set_basename_wide";
5433
5434
#if !defined( HAVE_WIDE_SYSTEM_CHARACTER )
5435
  int result            = 0;
5436
#endif
5437
5438
  if( internal_handle == NULL )
5439
  {
5440
    libcerror_error_set(
5441
     error,
5442
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5443
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5444
     "%s: invalid handle.",
5445
     function );
5446
5447
    return( -1 );
5448
  }
5449
  if( basename == NULL )
5450
  {
5451
    libcerror_error_set(
5452
     error,
5453
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5454
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5455
     "%s: invalid basename.",
5456
     function );
5457
5458
    return( -1 );
5459
  }
5460
  if( internal_handle->basename != NULL )
5461
  {
5462
    memory_free(
5463
     internal_handle->basename );
5464
5465
    internal_handle->basename      = NULL;
5466
    internal_handle->basename_size = 0;
5467
  }
5468
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
5469
  internal_handle->basename_size = basename_length + 1;
5470
#else
5471
  if( libclocale_codepage == 0 )
5472
  {
5473
#if SIZEOF_WCHAR_T == 4
5474
    result = libuna_utf8_string_size_from_utf32(
5475
              (libuna_utf32_character_t *) basename,
5476
              basename_length + 1,
5477
              &( internal_handle->basename_size ),
5478
              error );
5479
#elif SIZEOF_WCHAR_T == 2
5480
    result = libuna_utf8_string_size_from_utf16(
5481
              (libuna_utf16_character_t *) basename,
5482
              basename_length + 1,
5483
              &( internal_handle->basename_size ),
5484
              error );
5485
#else
5486
#error Unsupported size of wchar_t
5487
#endif /* SIZEOF_WCHAR_T */
5488
  }
5489
  else
5490
  {
5491
#if SIZEOF_WCHAR_T == 4
5492
    result = libuna_byte_stream_size_from_utf32(
5493
              (libuna_utf32_character_t *) basename,
5494
              basename_length + 1,
5495
              libclocale_codepage,
5496
              &( internal_handle->basename_size ),
5497
              error );
5498
#elif SIZEOF_WCHAR_T == 2
5499
    result = libuna_byte_stream_size_from_utf16(
5500
              (libuna_utf16_character_t *) basename,
5501
              basename_length + 1,
5502
              libclocale_codepage,
5503
              &( internal_handle->basename_size ),
5504
              error );
5505
#else
5506
#error Unsupported size of wchar_t
5507
#endif /* SIZEOF_WCHAR_T */
5508
  }
5509
  if( result != 1 )
5510
  {
5511
    libcerror_error_set(
5512
     error,
5513
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
5514
     LIBCERROR_CONVERSION_ERROR_GENERIC,
5515
     "%s: unable to determine basename size.",
5516
     function );
5517
5518
    return( -1 );
5519
  }
5520
#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
5521
  internal_handle->basename = system_string_allocate(
5522
                               internal_handle->basename_size );
5523
5524
  if( internal_handle->basename == NULL )
5525
  {
5526
    libcerror_error_set(
5527
     error,
5528
     LIBCERROR_ERROR_DOMAIN_MEMORY,
5529
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
5530
     "%s: unable to create basename.",
5531
     function );
5532
5533
    return( -1 );
5534
  }
5535
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
5536
  if( system_string_copy(
5537
       internal_handle->basename,
5538
       basename,
5539
       basename_length ) == NULL )
5540
  {
5541
    libcerror_error_set(
5542
     error,
5543
     LIBCERROR_ERROR_DOMAIN_MEMORY,
5544
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
5545
     "%s: unable to set basename.",
5546
     function );
5547
5548
    memory_free(
5549
     internal_handle->basename );
5550
5551
    internal_handle->basename      = NULL;
5552
    internal_handle->basename_size = 0;
5553
5554
    return( -1 );
5555
  }
5556
  internal_handle->basename[ basename_length ] = 0;
5557
#else
5558
  if( libclocale_codepage == 0 )
5559
  {
5560
#if SIZEOF_WCHAR_T == 4
5561
    result = libuna_utf8_string_copy_from_utf32(
5562
              (libuna_utf8_character_t *) internal_handle->basename,
5563
              internal_handle->basename_size,
5564
              (libuna_utf32_character_t *) basename,
5565
              basename_length + 1,
5566
              error );
5567
#elif SIZEOF_WCHAR_T == 2
5568
    result = libuna_utf8_string_copy_from_utf16(
5569
              (libuna_utf8_character_t *) internal_handle->basename,
5570
              internal_handle->basename_size,
5571
              (libuna_utf16_character_t *) basename,
5572
              basename_length + 1,
5573
              error );
5574
#else
5575
#error Unsupported size of wchar_t
5576
#endif /* SIZEOF_WCHAR_T */
5577
  }
5578
  else
5579
  {
5580
#if SIZEOF_WCHAR_T == 4
5581
    result = libuna_byte_stream_copy_from_utf32(
5582
              (uint8_t *) internal_handle->basename,
5583
              internal_handle->basename_size,
5584
              libclocale_codepage,
5585
              (libuna_utf32_character_t *) basename,
5586
              basename_length + 1,
5587
              error );
5588
#elif SIZEOF_WCHAR_T == 2
5589
    result = libuna_byte_stream_copy_from_utf16(
5590
              (uint8_t *) internal_handle->basename,
5591
              internal_handle->basename_size,
5592
              libclocale_codepage,
5593
              (libuna_utf16_character_t *) basename,
5594
              basename_length + 1,
5595
              error );
5596
#else
5597
#error Unsupported size of wchar_t
5598
#endif /* SIZEOF_WCHAR_T */
5599
  }
5600
  if( result != 1 )
5601
  {
5602
    libcerror_error_set(
5603
     error,
5604
     LIBCERROR_ERROR_DOMAIN_CONVERSION,
5605
     LIBCERROR_CONVERSION_ERROR_GENERIC,
5606
     "%s: unable to set basename.",
5607
     function );
5608
5609
    memory_free(
5610
     internal_handle->basename );
5611
5612
    internal_handle->basename      = NULL;
5613
    internal_handle->basename_size = 0;
5614
5615
    return( -1 );
5616
  }
5617
#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
5618
  return( 1 );
5619
}
5620
5621
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
5622
5623
/* Sets the maximum number of (concurrent) open file handles
5624
 * Returns 1 if successful or -1 on error
5625
 */
5626
int libodraw_handle_set_maximum_number_of_open_handles(
5627
     libodraw_handle_t *handle,
5628
     int maximum_number_of_open_handles,
5629
     libcerror_error_t **error )
5630
0
{
5631
0
  libodraw_internal_handle_t *internal_handle = NULL;
5632
0
  static char *function                       = "libodraw_handle_set_maximum_number_of_open_handles";
5633
5634
0
  if( handle == NULL )
5635
0
  {
5636
0
    libcerror_error_set(
5637
0
     error,
5638
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5639
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5640
0
     "%s: invalid handle.",
5641
0
     function );
5642
5643
0
    return( -1 );
5644
0
  }
5645
0
  internal_handle = (libodraw_internal_handle_t *) handle;
5646
5647
0
  if( internal_handle->data_file_io_pool != NULL )
5648
0
  {
5649
0
    if( libbfio_pool_set_maximum_number_of_open_handles(
5650
0
         internal_handle->data_file_io_pool,
5651
0
         maximum_number_of_open_handles,
5652
0
         error ) != 1 )
5653
0
    {
5654
0
      libcerror_error_set(
5655
0
       error,
5656
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5657
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5658
0
       "%s: unable to set maximum number of open handles in data files IO handle.",
5659
0
       function );
5660
5661
0
      return( -1 );
5662
0
    }
5663
0
  }
5664
0
  internal_handle->maximum_number_of_open_handles = maximum_number_of_open_handles;
5665
5666
0
  return( 1 );
5667
0
}
5668
5669
/* Sets the media values
5670
 * Returns 1 if successful or -1 on error
5671
 */
5672
int libodraw_handle_set_media_values(
5673
     libodraw_internal_handle_t *internal_handle,
5674
     libcerror_error_t **error )
5675
0
{
5676
0
  static char *function                 = "libodraw_handle_set_media_values";
5677
0
  libodraw_sector_range_t *sector_range = NULL;
5678
0
  libodraw_track_value_t *track_value   = NULL;
5679
0
  size64_t data_file_size               = 0;
5680
0
  uint64_t number_of_sectors            = 0;
5681
0
  int number_of_file_io_handles         = 0;
5682
0
  int number_of_sessions                = 0;
5683
0
  int number_of_tracks                  = 0;
5684
5685
0
  if( internal_handle == NULL )
5686
0
  {
5687
0
    libcerror_error_set(
5688
0
     error,
5689
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5690
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5691
0
     "%s: invalid handle.",
5692
0
     function );
5693
5694
0
    return( -1 );
5695
0
  }
5696
0
  if( internal_handle->io_handle == NULL )
5697
0
  {
5698
0
    libcerror_error_set(
5699
0
     error,
5700
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5701
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5702
0
     "%s: invalid handle - missing IO handle.",
5703
0
     function );
5704
5705
0
    return( -1 );
5706
0
  }
5707
0
  if( internal_handle->io_handle->bytes_per_sector == 0 )
5708
0
  {
5709
0
    libcerror_error_set(
5710
0
     error,
5711
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5712
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5713
0
     "%s: invalid handle - invalid IO handle - missing bytes per sector.",
5714
0
     function );
5715
5716
0
    return( -1 );
5717
0
  }
5718
0
  if( internal_handle->data_file_io_pool == NULL )
5719
0
  {
5720
0
    libcerror_error_set(
5721
0
     error,
5722
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5723
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5724
0
     "%s: invalid handle - missing data file IO pool.",
5725
0
     function );
5726
5727
0
    return( -1 );
5728
0
  }
5729
0
  if( libbfio_pool_get_number_of_handles(
5730
0
       internal_handle->data_file_io_pool,
5731
0
       &number_of_file_io_handles,
5732
0
       error ) != 1 )
5733
0
  {
5734
0
    libcerror_error_set(
5735
0
     error,
5736
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5737
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5738
0
     "%s: unable to retrieve number of file IO handles in pool.",
5739
0
     function );
5740
5741
0
    return( -1 );
5742
0
  }
5743
0
  if( libbfio_pool_get_size(
5744
0
       internal_handle->data_file_io_pool,
5745
0
       number_of_file_io_handles - 1,
5746
0
       &data_file_size,
5747
0
       error ) != 1 )
5748
0
  {
5749
0
    libcerror_error_set(
5750
0
     error,
5751
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5752
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5753
0
     "%s: unable to retrieve data file: %d size.",
5754
0
     function,
5755
0
     number_of_file_io_handles - 1 );
5756
5757
0
    return( -1 );
5758
0
  }
5759
0
  if( libcdata_array_get_number_of_entries(
5760
0
       internal_handle->tracks_array,
5761
0
       &number_of_tracks,
5762
0
       error ) != 1 )
5763
0
  {
5764
0
    libcerror_error_set(
5765
0
     error,
5766
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5767
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5768
0
     "%s: unable to retrieve number of elements in tracks array.",
5769
0
     function );
5770
5771
0
    return( -1 );
5772
0
  }
5773
0
  if( number_of_tracks == 0 )
5774
0
  {
5775
0
    libcerror_error_set(
5776
0
     error,
5777
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5778
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5779
0
     "%s: missing track values.",
5780
0
     function );
5781
5782
0
    return( -1 );
5783
0
  }
5784
0
  if( libcdata_array_get_entry_by_index(
5785
0
       internal_handle->tracks_array,
5786
0
       number_of_tracks - 1,
5787
0
       (intptr_t **) &track_value,
5788
0
       error ) != 1 )
5789
0
  {
5790
0
    libcerror_error_set(
5791
0
     error,
5792
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5793
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5794
0
     "%s: unable to retrieve track value: %d from array.",
5795
0
     function,
5796
0
     number_of_tracks - 1 );
5797
5798
0
    return( -1 );
5799
0
  }
5800
0
  if( track_value == NULL )
5801
0
  {
5802
0
    libcerror_error_set(
5803
0
     error,
5804
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5805
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5806
0
     "%s: missing track value: %d.",
5807
0
     function,
5808
0
     number_of_tracks - 1 );
5809
5810
0
    return( -1 );
5811
0
  }
5812
0
  if( track_value->bytes_per_sector == 0 )
5813
0
  {
5814
0
    libcerror_error_set(
5815
0
     error,
5816
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5817
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5818
0
     "%s: invalid track value: %d - missing bytes per sector.",
5819
0
     function,
5820
0
     number_of_tracks - 1 );
5821
5822
0
    return( -1 );
5823
0
  }
5824
0
  if( internal_handle->media_size == 0 )
5825
0
  {
5826
/* TODO currently assumes that last track start sector is always relative to the start of the media */
5827
0
    if( number_of_file_io_handles > 1 )
5828
0
    {
5829
0
      internal_handle->media_size = track_value->start_sector * track_value->bytes_per_sector;
5830
0
    }
5831
0
    internal_handle->media_size += data_file_size;
5832
5833
0
    internal_handle->number_of_sectors = internal_handle->media_size / track_value->bytes_per_sector;
5834
5835
0
    internal_handle->media_size = internal_handle->number_of_sectors * internal_handle->io_handle->bytes_per_sector;
5836
0
  }
5837
0
  if( track_value->number_of_sectors == 0 )
5838
0
  {
5839
0
    number_of_sectors = internal_handle->number_of_sectors - track_value->start_sector;
5840
5841
0
    if( number_of_sectors > (uint64_t) UINT32_MAX )
5842
0
    {
5843
0
      libcerror_error_set(
5844
0
       error,
5845
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5846
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5847
0
       "%s: number of sectors value out of bounds.",
5848
0
       function );
5849
5850
0
      return( -1 );
5851
0
    }
5852
0
    if( libodraw_track_value_set(
5853
0
         track_value,
5854
0
         track_value->start_sector,
5855
0
         number_of_sectors,
5856
0
         track_value->type,
5857
0
         track_value->data_file_index,
5858
0
         track_value->data_file_start_sector,
5859
0
         error ) != 1 )
5860
0
    {
5861
0
      libcerror_error_set(
5862
0
       error,
5863
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5864
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5865
0
       "%s: unable to set last track value.",
5866
0
       function );
5867
5868
0
      return( -1 );
5869
0
    }
5870
0
  }
5871
0
  if( libcdata_array_get_number_of_entries(
5872
0
       internal_handle->sessions_array,
5873
0
       &number_of_sessions,
5874
0
       error ) != 1 )
5875
0
  {
5876
0
    libcerror_error_set(
5877
0
     error,
5878
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5879
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5880
0
     "%s: unable to retrieve number of elements in sessions array.",
5881
0
     function );
5882
5883
0
    return( -1 );
5884
0
  }
5885
0
  if( number_of_sessions > 0 )
5886
0
  {
5887
0
    if( libcdata_array_get_entry_by_index(
5888
0
         internal_handle->sessions_array,
5889
0
         number_of_sessions - 1,
5890
0
         (intptr_t **) &sector_range,
5891
0
         error ) != 1 )
5892
0
    {
5893
0
      libcerror_error_set(
5894
0
       error,
5895
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5896
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5897
0
       "%s: unable to retrieve session sector range: %d from array.",
5898
0
       function,
5899
0
       number_of_sessions - 1 );
5900
5901
0
      return( -1 );
5902
0
    }
5903
0
    if( sector_range == NULL )
5904
0
    {
5905
0
      libcerror_error_set(
5906
0
       error,
5907
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5908
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5909
0
       "%s: missing sessions sector range: %d.",
5910
0
       function,
5911
0
       number_of_sessions - 1 );
5912
5913
0
      return( -1 );
5914
0
    }
5915
0
    if( sector_range->number_of_sectors == 0 )
5916
0
    {
5917
/* TODO currently assumes that last session is not followed by a lead-out */
5918
0
      number_of_sectors = internal_handle->number_of_sectors - sector_range->start_sector;
5919
5920
0
      if( number_of_sectors > (uint64_t) UINT32_MAX )
5921
0
      {
5922
0
        libcerror_error_set(
5923
0
         error,
5924
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
5925
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5926
0
         "%s: number of sectors value out of bounds.",
5927
0
         function );
5928
5929
0
        return( -1 );
5930
0
      }
5931
0
      if( libodraw_sector_range_set(
5932
0
           sector_range,
5933
0
           sector_range->start_sector,
5934
0
           number_of_sectors,
5935
0
           error ) != 1 )
5936
0
      {
5937
0
        libcerror_error_set(
5938
0
         error,
5939
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
5940
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5941
0
         "%s: unable to set last session sector range.",
5942
0
         function );
5943
5944
0
        return( -1 );
5945
0
      }
5946
0
    }
5947
0
  }
5948
0
  return( 1 );
5949
0
}
5950
5951
/* Retrieves the handle ASCII codepage
5952
 * Returns 1 if successful or -1 on error
5953
 */
5954
int libodraw_handle_get_ascii_codepage(
5955
     libodraw_handle_t *handle,
5956
     int *ascii_codepage,
5957
     libcerror_error_t **error )
5958
0
{
5959
0
  libodraw_internal_handle_t *internal_handle = NULL;
5960
0
  static char *function                       = "libodraw_handle_get_ascii_codepage";
5961
5962
0
  if( handle == NULL )
5963
0
  {
5964
0
    libcerror_error_set(
5965
0
     error,
5966
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5967
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5968
0
     "%s: invalid handle.",
5969
0
     function );
5970
5971
0
    return( -1 );
5972
0
  }
5973
0
  internal_handle = (libodraw_internal_handle_t *) handle;
5974
5975
0
  if( internal_handle->io_handle == NULL )
5976
0
  {
5977
0
    libcerror_error_set(
5978
0
     error,
5979
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5980
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5981
0
     "%s: invalid handle - missing IO handle.",
5982
0
     function );
5983
5984
0
    return( -1 );
5985
0
  }
5986
0
  if( ascii_codepage == NULL )
5987
0
  {
5988
0
    libcerror_error_set(
5989
0
     error,
5990
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5991
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5992
0
     "%s: invalid ASCII codepage.",
5993
0
     function );
5994
5995
0
    return( -1 );
5996
0
  }
5997
0
  *ascii_codepage = internal_handle->io_handle->ascii_codepage;
5998
5999
0
  return( 1 );
6000
0
}
6001
6002
/* Sets the handle ASCII codepage
6003
 * Returns 1 if successful or -1 on error
6004
 */
6005
int libodraw_handle_set_ascii_codepage(
6006
     libodraw_handle_t *handle,
6007
     int ascii_codepage,
6008
     libcerror_error_t **error )
6009
0
{
6010
0
  libodraw_internal_handle_t *internal_handle = NULL;
6011
0
  static char *function                       = "libodraw_handle_set_ascii_codepage";
6012
6013
0
  if( handle == NULL )
6014
0
  {
6015
0
    libcerror_error_set(
6016
0
     error,
6017
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6018
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6019
0
     "%s: invalid handle.",
6020
0
     function );
6021
6022
0
    return( -1 );
6023
0
  }
6024
0
  internal_handle = (libodraw_internal_handle_t *) handle;
6025
6026
0
  if( internal_handle->io_handle == NULL )
6027
0
  {
6028
0
    libcerror_error_set(
6029
0
     error,
6030
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6031
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6032
0
     "%s: invalid handle - missing IO handle.",
6033
0
     function );
6034
6035
0
    return( -1 );
6036
0
  }
6037
0
  if( ( ascii_codepage != LIBODRAW_CODEPAGE_ASCII )
6038
0
   && ( ascii_codepage != LIBODRAW_CODEPAGE_WINDOWS_874 )
6039
0
   && ( ascii_codepage != LIBODRAW_CODEPAGE_WINDOWS_932 )
6040
0
   && ( ascii_codepage != LIBODRAW_CODEPAGE_WINDOWS_936 )
6041
0
   && ( ascii_codepage != LIBODRAW_CODEPAGE_WINDOWS_949 )
6042
0
   && ( ascii_codepage != LIBODRAW_CODEPAGE_WINDOWS_950 )
6043
0
   && ( ascii_codepage != LIBODRAW_CODEPAGE_WINDOWS_1250 )
6044
0
   && ( ascii_codepage != LIBODRAW_CODEPAGE_WINDOWS_1251 )
6045
0
   && ( ascii_codepage != LIBODRAW_CODEPAGE_WINDOWS_1252 )
6046
0
   && ( ascii_codepage != LIBODRAW_CODEPAGE_WINDOWS_1253 )
6047
0
   && ( ascii_codepage != LIBODRAW_CODEPAGE_WINDOWS_1254 )
6048
0
   && ( ascii_codepage != LIBODRAW_CODEPAGE_WINDOWS_1255 )
6049
0
   && ( ascii_codepage != LIBODRAW_CODEPAGE_WINDOWS_1256 )
6050
0
   && ( ascii_codepage != LIBODRAW_CODEPAGE_WINDOWS_1257 )
6051
0
   && ( ascii_codepage != LIBODRAW_CODEPAGE_WINDOWS_1258 ) )
6052
0
  {
6053
0
    libcerror_error_set(
6054
0
     error,
6055
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6056
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
6057
0
     "%s: unsupported ASCII codepage.",
6058
0
     function );
6059
6060
0
    return( -1 );
6061
0
  }
6062
0
  internal_handle->io_handle->ascii_codepage = ascii_codepage;
6063
6064
0
  return( 1 );
6065
0
}
6066
6067
/* Retrieves the number of data files
6068
 * Returns 1 if successful or -1 on error
6069
 */
6070
int libodraw_handle_get_number_of_data_files(
6071
     libodraw_handle_t *handle,
6072
     int *number_of_data_files,
6073
     libcerror_error_t **error )
6074
0
{
6075
0
  libodraw_internal_handle_t *internal_handle = NULL;
6076
0
  static char *function                       = "libodraw_handle_get_number_of_data_files";
6077
6078
0
  if( handle == NULL )
6079
0
  {
6080
0
    libcerror_error_set(
6081
0
     error,
6082
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6083
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6084
0
     "%s: invalid handle.",
6085
0
     function );
6086
6087
0
    return( -1 );
6088
0
  }
6089
0
  internal_handle = (libodraw_internal_handle_t *) handle;
6090
6091
0
  if( libcdata_array_get_number_of_entries(
6092
0
       internal_handle->data_file_descriptors_array,
6093
0
       number_of_data_files,
6094
0
       error ) != 1 )
6095
0
  {
6096
0
    libcerror_error_set(
6097
0
     error,
6098
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6099
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6100
0
     "%s: unable to retrieve number of entries in data file descriptors array.",
6101
0
     function );
6102
6103
0
    return( -1 );
6104
0
  }
6105
0
  return( 1 );
6106
0
}
6107
6108
/* Retrieves a data file
6109
 * Returns 1 if successful or -1 on error
6110
 */
6111
int libodraw_handle_get_data_file(
6112
     libodraw_handle_t *handle,
6113
     int index,
6114
     libodraw_data_file_t **data_file,
6115
     libcerror_error_t **error )
6116
0
{
6117
0
  libodraw_data_file_descriptor_t *data_file_descriptor = NULL;
6118
0
  libodraw_internal_handle_t *internal_handle           = NULL;
6119
0
  static char *function                                 = "libodraw_handle_get_data_file";
6120
6121
0
  if( handle == NULL )
6122
0
  {
6123
0
    libcerror_error_set(
6124
0
     error,
6125
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6126
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6127
0
     "%s: invalid handle.",
6128
0
     function );
6129
6130
0
    return( -1 );
6131
0
  }
6132
0
  internal_handle = (libodraw_internal_handle_t *) handle;
6133
6134
0
  if( libcdata_array_get_entry_by_index(
6135
0
       internal_handle->data_file_descriptors_array,
6136
0
       index,
6137
0
       (intptr_t **) &data_file_descriptor,
6138
0
       error ) != 1 )
6139
0
  {
6140
0
    libcerror_error_set(
6141
0
     error,
6142
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6143
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6144
0
     "%s: unable to retrieve data file descriptor: %d from array.",
6145
0
     function,
6146
0
     index );
6147
6148
0
    return( -1 );
6149
0
  }
6150
0
  if( libodraw_data_file_initialize(
6151
0
       data_file,
6152
0
       internal_handle,
6153
0
       data_file_descriptor,
6154
0
       error ) != 1 )
6155
0
  {
6156
0
    libcerror_error_set(
6157
0
     error,
6158
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6159
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6160
0
     "%s: unable to create data file.",
6161
0
     function );
6162
6163
0
    return( -1 );
6164
0
  }
6165
0
  return( 1 );
6166
0
}
6167
6168
/* Appends a data file
6169
 * Returns 1 if successful or -1 on error
6170
 */
6171
int libodraw_handle_append_data_file(
6172
     libodraw_handle_t *handle,
6173
     const char *name,
6174
     size_t name_length,
6175
     uint8_t type,
6176
     libcerror_error_t **error )
6177
645k
{
6178
645k
  libodraw_data_file_descriptor_t *data_file_descriptor = NULL;
6179
645k
  libodraw_internal_handle_t *internal_handle           = NULL;
6180
645k
  static char *function                                 = "libodraw_handle_append_data_file";
6181
645k
  int entry_index                                       = 0;
6182
6183
645k
  if( handle == NULL )
6184
0
  {
6185
0
    libcerror_error_set(
6186
0
     error,
6187
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6188
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6189
0
     "%s: invalid handle.",
6190
0
     function );
6191
6192
0
    return( -1 );
6193
0
  }
6194
645k
  internal_handle = (libodraw_internal_handle_t *) handle;
6195
6196
645k
  if( name == NULL )
6197
0
  {
6198
0
    libcerror_error_set(
6199
0
     error,
6200
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6201
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6202
0
     "%s: invalid name.",
6203
0
     function );
6204
6205
0
    return( -1 );
6206
0
  }
6207
645k
  if( ( type != LIBODRAW_FILE_TYPE_UNKNOWN )
6208
645k
   && ( type != LIBODRAW_FILE_TYPE_BINARY_LITTLE_ENDIAN )
6209
645k
   && ( type != LIBODRAW_FILE_TYPE_BINARY_BIG_ENDIAN )
6210
645k
   && ( type != LIBODRAW_FILE_TYPE_AUDIO_AIFF )
6211
645k
   && ( type != LIBODRAW_FILE_TYPE_AUDIO_WAVE )
6212
645k
   && ( type != LIBODRAW_FILE_TYPE_AUDIO_MPEG1_LAYER3 ) )
6213
0
  {
6214
0
    libcerror_error_set(
6215
0
     error,
6216
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6217
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
6218
0
     "%s: unsupported type codepage.",
6219
0
     function );
6220
6221
0
    return( -1 );
6222
0
  }
6223
645k
  if( libodraw_data_file_descriptor_initialize(
6224
645k
       &data_file_descriptor,
6225
645k
       error ) != 1 )
6226
0
  {
6227
0
    libcerror_error_set(
6228
0
     error,
6229
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6230
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6231
0
     "%s: unable to create data file descriptor.",
6232
0
     function );
6233
6234
0
    goto on_error;
6235
0
  }
6236
645k
  if( libodraw_data_file_descriptor_set_name(
6237
645k
       data_file_descriptor,
6238
645k
       name,
6239
645k
       name_length,
6240
645k
       error ) != 1 )
6241
0
  {
6242
0
    libcerror_error_set(
6243
0
     error,
6244
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6245
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6246
0
     "%s: unable to set name in data file descriptor.",
6247
0
     function );
6248
6249
0
    goto on_error;
6250
0
  }
6251
645k
  data_file_descriptor->type = type;
6252
6253
645k
  if( libcdata_array_append_entry(
6254
645k
       internal_handle->data_file_descriptors_array,
6255
645k
       &entry_index,
6256
645k
       (intptr_t *) data_file_descriptor,
6257
645k
       error ) != 1 )
6258
0
  {
6259
0
    libcerror_error_set(
6260
0
     error,
6261
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6262
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
6263
0
     "%s: unable to append data file descriptor.",
6264
0
     function );
6265
6266
0
    goto on_error;
6267
0
  }
6268
645k
  return( 1 );
6269
6270
0
on_error:
6271
0
  if( data_file_descriptor != NULL )
6272
0
  {
6273
0
    libodraw_data_file_descriptor_free(
6274
0
     &data_file_descriptor,
6275
0
     NULL );
6276
0
  }
6277
0
  return( -1 );
6278
645k
}
6279
6280
#if defined( HAVE_WIDE_CHARACTER_TYPE )
6281
6282
/* Appends a data file
6283
 * Returns 1 if successful or -1 on error
6284
 */
6285
int libodraw_handle_append_data_file_wide(
6286
     libodraw_handle_t *handle,
6287
     const wchar_t *name,
6288
     size_t name_length,
6289
     uint8_t type,
6290
     libcerror_error_t **error )
6291
{
6292
  libodraw_data_file_descriptor_t *data_file_descriptor = NULL;
6293
  libodraw_internal_handle_t *internal_handle           = NULL;
6294
  static char *function                                 = "libodraw_handle_append_data_file_wide";
6295
  int entry_index                                       = 0;
6296
6297
  if( handle == NULL )
6298
  {
6299
    libcerror_error_set(
6300
     error,
6301
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6302
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6303
     "%s: invalid handle.",
6304
     function );
6305
6306
    return( -1 );
6307
  }
6308
  internal_handle = (libodraw_internal_handle_t *) handle;
6309
6310
  if( name == NULL )
6311
  {
6312
    libcerror_error_set(
6313
     error,
6314
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6315
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6316
     "%s: invalid name.",
6317
     function );
6318
6319
    return( -1 );
6320
  }
6321
  if( ( type != LIBODRAW_FILE_TYPE_UNKNOWN )
6322
   && ( type != LIBODRAW_FILE_TYPE_BINARY_LITTLE_ENDIAN )
6323
   && ( type != LIBODRAW_FILE_TYPE_BINARY_BIG_ENDIAN )
6324
   && ( type != LIBODRAW_FILE_TYPE_AUDIO_AIFF )
6325
   && ( type != LIBODRAW_FILE_TYPE_AUDIO_WAVE )
6326
   && ( type != LIBODRAW_FILE_TYPE_AUDIO_MPEG1_LAYER3 ) )
6327
  {
6328
    libcerror_error_set(
6329
     error,
6330
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6331
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
6332
     "%s: unsupported type codepage.",
6333
     function );
6334
6335
    return( -1 );
6336
  }
6337
  if( libodraw_data_file_descriptor_initialize(
6338
       &data_file_descriptor,
6339
       error ) != 1 )
6340
  {
6341
    libcerror_error_set(
6342
     error,
6343
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6344
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6345
     "%s: unable to create data file descriptor.",
6346
     function );
6347
6348
    goto on_error;
6349
  }
6350
  if( libodraw_data_file_descriptor_set_name_wide(
6351
       data_file_descriptor,
6352
       name,
6353
       name_length,
6354
       error ) != 1 )
6355
  {
6356
    libcerror_error_set(
6357
     error,
6358
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6359
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6360
     "%s: unable to set name in data file descriptor.",
6361
     function );
6362
6363
    goto on_error;
6364
  }
6365
  data_file_descriptor->type = type;
6366
6367
  if( libcdata_array_append_entry(
6368
       internal_handle->data_file_descriptors_array,
6369
       &entry_index,
6370
       (intptr_t *) data_file_descriptor,
6371
       error ) != 1 )
6372
  {
6373
    libcerror_error_set(
6374
     error,
6375
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6376
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
6377
     "%s: unable to append data file descriptor.",
6378
     function );
6379
6380
    goto on_error;
6381
  }
6382
  return( 1 );
6383
6384
on_error:
6385
  if( data_file_descriptor != NULL )
6386
  {
6387
    libodraw_data_file_descriptor_free(
6388
     &data_file_descriptor,
6389
     NULL );
6390
  }
6391
  return( -1 );
6392
}
6393
6394
#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
6395
6396
/* Retrieves the number of media size
6397
 * Returns 1 if successful or -1 on error
6398
 */
6399
int libodraw_handle_get_media_size(
6400
     libodraw_handle_t *handle,
6401
     size64_t *media_size,
6402
     libcerror_error_t **error )
6403
0
{
6404
0
  libodraw_internal_handle_t *internal_handle = NULL;
6405
0
  static char *function                       = "libodraw_handle_get_media_size";
6406
6407
0
  if( handle == NULL )
6408
0
  {
6409
0
    libcerror_error_set(
6410
0
     error,
6411
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6412
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6413
0
     "%s: invalid handle.",
6414
0
     function );
6415
6416
0
    return( -1 );
6417
0
  }
6418
0
  internal_handle = (libodraw_internal_handle_t *) handle;
6419
6420
0
  if( media_size == NULL )
6421
0
  {
6422
0
    libcerror_error_set(
6423
0
     error,
6424
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6425
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6426
0
     "%s: invalid media size.",
6427
0
     function );
6428
6429
0
    return( -1 );
6430
0
  }
6431
0
  *media_size = internal_handle->media_size;
6432
6433
0
  return( 1 );
6434
0
}
6435
6436
/* Retrieves the number of bytes per sector
6437
 * Returns 1 if successful or -1 on error
6438
 */
6439
int libodraw_handle_get_bytes_per_sector(
6440
     libodraw_handle_t *handle,
6441
     uint32_t *bytes_per_sector,
6442
     libcerror_error_t **error )
6443
0
{
6444
0
  libodraw_internal_handle_t *internal_handle = NULL;
6445
0
  static char *function                       = "libodraw_handle_get_bytes_per_sector";
6446
6447
0
  if( handle == NULL )
6448
0
  {
6449
0
    libcerror_error_set(
6450
0
     error,
6451
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6452
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6453
0
     "%s: invalid handle.",
6454
0
     function );
6455
6456
0
    return( -1 );
6457
0
  }
6458
0
  internal_handle = (libodraw_internal_handle_t *) handle;
6459
6460
0
  if( internal_handle->io_handle == NULL )
6461
0
  {
6462
0
    libcerror_error_set(
6463
0
     error,
6464
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6465
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6466
0
     "%s: invalid handle - missing IO handle.",
6467
0
     function );
6468
6469
0
    return( -1 );
6470
0
  }
6471
0
  if( bytes_per_sector == NULL )
6472
0
  {
6473
0
    libcerror_error_set(
6474
0
     error,
6475
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6476
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6477
0
     "%s: invalid bytes per sector.",
6478
0
     function );
6479
6480
0
    return( -1 );
6481
0
  }
6482
0
  *bytes_per_sector = internal_handle->io_handle->bytes_per_sector;
6483
6484
0
  return( 1 );
6485
0
}
6486
6487
/* Sets the number of bytes per sector
6488
 * Returns 1 if successful or -1 on error
6489
 */
6490
int libodraw_handle_set_bytes_per_sector(
6491
     libodraw_handle_t *handle,
6492
     uint32_t bytes_per_sector,
6493
     libcerror_error_t **error )
6494
0
{
6495
0
  libodraw_internal_handle_t *internal_handle = NULL;
6496
0
  static char *function                       = "libodraw_handle_set_bytes_per_sector";
6497
6498
0
  if( handle == NULL )
6499
0
  {
6500
0
    libcerror_error_set(
6501
0
     error,
6502
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6503
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6504
0
     "%s: invalid handle.",
6505
0
     function );
6506
6507
0
    return( -1 );
6508
0
  }
6509
0
  internal_handle = (libodraw_internal_handle_t *) handle;
6510
6511
0
  if( internal_handle->io_handle == NULL )
6512
0
  {
6513
0
    libcerror_error_set(
6514
0
     error,
6515
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6516
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6517
0
     "%s: invalid handle - missing IO handle.",
6518
0
     function );
6519
6520
0
    return( -1 );
6521
0
  }
6522
/* TODO add support for 2352 */
6523
0
  if( bytes_per_sector != 2048 )
6524
0
  {
6525
0
    libcerror_error_set(
6526
0
     error,
6527
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6528
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
6529
0
     "%s: unsupported bytes per sector.",
6530
0
     function );
6531
6532
0
    return( -1 );
6533
0
  }
6534
0
  internal_handle->io_handle->bytes_per_sector = bytes_per_sector;
6535
6536
0
  return( 1 );
6537
0
}
6538
6539
/* Retrieves the number of sectors
6540
 * Returns 1 if successful or -1 on error
6541
 */
6542
int libodraw_handle_get_number_of_sectors(
6543
     libodraw_handle_t *handle,
6544
     uint64_t *number_of_sectors,
6545
     libcerror_error_t **error )
6546
0
{
6547
0
  libodraw_internal_handle_t *internal_handle = NULL;
6548
0
  static char *function                       = "libodraw_handle_get_number_of_sectors";
6549
6550
0
  if( handle == NULL )
6551
0
  {
6552
0
    libcerror_error_set(
6553
0
     error,
6554
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6555
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6556
0
     "%s: invalid handle.",
6557
0
     function );
6558
6559
0
    return( -1 );
6560
0
  }
6561
0
  internal_handle = (libodraw_internal_handle_t *) handle;
6562
6563
0
  if( number_of_sectors == NULL )
6564
0
  {
6565
0
    libcerror_error_set(
6566
0
     error,
6567
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6568
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6569
0
     "%s: invalid number of sectors.",
6570
0
     function );
6571
6572
0
    return( -1 );
6573
0
  }
6574
0
  *number_of_sectors = internal_handle->number_of_sectors;
6575
6576
0
  return( 1 );
6577
0
}
6578
6579
/* Retrieves the number of sessions
6580
 * Returns 1 if successful or -1 on error
6581
 */
6582
int libodraw_handle_get_number_of_sessions(
6583
     libodraw_handle_t *handle,
6584
     int *number_of_sessions,
6585
     libcerror_error_t **error )
6586
0
{
6587
0
  libodraw_internal_handle_t *internal_handle = NULL;
6588
0
  static char *function                       = "libodraw_handle_get_number_of_sessions";
6589
6590
0
  if( handle == NULL )
6591
0
  {
6592
0
    libcerror_error_set(
6593
0
     error,
6594
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6595
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6596
0
     "%s: invalid handle.",
6597
0
     function );
6598
6599
0
    return( -1 );
6600
0
  }
6601
0
  internal_handle = (libodraw_internal_handle_t *) handle;
6602
6603
0
  if( libcdata_array_get_number_of_entries(
6604
0
       internal_handle->sessions_array,
6605
0
       number_of_sessions,
6606
0
       error ) != 1 )
6607
0
  {
6608
0
    libcerror_error_set(
6609
0
     error,
6610
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6611
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6612
0
     "%s: unable to retrieve number of elements in sessions array.",
6613
0
     function );
6614
6615
0
    return( -1 );
6616
0
  }
6617
0
  return( 1 );
6618
0
}
6619
6620
/* Retrieves a session
6621
 * Returns 1 if successful or -1 on error
6622
 */
6623
int libodraw_handle_get_session(
6624
     libodraw_handle_t *handle,
6625
     int index,
6626
     uint64_t *start_sector,
6627
     uint64_t *number_of_sectors,
6628
     libcerror_error_t **error )
6629
0
{
6630
0
  libodraw_internal_handle_t *internal_handle = NULL;
6631
0
  libodraw_sector_range_t *sector_range       = NULL;
6632
0
  static char *function                       = "libodraw_handle_get_session";
6633
6634
0
  if( handle == NULL )
6635
0
  {
6636
0
    libcerror_error_set(
6637
0
     error,
6638
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6639
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6640
0
     "%s: invalid handle.",
6641
0
     function );
6642
6643
0
    return( -1 );
6644
0
  }
6645
0
  internal_handle = (libodraw_internal_handle_t *) handle;
6646
6647
0
  if( libcdata_array_get_entry_by_index(
6648
0
       internal_handle->sessions_array,
6649
0
       index,
6650
0
       (intptr_t **) &sector_range,
6651
0
       error ) != 1 )
6652
0
  {
6653
0
    libcerror_error_set(
6654
0
     error,
6655
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6656
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6657
0
     "%s: unable to retrieve session sector range: %d from array.",
6658
0
     function,
6659
0
     index );
6660
6661
0
    return( -1 );
6662
0
  }
6663
0
  if( libodraw_sector_range_get(
6664
0
       sector_range,
6665
0
       start_sector,
6666
0
       number_of_sectors,
6667
0
       error ) != 1 )
6668
0
  {
6669
0
    libcerror_error_set(
6670
0
     error,
6671
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6672
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6673
0
     "%s: unable to retrieve sector range.",
6674
0
     function );
6675
6676
0
    return( -1 );
6677
0
  }
6678
0
  return( 1 );
6679
0
}
6680
6681
/* Appends a session
6682
 * Returns 1 if successful or -1 on error
6683
 */
6684
int libodraw_handle_append_session(
6685
     libodraw_handle_t *handle,
6686
     uint64_t start_sector,
6687
     uint64_t number_of_sectors,
6688
     libcerror_error_t **error )
6689
0
{
6690
0
  libodraw_internal_handle_t *internal_handle = NULL;
6691
0
  libodraw_sector_range_t *sector_range       = NULL;
6692
0
  static char *function                       = "libodraw_handle_append_session";
6693
0
  int entry_index                             = 0;
6694
6695
0
  if( handle == NULL )
6696
0
  {
6697
0
    libcerror_error_set(
6698
0
     error,
6699
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6700
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6701
0
     "%s: invalid handle.",
6702
0
     function );
6703
6704
0
    return( -1 );
6705
0
  }
6706
0
  internal_handle = (libodraw_internal_handle_t *) handle;
6707
6708
0
  if( libodraw_sector_range_initialize(
6709
0
       &sector_range,
6710
0
       error ) != 1 )
6711
0
  {
6712
0
    libcerror_error_set(
6713
0
     error,
6714
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6715
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6716
0
     "%s: unable to create sector range.",
6717
0
     function );
6718
6719
0
    goto on_error;
6720
0
  }
6721
0
  if( libodraw_sector_range_set(
6722
0
       sector_range,
6723
0
       start_sector,
6724
0
       number_of_sectors,
6725
0
       error ) != 1 )
6726
0
  {
6727
0
    libcerror_error_set(
6728
0
     error,
6729
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6730
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6731
0
     "%s: unable to set sector range.",
6732
0
     function );
6733
6734
0
    goto on_error;
6735
0
  }
6736
0
  if( libcdata_array_append_entry(
6737
0
       internal_handle->sessions_array,
6738
0
       &entry_index,
6739
0
       (intptr_t *) sector_range,
6740
0
       error ) != 1 )
6741
0
  {
6742
0
    libcerror_error_set(
6743
0
     error,
6744
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6745
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
6746
0
     "%s: unable to append session sector range to array.",
6747
0
     function );
6748
6749
0
    goto on_error;
6750
0
  }
6751
0
  return( 1 );
6752
6753
0
on_error:
6754
0
  if( sector_range != NULL )
6755
0
  {
6756
0
    libodraw_sector_range_free(
6757
0
     &sector_range,
6758
0
     NULL );
6759
0
  }
6760
0
  return( -1 );
6761
0
}
6762
6763
/* Retrieves the number of lead-outs
6764
 * Returns 1 if successful or -1 on error
6765
 */
6766
int libodraw_handle_get_number_of_lead_outs(
6767
     libodraw_handle_t *handle,
6768
     int *number_of_lead_outs,
6769
     libcerror_error_t **error )
6770
0
{
6771
0
  libodraw_internal_handle_t *internal_handle = NULL;
6772
0
  static char *function                       = "libodraw_handle_get_number_of_lead_outs";
6773
6774
0
  if( handle == NULL )
6775
0
  {
6776
0
    libcerror_error_set(
6777
0
     error,
6778
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6779
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6780
0
     "%s: invalid handle.",
6781
0
     function );
6782
6783
0
    return( -1 );
6784
0
  }
6785
0
  internal_handle = (libodraw_internal_handle_t *) handle;
6786
6787
0
  if( libcdata_array_get_number_of_entries(
6788
0
       internal_handle->lead_outs_array,
6789
0
       number_of_lead_outs,
6790
0
       error ) != 1 )
6791
0
  {
6792
0
    libcerror_error_set(
6793
0
     error,
6794
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6795
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6796
0
     "%s: unable to retrieve number of elements in lead-outs array.",
6797
0
     function );
6798
6799
0
    return( -1 );
6800
0
  }
6801
0
  return( 1 );
6802
0
}
6803
6804
/* Retrieves a lead-out
6805
 * Returns 1 if successful or -1 on error
6806
 */
6807
int libodraw_handle_get_lead_out(
6808
     libodraw_handle_t *handle,
6809
     int index,
6810
     uint64_t *start_sector,
6811
     uint64_t *number_of_sectors,
6812
     libcerror_error_t **error )
6813
0
{
6814
0
  libodraw_internal_handle_t *internal_handle = NULL;
6815
0
  libodraw_sector_range_t *sector_range       = NULL;
6816
0
  static char *function                       = "libodraw_handle_get_lead_out";
6817
6818
0
  if( handle == NULL )
6819
0
  {
6820
0
    libcerror_error_set(
6821
0
     error,
6822
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6823
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6824
0
     "%s: invalid handle.",
6825
0
     function );
6826
6827
0
    return( -1 );
6828
0
  }
6829
0
  internal_handle = (libodraw_internal_handle_t *) handle;
6830
6831
0
  if( libcdata_array_get_entry_by_index(
6832
0
       internal_handle->lead_outs_array,
6833
0
       index,
6834
0
       (intptr_t **) &sector_range,
6835
0
       error ) != 1 )
6836
0
  {
6837
0
    libcerror_error_set(
6838
0
     error,
6839
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6840
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6841
0
     "%s: unable to retrieve lead-out sector range: %d from array.",
6842
0
     function,
6843
0
     index );
6844
6845
0
    return( -1 );
6846
0
  }
6847
0
  if( libodraw_sector_range_get(
6848
0
       sector_range,
6849
0
       start_sector,
6850
0
       number_of_sectors,
6851
0
       error ) != 1 )
6852
0
  {
6853
0
    libcerror_error_set(
6854
0
     error,
6855
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6856
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6857
0
     "%s: unable to retrieve sector range.",
6858
0
     function );
6859
6860
0
    return( -1 );
6861
0
  }
6862
0
  return( 1 );
6863
0
}
6864
6865
/* Appends a lead-out
6866
 * Returns 1 if successful or -1 on error
6867
 */
6868
int libodraw_handle_append_lead_out(
6869
     libodraw_handle_t *handle,
6870
     uint64_t start_sector,
6871
     uint64_t number_of_sectors,
6872
     libcerror_error_t **error )
6873
0
{
6874
0
  libodraw_internal_handle_t *internal_handle = NULL;
6875
0
  libodraw_sector_range_t *sector_range       = NULL;
6876
0
  static char *function                       = "libodraw_handle_append_lead_out";
6877
0
  int entry_index                             = 0;
6878
6879
0
  if( handle == NULL )
6880
0
  {
6881
0
    libcerror_error_set(
6882
0
     error,
6883
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6884
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6885
0
     "%s: invalid handle.",
6886
0
     function );
6887
6888
0
    return( -1 );
6889
0
  }
6890
0
  internal_handle = (libodraw_internal_handle_t *) handle;
6891
6892
0
  if( libodraw_sector_range_initialize(
6893
0
       &sector_range,
6894
0
       error ) != 1 )
6895
0
  {
6896
0
    libcerror_error_set(
6897
0
     error,
6898
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6899
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6900
0
     "%s: unable to create sector range.",
6901
0
     function );
6902
6903
0
    goto on_error;
6904
0
  }
6905
0
  if( libodraw_sector_range_set(
6906
0
       sector_range,
6907
0
       start_sector,
6908
0
       number_of_sectors,
6909
0
       error ) != 1 )
6910
0
  {
6911
0
    libcerror_error_set(
6912
0
     error,
6913
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6914
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6915
0
     "%s: unable to set sector range.",
6916
0
     function );
6917
6918
0
    goto on_error;
6919
0
  }
6920
0
  if( libcdata_array_append_entry(
6921
0
       internal_handle->lead_outs_array,
6922
0
       &entry_index,
6923
0
       (intptr_t *) sector_range,
6924
0
       error ) != 1 )
6925
0
  {
6926
0
    libcerror_error_set(
6927
0
     error,
6928
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6929
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
6930
0
     "%s: unable to append lead-out sector range to array.",
6931
0
     function );
6932
6933
0
    goto on_error;
6934
0
  }
6935
0
  return( 1 );
6936
6937
0
on_error:
6938
0
  if( sector_range != NULL )
6939
0
  {
6940
0
    libodraw_sector_range_free(
6941
0
     &sector_range,
6942
0
     NULL );
6943
0
  }
6944
0
  return( -1 );
6945
0
}
6946
6947
/* Retrieves the number of tracks
6948
 * Returns 1 if successful or -1 on error
6949
 */
6950
int libodraw_handle_get_number_of_tracks(
6951
     libodraw_handle_t *handle,
6952
     int *number_of_tracks,
6953
     libcerror_error_t **error )
6954
0
{
6955
0
  libodraw_internal_handle_t *internal_handle = NULL;
6956
0
  static char *function                       = "libodraw_handle_get_number_of_tracks";
6957
6958
0
  if( handle == NULL )
6959
0
  {
6960
0
    libcerror_error_set(
6961
0
     error,
6962
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6963
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6964
0
     "%s: invalid handle.",
6965
0
     function );
6966
6967
0
    return( -1 );
6968
0
  }
6969
0
  internal_handle = (libodraw_internal_handle_t *) handle;
6970
6971
0
  if( libcdata_array_get_number_of_entries(
6972
0
       internal_handle->tracks_array,
6973
0
       number_of_tracks,
6974
0
       error ) != 1 )
6975
0
  {
6976
0
    libcerror_error_set(
6977
0
     error,
6978
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6979
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6980
0
     "%s: unable to retrieve number of elements in tracks array.",
6981
0
     function );
6982
6983
0
    return( -1 );
6984
0
  }
6985
0
  return( 1 );
6986
0
}
6987
6988
/* Retrieves a track
6989
 * Returns 1 if successful or -1 on error
6990
 */
6991
int libodraw_handle_get_track(
6992
     libodraw_handle_t *handle,
6993
     int index,
6994
     uint64_t *start_sector,
6995
     uint64_t *number_of_sectors,
6996
     uint8_t *type,
6997
     int *data_file_index,
6998
     uint64_t *data_file_start_sector,
6999
     libcerror_error_t **error )
7000
0
{
7001
0
  libodraw_internal_handle_t *internal_handle = NULL;
7002
0
  libodraw_track_value_t *track_value         = NULL;
7003
0
  static char *function                       = "libodraw_handle_get_track";
7004
7005
0
  if( handle == NULL )
7006
0
  {
7007
0
    libcerror_error_set(
7008
0
     error,
7009
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7010
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7011
0
     "%s: invalid handle.",
7012
0
     function );
7013
7014
0
    return( -1 );
7015
0
  }
7016
0
  internal_handle = (libodraw_internal_handle_t *) handle;
7017
7018
0
  if( libcdata_array_get_entry_by_index(
7019
0
       internal_handle->tracks_array,
7020
0
       index,
7021
0
       (intptr_t **) &track_value,
7022
0
       error ) != 1 )
7023
0
  {
7024
0
    libcerror_error_set(
7025
0
     error,
7026
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7027
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7028
0
     "%s: unable to retrieve track value: %d from array.",
7029
0
     function,
7030
0
     index );
7031
7032
0
    return( -1 );
7033
0
  }
7034
0
  if( libodraw_track_value_get(
7035
0
       track_value,
7036
0
       start_sector,
7037
0
       number_of_sectors,
7038
0
       type,
7039
0
       data_file_index,
7040
0
       data_file_start_sector,
7041
0
       error ) != 1 )
7042
0
  {
7043
0
    libcerror_error_set(
7044
0
     error,
7045
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7046
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7047
0
     "%s: unable to retrieve track value.",
7048
0
     function );
7049
7050
0
    return( -1 );
7051
0
  }
7052
0
  return( 1 );
7053
0
}
7054
7055
/* Appends a track
7056
 * Returns 1 if successful or -1 on error
7057
 */
7058
int libodraw_handle_append_track(
7059
     libodraw_handle_t *handle,
7060
     uint64_t start_sector,
7061
     uint64_t number_of_sectors,
7062
     uint8_t type,
7063
     int data_file_index,
7064
     uint64_t data_file_start_sector,
7065
     libcerror_error_t **error )
7066
17.8k
{
7067
17.8k
  libodraw_internal_handle_t *internal_handle = NULL;
7068
17.8k
  libodraw_track_value_t *track_value         = NULL;
7069
17.8k
  static char *function                       = "libodraw_handle_append_track";
7070
17.8k
  int entry_index                             = 0;
7071
7072
17.8k
  if( handle == NULL )
7073
0
  {
7074
0
    libcerror_error_set(
7075
0
     error,
7076
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7077
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7078
0
     "%s: invalid handle.",
7079
0
     function );
7080
7081
0
    return( -1 );
7082
0
  }
7083
17.8k
  internal_handle = (libodraw_internal_handle_t *) handle;
7084
7085
17.8k
  if( libodraw_track_value_initialize(
7086
17.8k
       &track_value,
7087
17.8k
       error ) != 1 )
7088
0
  {
7089
0
    libcerror_error_set(
7090
0
     error,
7091
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7092
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
7093
0
     "%s: unable to create track value.",
7094
0
     function );
7095
7096
0
    goto on_error;
7097
0
  }
7098
17.8k
  if( libodraw_track_value_set(
7099
17.8k
       track_value,
7100
17.8k
       start_sector,
7101
17.8k
       number_of_sectors,
7102
17.8k
       type,
7103
17.8k
       data_file_index,
7104
17.8k
       data_file_start_sector,
7105
17.8k
       error ) != 1 )
7106
89
  {
7107
89
    libcerror_error_set(
7108
89
     error,
7109
89
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7110
89
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7111
89
     "%s: unable to set track value.",
7112
89
     function );
7113
7114
89
    goto on_error;
7115
89
  }
7116
17.7k
  if( libcdata_array_append_entry(
7117
17.7k
       internal_handle->tracks_array,
7118
17.7k
       &entry_index,
7119
17.7k
       (intptr_t *) track_value,
7120
17.7k
       error ) != 1 )
7121
0
  {
7122
0
    libcerror_error_set(
7123
0
     error,
7124
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7125
0
     LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
7126
0
     "%s: unable to append track to array.",
7127
0
     function );
7128
7129
0
    goto on_error;
7130
0
  }
7131
17.7k
  return( 1 );
7132
7133
89
on_error:
7134
89
  if( track_value != NULL )
7135
89
  {
7136
89
    libodraw_track_value_free(
7137
89
     &track_value,
7138
89
     NULL );
7139
89
  }
7140
89
  return( -1 );
7141
17.7k
}
7142
7143