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 **) &sector_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 **) &sector_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 **) &sector_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 **) &sector_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 		     &current_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 		     &current_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 		     &current_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 		     &current_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 		     &current_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 		     &current_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 **) &sector_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 **) &sector_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 	     &sector_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 		 &sector_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 **) &sector_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 	     &sector_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 		 &sector_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