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