1 /*
2  * Handle functions
3  *
4  * Copyright (c) 2006-2014, Joachim Metz <joachim.metz@gmail.com>
5  *
6  * Refer to AUTHORS for acknowledgements.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #include <common.h>
23 #include <memory.h>
24 #include <narrow_string.h>
25 #include <types.h>
26 #include <wide_string.h>
27 
28 #if defined( TIME_WITH_SYS_TIME )
29 #include <sys/time.h>
30 #include <time.h>
31 #elif defined( HAVE_SYS_TIME_H )
32 #include <sys/time.h>
33 #else
34 #include <time.h>
35 #endif
36 
37 #include "libewf_checksum.h"
38 #include "libewf_chunk_data.h"
39 #include "libewf_chunk_table.h"
40 #include "libewf_compression.h"
41 #include "libewf_definitions.h"
42 #include "libewf_empty_block.h"
43 #include "libewf_file_entry.h"
44 #include "libewf_handle.h"
45 #include "libewf_header_values.h"
46 #include "libewf_io_handle.h"
47 #include "libewf_libbfio.h"
48 #include "libewf_libcdata.h"
49 #include "libewf_libcerror.h"
50 #include "libewf_libcnotify.h"
51 #include "libewf_libfcache.h"
52 #include "libewf_libfvalue.h"
53 #include "libewf_libmfdata.h"
54 #include "libewf_metadata.h"
55 #include "libewf_sector_range.h"
56 #include "libewf_segment_file.h"
57 #include "libewf_single_file_entry.h"
58 #include "libewf_single_files.h"
59 #include "libewf_single_file_tree.h"
60 #include "libewf_types.h"
61 #include "libewf_unused.h"
62 #include "libewf_write_io_handle.h"
63 
64 #include "ewf_data.h"
65 #include "ewf_definitions.h"
66 #include "ewf_file_header.h"
67 
68 /* Initialize the handle
69  * The handle must point to a NULL pointer to be allocated
70  * Returns 1 if successful or -1 on error
71  */
libewf_handle_initialize(libewf_handle_t ** handle,libcerror_error_t ** error)72 int libewf_handle_initialize(
73      libewf_handle_t **handle,
74      libcerror_error_t **error )
75 {
76 	libewf_internal_handle_t *internal_handle = NULL;
77 	static char *function                     = "libewf_handle_initialize";
78 
79 	if( handle == NULL )
80 	{
81 		libcerror_error_set(
82 		 error,
83 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
84 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
85 		 "%s: invalid handle.",
86 		 function );
87 
88 		return( -1 );
89 	}
90 	if( *handle != NULL )
91 	{
92 		libcerror_error_set(
93 		 error,
94 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
95 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
96 		 "%s: invalid handle value already set.",
97 		 function );
98 
99 		return( -1 );
100 	}
101 	internal_handle = memory_allocate_structure(
102 	                   libewf_internal_handle_t );
103 
104 	if( internal_handle == NULL )
105 	{
106 		libcerror_error_set(
107 		 error,
108 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
109 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
110 		 "%s: unable to create handle.",
111 		 function );
112 
113 		goto on_error;
114 	}
115 	if( memory_set(
116 	     internal_handle,
117 	     0,
118 	     sizeof( libewf_internal_handle_t ) ) == NULL )
119 	{
120 		libcerror_error_set(
121 		 error,
122 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
123 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
124 		 "%s: unable to clear handle.",
125 		 function );
126 
127 		memory_free(
128 		 internal_handle );
129 
130 		return( -1 );
131 	}
132 	if( libewf_io_handle_initialize(
133 	     &( internal_handle->io_handle ),
134 	     error ) != 1 )
135 	{
136 		libcerror_error_set(
137 		 error,
138 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
139 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
140 		 "%s: unable to create IO handle.",
141 		 function );
142 
143 		goto on_error;
144 	}
145 	if( libewf_media_values_initialize(
146 	     &( internal_handle->media_values ),
147 	     error ) != 1 )
148 	{
149 		libcerror_error_set(
150 		 error,
151 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
152 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
153 		 "%s: unable to create media values.",
154 		 function );
155 
156 		goto on_error;
157 	}
158 	if( libcdata_array_initialize(
159 	     &( internal_handle->sessions ),
160 	     0,
161 	     error ) != 1 )
162 	{
163 		libcerror_error_set(
164 		 error,
165 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
166 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
167 		 "%s: unable to create sessions array.",
168 		 function );
169 
170 		goto on_error;
171 	}
172 	if( libcdata_array_initialize(
173 	     &( internal_handle->tracks ),
174 	     0,
175 	     error ) != 1 )
176 	{
177 		libcerror_error_set(
178 		 error,
179 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
180 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
181 		 "%s: unable to create tracks array.",
182 		 function );
183 
184 		goto on_error;
185 	}
186 	if( libcdata_range_list_initialize(
187 	     &( internal_handle->acquiry_errors ),
188 	     error ) != 1 )
189 	{
190 		libcerror_error_set(
191 		 error,
192 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
193 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
194 		 "%s: unable to create acquiry errors range list.",
195 		 function );
196 
197 		goto on_error;
198 	}
199 	internal_handle->date_format                    = LIBEWF_DATE_FORMAT_CTIME;
200 	internal_handle->maximum_number_of_open_handles = LIBBFIO_POOL_UNLIMITED_NUMBER_OF_OPEN_HANDLES;
201 
202 	*handle = (libewf_handle_t *) internal_handle;
203 
204 	return( 1 );
205 
206 on_error:
207 	if( internal_handle != NULL )
208 	{
209 		if( internal_handle->tracks != NULL )
210 		{
211 			libcdata_array_free(
212 			 &( internal_handle->tracks ),
213 			 NULL,
214 			 NULL );
215 		}
216 		if( internal_handle->sessions != NULL )
217 		{
218 			libcdata_array_free(
219 			 &( internal_handle->sessions ),
220 			 NULL,
221 			 NULL );
222 		}
223 		if( internal_handle->media_values != NULL )
224 		{
225 			libewf_media_values_free(
226 			 &( internal_handle->media_values ),
227 			 NULL );
228 		}
229 		if( internal_handle->io_handle != NULL )
230 		{
231 			libewf_io_handle_free(
232 			 &( internal_handle->io_handle ),
233 			 NULL );
234 		}
235 		memory_free(
236 		 internal_handle );
237 	}
238 	return( -1 );
239 }
240 
241 /* Frees the handle including elements
242  * Returns 1 if successful or -1 on error
243  */
libewf_handle_free(libewf_handle_t ** handle,libcerror_error_t ** error)244 int libewf_handle_free(
245      libewf_handle_t **handle,
246      libcerror_error_t **error )
247 {
248 	libewf_internal_handle_t *internal_handle = NULL;
249 	static char *function                     = "libewf_internal_handle_free";
250 	int result                                = 1;
251 
252 	if( handle == NULL )
253 	{
254 		libcerror_error_set(
255 		 error,
256 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
257 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
258 		 "%s: invalid handle.",
259 		 function );
260 
261 		return( -1 );
262 	}
263 	if( *handle != NULL )
264 	{
265 		internal_handle = (libewf_internal_handle_t *) *handle;
266 
267 		if( internal_handle->file_io_pool != NULL )
268 		{
269 			if( libewf_handle_close(
270 			     *handle,
271 			     error ) != 0 )
272 			{
273 				libcerror_error_set(
274 				 error,
275 				 LIBCERROR_ERROR_DOMAIN_IO,
276 				 LIBCERROR_IO_ERROR_CLOSE_FAILED,
277 				 "%s: unable to close handle.",
278 				 function );
279 
280 				result = -1;
281 			}
282 		}
283 		*handle = NULL;
284 
285 		if( libewf_io_handle_free(
286 		     &( internal_handle->io_handle ),
287 		     error ) != 1 )
288 		{
289 			libcerror_error_set(
290 			 error,
291 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
292 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
293 			 "%s: unable to free IO handle.",
294 			 function );
295 
296 			result = -1;
297 		}
298 		if( libewf_media_values_free(
299 		     &( internal_handle->media_values ),
300 		     error ) != 1 )
301 		{
302 			libcerror_error_set(
303 			 error,
304 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
305 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
306 			 "%s: unable to free media values.",
307 			 function );
308 
309 			result = -1;
310 		}
311 		if( libcdata_array_free(
312 		     &( internal_handle->sessions ),
313 		     (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
314 		     error ) != 1 )
315 		{
316 			libcerror_error_set(
317 			 error,
318 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
319 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
320 			 "%s: unable to free sessions array.",
321 			 function );
322 
323 			result = -1;
324 		}
325 		if( libcdata_array_free(
326 		     &( internal_handle->tracks ),
327 		     (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
328 		     error ) != 1 )
329 		{
330 			libcerror_error_set(
331 			 error,
332 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
333 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
334 			 "%s: unable to free tracks array.",
335 			 function );
336 
337 			result = -1;
338 		}
339 		if( libcdata_range_list_free(
340 		     &( internal_handle->acquiry_errors ),
341 		     NULL,
342 		     error ) != 1 )
343 		{
344 			libcerror_error_set(
345 			 error,
346 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
347 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
348 			 "%s: unable to free acquiry errors range list.",
349 			 function );
350 
351 			result = -1;
352 		}
353 		memory_free(
354 		 internal_handle );
355 	}
356 	return( result );
357 }
358 
359 /* Clones the handle including elements
360  * Returns 1 if successful or -1 on error
361  */
libewf_handle_clone(libewf_handle_t ** destination_handle,libewf_handle_t * source_handle,libcerror_error_t ** error)362 int libewf_handle_clone(
363      libewf_handle_t **destination_handle,
364      libewf_handle_t *source_handle,
365      libcerror_error_t **error )
366 {
367 	libewf_internal_handle_t *internal_destination_handle = NULL;
368 	libewf_internal_handle_t *internal_source_handle      = NULL;
369 	static char *function                                 = "libewf_handle_clone";
370 
371 	if( destination_handle == NULL )
372 	{
373 		libcerror_error_set(
374 		 error,
375 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
376 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
377 		 "%s: invalid destination handle.",
378 		 function );
379 
380 		return( -1 );
381 	}
382 	if( *destination_handle != NULL )
383 	{
384 		libcerror_error_set(
385 		 error,
386 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
387 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
388 		 "%s: invalid destination handle value already set.",
389 		 function );
390 
391 		return( -1 );
392 	}
393 	if( source_handle == NULL )
394 	{
395 		*destination_handle = NULL;
396 
397 		return( 1 );
398 	}
399 	internal_source_handle = (libewf_internal_handle_t *) source_handle;
400 
401 	if( internal_source_handle->io_handle == NULL )
402 	{
403 		libcerror_error_set(
404 		 error,
405 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
406 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
407 		 "%s: invalid source handle - missing IO handle.",
408 		 function );
409 
410 		return( -1 );
411 	}
412 	if( ( internal_source_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
413 	{
414 		libcerror_error_set(
415 		 error,
416 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
417 		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
418 		 "%s: write access currently not supported.",
419 		 function );
420 
421 		return( -1 );
422 	}
423 	internal_destination_handle = memory_allocate_structure(
424 			               libewf_internal_handle_t );
425 
426 	if( internal_destination_handle == NULL )
427 	{
428 		libcerror_error_set(
429 		 error,
430 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
431 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
432 		 "%s: unable to create destination handle.",
433 		 function );
434 
435 		goto on_error;
436 	}
437 	if( memory_set(
438 	     internal_destination_handle,
439 	     0,
440 	     sizeof( libewf_internal_handle_t ) ) == NULL )
441 	{
442 		libcerror_error_set(
443 		 error,
444 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
445 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
446 		 "%s: unable to clear destination handle.",
447 		 function );
448 
449 		goto on_error;
450 	}
451 	if( libewf_io_handle_clone(
452 	     &( internal_destination_handle->io_handle ),
453 	     internal_source_handle->io_handle,
454 	     error ) != 1 )
455 	{
456 		libcerror_error_set(
457 		 error,
458 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
459 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
460 		 "%s: unable to create destination IO handle.",
461 		 function );
462 
463 		goto on_error;
464 	}
465 	if( libewf_media_values_clone(
466 	     &( internal_destination_handle->media_values ),
467 	     internal_source_handle->media_values,
468 	     error ) != 1 )
469 	{
470 		libcerror_error_set(
471 		 error,
472 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
473 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
474 		 "%s: unable to create destination media values.",
475 		 function );
476 
477 		goto on_error;
478 	}
479 	if( libcdata_array_clone(
480 	     &( internal_destination_handle->sessions ),
481 	     internal_source_handle->sessions,
482 	     (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
483 	     (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libewf_sector_range_clone,
484 	     error ) != 1 )
485 	{
486 		libcerror_error_set(
487 		 error,
488 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
489 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
490 		 "%s: unable to create destination sessions array.",
491 		 function );
492 
493 		goto on_error;
494 	}
495 	if( libcdata_array_clone(
496 	     &( internal_destination_handle->tracks ),
497 	     internal_source_handle->tracks,
498 	     (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
499 	     (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libewf_sector_range_clone,
500 	     error ) != 1 )
501 	{
502 		libcerror_error_set(
503 		 error,
504 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
505 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
506 		 "%s: unable to create destination tracks array.",
507 		 function );
508 
509 		goto on_error;
510 	}
511 	if( libcdata_range_list_clone(
512 	     &( internal_destination_handle->acquiry_errors ),
513 	     internal_source_handle->acquiry_errors,
514 	     NULL,
515 	     NULL,
516 	     error ) != 1 )
517 	{
518 		libcerror_error_set(
519 		 error,
520 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
521 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
522 		 "%s: unable to create destination acquiry errors range list.",
523 		 function );
524 
525 		goto on_error;
526 	}
527 	if( internal_source_handle->file_io_pool != NULL )
528 	{
529 		if( libbfio_pool_clone(
530 		     &( internal_destination_handle->file_io_pool ),
531 		     internal_source_handle->file_io_pool,
532 		     error ) != 1 )
533 		{
534 			libcerror_error_set(
535 			 error,
536 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
537 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
538 			 "%s: unable to create destination file IO pool.",
539 			 function );
540 
541 			goto on_error;
542 		}
543 		internal_destination_handle->file_io_pool_created_in_library = 1;
544 	}
545 	if( internal_source_handle->read_io_handle != NULL )
546 	{
547 		if( libewf_read_io_handle_clone(
548 		     &( internal_destination_handle->read_io_handle ),
549 		     internal_source_handle->read_io_handle,
550 		     error ) != 1 )
551 		{
552 			libcerror_error_set(
553 			 error,
554 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
555 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
556 			 "%s: unable to create destination read IO handle.",
557 			 function );
558 
559 			goto on_error;
560 		}
561 	}
562 	if( internal_source_handle->write_io_handle != NULL )
563 	{
564 		if( libewf_write_io_handle_clone(
565 		     &( internal_destination_handle->write_io_handle ),
566 		     internal_source_handle->write_io_handle,
567 		     error ) != 1 )
568 		{
569 			libcerror_error_set(
570 			 error,
571 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
572 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
573 			 "%s: unable to create destination write IO handle.",
574 			 function );
575 
576 			goto on_error;
577 		}
578 	}
579 	if( internal_source_handle->segment_files_list != NULL )
580 	{
581 		if( libmfdata_file_list_clone(
582 		     &( internal_destination_handle->segment_files_list ),
583 		     internal_source_handle->segment_files_list,
584 		     error ) != 1 )
585 		{
586 			libcerror_error_set(
587 			 error,
588 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
589 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
590 			 "%s: unable to create destination segment files list.",
591 			 function );
592 
593 			goto on_error;
594 		}
595 	}
596 	if( internal_source_handle->delta_segment_files_list != NULL )
597 	{
598 		if( libmfdata_file_list_clone(
599 		     &( internal_destination_handle->delta_segment_files_list ),
600 		     internal_source_handle->delta_segment_files_list,
601 		     error ) != 1 )
602 		{
603 			libcerror_error_set(
604 			 error,
605 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
606 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
607 			 "%s: unable to create destination delta segment files list.",
608 			 function );
609 
610 			goto on_error;
611 		}
612 	}
613 	if( internal_source_handle->segment_files_cache != NULL )
614 	{
615 		if( libfcache_cache_clone(
616 		     &( internal_destination_handle->segment_files_cache ),
617 		     internal_source_handle->segment_files_cache,
618 		     error ) != 1 )
619 		{
620 			libcerror_error_set(
621 			 error,
622 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
623 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
624 			 "%s: unable to create destination segment files cache.",
625 			 function );
626 
627 			goto on_error;
628 		}
629 	}
630 	if( internal_source_handle->segment_table != NULL )
631 	{
632 		if( libewf_segment_table_clone(
633 		     &( internal_destination_handle->segment_table ),
634 		     internal_source_handle->segment_table,
635 		     error ) != 1 )
636 		{
637 			libcerror_error_set(
638 			 error,
639 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
640 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
641 			 "%s: unable to create destination segment table.",
642 			 function );
643 
644 			goto on_error;
645 		}
646 	}
647 	if( internal_source_handle->delta_segment_table != NULL )
648 	{
649 		if( libewf_segment_table_clone(
650 		     &( internal_destination_handle->delta_segment_table ),
651 		     internal_source_handle->delta_segment_table,
652 		     error ) != 1 )
653 		{
654 			libcerror_error_set(
655 			 error,
656 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
657 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
658 			 "%s: unable to create destination delta segment table.",
659 			 function );
660 
661 			goto on_error;
662 		}
663 	}
664 	if( internal_source_handle->chunk_table_list != NULL )
665 	{
666 		if( libmfdata_list_clone(
667 		     &( internal_destination_handle->chunk_table_list ),
668 		     internal_source_handle->chunk_table_list,
669 		     error ) != 1 )
670 		{
671 			libcerror_error_set(
672 			 error,
673 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
674 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
675 			 "%s: unable to create destination chunk table list.",
676 			 function );
677 
678 			goto on_error;
679 		}
680 	}
681 	if( internal_source_handle->chunk_table_cache != NULL )
682 	{
683 		if( libfcache_cache_clone(
684 		     &( internal_destination_handle->chunk_table_cache ),
685 		     internal_source_handle->chunk_table_cache,
686 		     error ) != 1 )
687 		{
688 			libcerror_error_set(
689 			 error,
690 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
691 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
692 			 "%s: unable to create destination chunk table cache.",
693 			 function );
694 
695 			goto on_error;
696 		}
697 	}
698 	if( internal_source_handle->header_sections != NULL )
699 	{
700 		if( libewf_header_sections_clone(
701 		     &( internal_destination_handle->header_sections ),
702 		     internal_source_handle->header_sections,
703 		     error ) != 1 )
704 		{
705 			libcerror_error_set(
706 			 error,
707 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
708 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
709 			 "%s: unable to create destination header sections.",
710 			 function );
711 
712 			goto on_error;
713 		}
714 	}
715 	if( internal_source_handle->hash_sections != NULL )
716 	{
717 		if( libewf_hash_sections_clone(
718 		     &( internal_destination_handle->hash_sections ),
719 		     internal_source_handle->hash_sections,
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 destination hash sections.",
727 			 function );
728 
729 			goto on_error;
730 		}
731 	}
732 	if( internal_source_handle->header_values != NULL )
733 	{
734 		if( libfvalue_table_clone(
735 		     &( internal_destination_handle->header_values ),
736 		     internal_source_handle->header_values,
737 		     error ) != 1 )
738 		{
739 			libcerror_error_set(
740 			 error,
741 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
742 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
743 			 "%s: unable to create destination header values.",
744 			 function );
745 
746 			goto on_error;
747 		}
748 		internal_destination_handle->header_values_parsed = internal_source_handle->header_values_parsed;
749 	}
750 	if( internal_source_handle->hash_values != NULL )
751 	{
752 		if( libfvalue_table_clone(
753 		     &( internal_destination_handle->hash_values ),
754 		     internal_source_handle->hash_values,
755 		     error ) != 1 )
756 		{
757 			libcerror_error_set(
758 			 error,
759 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
760 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
761 			 "%s: unable to create destination hash values.",
762 			 function );
763 
764 			goto on_error;
765 		}
766 		internal_destination_handle->hash_values_parsed = internal_source_handle->hash_values_parsed;
767 	}
768 	internal_destination_handle->maximum_number_of_open_handles = internal_source_handle->maximum_number_of_open_handles;
769 	internal_destination_handle->date_format                    = internal_source_handle->date_format;
770 
771 	*destination_handle = (libewf_handle_t *) internal_destination_handle;
772 
773 	return( 1 );
774 
775 on_error:
776 	if( internal_destination_handle != NULL )
777 	{
778 		if( internal_destination_handle->hash_values != NULL )
779 		{
780 			libfvalue_table_free(
781 			 &( internal_destination_handle->hash_values ),
782 			 NULL );
783 		}
784 		if( internal_destination_handle->header_values != NULL )
785 		{
786 			libfvalue_table_free(
787 			 &( internal_destination_handle->header_values ),
788 			 NULL );
789 		}
790 		if( internal_destination_handle->hash_sections != NULL )
791 		{
792 			libewf_hash_sections_free(
793 			 &( internal_destination_handle->hash_sections ),
794 			 NULL );
795 		}
796 		if( internal_destination_handle->header_sections != NULL )
797 		{
798 			libewf_header_sections_free(
799 			 &( internal_destination_handle->header_sections ),
800 			 NULL );
801 		}
802 		if( internal_destination_handle->chunk_table_list != NULL )
803 		{
804 			libmfdata_list_free(
805 			 &( internal_destination_handle->chunk_table_list ),
806 			 NULL );
807 		}
808 		if( internal_destination_handle->chunk_table_cache != NULL )
809 		{
810 			libfcache_cache_free(
811 			 &( internal_destination_handle->chunk_table_cache ),
812 			 NULL );
813 		}
814 		if( internal_destination_handle->delta_segment_table != NULL )
815 		{
816 			libewf_segment_table_free(
817 			 &( internal_destination_handle->delta_segment_table ),
818 			 NULL );
819 		}
820 		if( internal_destination_handle->segment_table != NULL )
821 		{
822 			libewf_segment_table_free(
823 			 &( internal_destination_handle->segment_table ),
824 			 NULL );
825 		}
826 		if( internal_destination_handle->segment_files_cache != NULL )
827 		{
828 			libfcache_cache_free(
829 			 &( internal_destination_handle->segment_files_cache ),
830 			 NULL );
831 		}
832 		if( internal_destination_handle->delta_segment_files_list != NULL )
833 		{
834 			libmfdata_file_list_free(
835 			 &( internal_destination_handle->delta_segment_files_list ),
836 			 NULL );
837 		}
838 		if( internal_destination_handle->segment_files_list != NULL )
839 		{
840 			libmfdata_file_list_free(
841 			 &( internal_destination_handle->segment_files_list ),
842 			 NULL );
843 		}
844 		if( internal_destination_handle->write_io_handle != NULL )
845 		{
846 			libewf_write_io_handle_free(
847 			 &( internal_destination_handle->write_io_handle ),
848 			 NULL );
849 		}
850 		if( internal_destination_handle->read_io_handle != NULL )
851 		{
852 			libewf_read_io_handle_free(
853 			 &( internal_destination_handle->read_io_handle ),
854 			 NULL );
855 		}
856 		if( internal_destination_handle->file_io_pool != NULL )
857 		{
858 			libbfio_pool_free(
859 			 &( internal_destination_handle->file_io_pool ),
860 			 NULL );
861 		}
862 		if( internal_destination_handle->acquiry_errors != NULL )
863 		{
864 			libcdata_range_list_free(
865 			 &( internal_destination_handle->acquiry_errors ),
866 			 NULL,
867 			 NULL );
868 		}
869 		if( internal_destination_handle->tracks != NULL )
870 		{
871 			libcdata_array_free(
872 			 &( internal_destination_handle->tracks ),
873 			 (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
874 			 NULL );
875 		}
876 		if( internal_destination_handle->sessions != NULL )
877 		{
878 			libcdata_array_free(
879 			 &( internal_destination_handle->sessions ),
880 			 (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
881 			 NULL );
882 		}
883 		if( internal_destination_handle->media_values != NULL )
884 		{
885 			libewf_media_values_free(
886 			 &( internal_destination_handle->media_values ),
887 			 NULL );
888 		}
889 		if( internal_destination_handle->io_handle != NULL )
890 		{
891 			libewf_io_handle_free(
892 			 &( internal_destination_handle->io_handle ),
893 			 NULL );
894 		}
895 		memory_free(
896 		 internal_destination_handle );
897 	}
898 	return( -1 );
899 }
900 
901 /* Signals the handle to abort its current activity
902  * Returns 1 if successful or -1 on error
903  */
libewf_handle_signal_abort(libewf_handle_t * handle,libcerror_error_t ** error)904 int libewf_handle_signal_abort(
905      libewf_handle_t *handle,
906      libcerror_error_t **error )
907 {
908 	libewf_internal_handle_t *internal_handle = NULL;
909 	static char *function                     = "libewf_handle_signal_abort";
910 
911 	if( handle == NULL )
912 	{
913 		libcerror_error_set(
914 		 error,
915 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
916 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
917 		 "%s: invalid handle.",
918 		 function );
919 
920 		return( -1 );
921 	}
922 	internal_handle = (libewf_internal_handle_t *) handle;
923 
924 	if( internal_handle->io_handle == NULL )
925 	{
926 		libcerror_error_set(
927 		 error,
928 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
929 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
930 		 "%s: invalid handle - missing IO handle.",
931 		 function );
932 
933 		return( -1 );
934 	}
935 	internal_handle->io_handle->abort = 1;
936 
937 	return( 1 );
938 }
939 
940 /* Opens a set of EWF file(s)
941  * For reading files should contain all filenames that make up an EWF image
942  * For writing files should contain the base of the filename, extentions like .e01 will be automatically added
943  * Returns 1 if successful or -1 on error
944  */
libewf_handle_open(libewf_handle_t * handle,char * const filenames[],int number_of_filenames,int access_flags,libcerror_error_t ** error)945 int libewf_handle_open(
946      libewf_handle_t *handle,
947      char * const filenames[],
948      int number_of_filenames,
949      int access_flags,
950      libcerror_error_t **error )
951 {
952 	libbfio_handle_t *file_io_handle          = NULL;
953 	libbfio_pool_t *file_io_pool              = NULL;
954 	libewf_internal_handle_t *internal_handle = NULL;
955 	char *first_delta_segment_filename        = NULL;
956 	char *first_segment_filename              = NULL;
957 	static char *function                     = "libewf_handle_open";
958 	size_t filename_length                    = 0;
959 	int file_io_pool_entry                    = 0;
960 	int filename_iterator                     = 0;
961 
962 	if( handle == NULL )
963 	{
964 		libcerror_error_set(
965 		 error,
966 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
967 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
968 		 "%s: invalid handle.",
969 		 function );
970 
971 		return( -1 );
972 	}
973 	internal_handle = (libewf_internal_handle_t *) handle;
974 
975 	if( internal_handle->segment_table != NULL )
976 	{
977 		libcerror_error_set(
978 		 error,
979 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
980 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
981 		 "%s: invalid handle - segment table already set.",
982 		 function );
983 
984 		return( -1 );
985 	}
986 	if( internal_handle->delta_segment_table != NULL )
987 	{
988 		libcerror_error_set(
989 		 error,
990 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
991 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
992 		 "%s: invalid handle - delta segment table already set.",
993 		 function );
994 
995 		return( -1 );
996 	}
997 	if( filenames == NULL )
998 	{
999 		libcerror_error_set(
1000 		 error,
1001 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1002 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1003 		 "%s: invalid filenames.",
1004 		 function );
1005 
1006 		return( -1 );
1007 	}
1008 	if( number_of_filenames <= 0 )
1009 	{
1010 		libcerror_error_set(
1011 		 error,
1012 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1013 		 LIBCERROR_ARGUMENT_ERROR_VALUE_ZERO_OR_LESS,
1014 		 "%s: invalid number of files zero or less.",
1015 		 function );
1016 
1017 		return( -1 );
1018 	}
1019 #if !defined( HAVE_WRITE_SUPPORT )
1020 	if( ( access_flags & LIBEWF_ACCESS_FLAG_WRITE ) != 0 )
1021 	{
1022 		libcerror_error_set(
1023 		 error,
1024 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1025 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1026 		 "%s: write access currently not supported - compiled without zlib.",
1027 		 function );
1028 
1029 		return( -1 );
1030 	}
1031 #endif
1032 	if( libbfio_pool_initialize(
1033 	     &file_io_pool,
1034 	     0,
1035 	     internal_handle->maximum_number_of_open_handles,
1036 	     error ) != 1 )
1037 	{
1038 		libcerror_error_set(
1039 		 error,
1040 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1041 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1042 		 "%s: unable to create file IO pool.",
1043 		 function );
1044 
1045 		goto on_error;
1046 	}
1047 	if( ( ( access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
1048 	 || ( ( access_flags & LIBEWF_ACCESS_FLAG_RESUME ) != 0 ) )
1049 	{
1050 		for( filename_iterator = 0;
1051 		     filename_iterator < number_of_filenames;
1052 		     filename_iterator++ )
1053 		{
1054 			filename_length = narrow_string_length(
1055 					   filenames[ filename_iterator ] );
1056 
1057 			/* Make sure there is more to the filename than the extension
1058 			 */
1059 			if( filename_length <= 4 )
1060 			{
1061 				libcerror_error_set(
1062 				 error,
1063 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1064 				 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1065 				 "%s: filename: %s is too small.",
1066 				 function,
1067 				 filenames[ filename_iterator ] );
1068 
1069 				goto on_error;
1070 			}
1071 			if( libbfio_file_initialize(
1072 			     &file_io_handle,
1073 			     error ) != 1 )
1074 			{
1075 				libcerror_error_set(
1076 				 error,
1077 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1078 				 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1079 				 "%s: unable to create file IO handle.",
1080 				 function );
1081 
1082 				goto on_error;
1083 			}
1084 #if defined( HAVE_DEBUG_OUTPUT )
1085 			if( libbfio_handle_set_track_offsets_read(
1086 			     file_io_handle,
1087 			     1,
1088 			     error ) != 1 )
1089 			{
1090 		                libcerror_error_set(
1091 		                 error,
1092 		                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1093 		                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1094 		                 "%s: unable to set track offsets read in file IO handle.",
1095 		                 function );
1096 
1097 				goto on_error;
1098 			}
1099 #endif
1100 			if( libbfio_file_set_name(
1101 			     file_io_handle,
1102 			     filenames[ filename_iterator ],
1103 			     filename_length,
1104 			     error ) != 1 )
1105 			{
1106 				libcerror_error_set(
1107 				 error,
1108 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1109 				 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1110 				 "%s: unable to set name in file IO handle.",
1111 				 function );
1112 
1113 				goto on_error;
1114 			}
1115 			if( libbfio_pool_append_handle(
1116 			     file_io_pool,
1117 			     &file_io_pool_entry,
1118 			     file_io_handle,
1119 			     LIBBFIO_OPEN_READ,
1120 			     error ) != 1 )
1121 			{
1122 				libcerror_error_set(
1123 				 error,
1124 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1125 				 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1126 				 "%s: unable to append file IO handle to pool.",
1127 				 function );
1128 
1129 				goto on_error;
1130 			}
1131 			file_io_handle = NULL;
1132 
1133 #if defined( HAVE_DEBUG_OUTPUT )
1134 			if( libcnotify_verbose != 0 )
1135 			{
1136 				libcnotify_printf(
1137 				 "%s: added file IO pool entry: %d with filename: %s.\n",
1138 				 function,
1139 				 file_io_pool_entry,
1140 				 filenames[ filename_iterator ] );
1141 			}
1142 #endif
1143 			if( ( filenames[ filename_iterator ][ filename_length - 3 ] == 'e' )
1144 			 || ( filenames[ filename_iterator ][ filename_length - 3 ] == 'E' )
1145 			 || ( filenames[ filename_iterator ][ filename_length - 3 ] == 'l' )
1146 			 || ( filenames[ filename_iterator ][ filename_length - 3 ] == 'L' )
1147 			 || ( filenames[ filename_iterator ][ filename_length - 3 ] == 's' )
1148 			 || ( filenames[ filename_iterator ][ filename_length - 3 ] == 'S' ) )
1149 			{
1150 				if( ( filenames[ filename_iterator ][ filename_length - 2 ] == '0' )
1151 				 && ( filenames[ filename_iterator ][ filename_length - 1 ] == '1' ) )
1152 				{
1153 					first_segment_filename = filenames[ filename_iterator ];
1154 
1155 					if( first_delta_segment_filename == NULL )
1156 					{
1157 						first_delta_segment_filename = filenames[ filename_iterator ];
1158 					}
1159 				}
1160 			}
1161 			else if( ( filenames[ filename_iterator ][ filename_length - 3 ] == 'd' )
1162 			      || ( filenames[ filename_iterator ][ filename_length - 3 ] == 'D' ) )
1163 			{
1164 				if( ( filenames[ filename_iterator ][ filename_length - 2 ] == '0' )
1165 				 && ( filenames[ filename_iterator ][ filename_length - 1 ] == '1' ) )
1166 				{
1167 					first_delta_segment_filename = filenames[ filename_iterator ];
1168 				}
1169 			}
1170 		}
1171 	}
1172 	if( libewf_segment_table_initialize(
1173 	     &( internal_handle->segment_table ),
1174 	     LIBEWF_DEFAULT_SEGMENT_FILE_SIZE,
1175 	     error ) != 1 )
1176 	{
1177 		libcerror_error_set(
1178 		 error,
1179 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1180 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1181 		 "%s: unable to create segment table.",
1182 		 function );
1183 
1184 		goto on_error;
1185 	}
1186 	if( libewf_segment_table_initialize(
1187 	     &( internal_handle->delta_segment_table ),
1188 	     INT64_MAX,
1189 	     error ) != 1 )
1190 	{
1191 		libcerror_error_set(
1192 		 error,
1193 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1194 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1195 		 "%s: unable to create delta segment table.",
1196 		 function );
1197 
1198 		goto on_error;
1199 	}
1200 	if( ( access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
1201 	{
1202 		/* Get the basename of the first segment file
1203 		 */
1204 		if( first_segment_filename != NULL )
1205 		{
1206 			filename_length = narrow_string_length(
1207 					   first_segment_filename );
1208 
1209 			/* Set segment table basename
1210 			 */
1211 			if( libewf_segment_table_set_basename(
1212 			     internal_handle->segment_table,
1213 			     first_segment_filename,
1214 			     filename_length - 4,
1215 			     error ) != 1 )
1216 			{
1217 				libcerror_error_set(
1218 				 error,
1219 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1220 				 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1221 				 "%s: unable to set basename in segment table.",
1222 				 function );
1223 
1224 				goto on_error;
1225 			}
1226 		}
1227 		/* Get the basename of the first delta segment file
1228 		 */
1229 		if( first_delta_segment_filename != NULL )
1230 		{
1231 			filename_length = narrow_string_length(
1232 					   first_delta_segment_filename );
1233 
1234 			/* Set delta segment table basename
1235 			 */
1236 			if( libewf_segment_table_set_basename(
1237 			     internal_handle->delta_segment_table,
1238 			     first_delta_segment_filename,
1239 			     filename_length - 4,
1240 			     error ) != 1 )
1241 			{
1242 				libcerror_error_set(
1243 				 error,
1244 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1245 				 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1246 				 "%s: unable to set basename in delta segment table.",
1247 				 function );
1248 
1249 				goto on_error;
1250 			}
1251 		}
1252 	}
1253 	else if( ( access_flags & LIBEWF_ACCESS_FLAG_RESUME ) != 0 )
1254 	{
1255 		/* Get the basename of the first segment file
1256 		 */
1257 		if( first_segment_filename != NULL )
1258 		{
1259 			filename_length = narrow_string_length(
1260 					   first_segment_filename );
1261 
1262 			/* Set segment table basename
1263 			 */
1264 			if( libewf_segment_table_set_basename(
1265 			     internal_handle->segment_table,
1266 			     first_segment_filename,
1267 			     filename_length - 4,
1268 			     error ) != 1 )
1269 			{
1270 				libcerror_error_set(
1271 				 error,
1272 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1273 				 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1274 				 "%s: unable to set basename in segment table.",
1275 				 function );
1276 
1277 				goto on_error;
1278 			}
1279 		}
1280 	}
1281 	else if( ( access_flags & LIBEWF_ACCESS_FLAG_WRITE ) != 0 )
1282 	{
1283 		/* Get the basename and store it in the segment tables
1284 		 */
1285 		filename_length = narrow_string_length(
1286 				   filenames[ 0 ] );
1287 
1288 		/* Set segment table basename
1289 		 */
1290 		if( libewf_segment_table_set_basename(
1291 		     internal_handle->segment_table,
1292 		     filenames[ 0 ],
1293 		     filename_length,
1294 		     error ) != 1 )
1295 		{
1296 			libcerror_error_set(
1297 			 error,
1298 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1299 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1300 			 "%s: unable to set basename in segment table.",
1301 			 function );
1302 
1303 			goto on_error;
1304 		}
1305 	}
1306 	if( libewf_handle_open_file_io_pool(
1307 	     handle,
1308 	     file_io_pool,
1309 	     access_flags,
1310 	     error ) != 1 )
1311 	{
1312 		libcerror_error_set(
1313 		 error,
1314 		 LIBCERROR_ERROR_DOMAIN_IO,
1315 		 LIBCERROR_IO_ERROR_OPEN_FAILED,
1316 		 "%s: unable to open handle using a file IO pool.",
1317 		 function );
1318 
1319 		goto on_error;
1320 	}
1321 	internal_handle->file_io_pool_created_in_library = 1;
1322 
1323 	return( 1 );
1324 
1325 on_error:
1326 	if( internal_handle->delta_segment_table != NULL )
1327 	{
1328 		libewf_segment_table_free(
1329 		 &( internal_handle->delta_segment_table ),
1330 		 NULL );
1331 	}
1332 	if( internal_handle->segment_table != NULL )
1333 	{
1334 		libewf_segment_table_free(
1335 		 &( internal_handle->segment_table ),
1336 		 NULL );
1337 	}
1338 	if( file_io_handle != NULL )
1339 	{
1340 		libbfio_handle_free(
1341 		 &file_io_handle,
1342 		 NULL );
1343 	}
1344 	if( file_io_pool != NULL )
1345 	{
1346 		libbfio_pool_free(
1347 		 &file_io_pool,
1348 		 NULL );
1349 	}
1350 	return( -1 );
1351 }
1352 
1353 #if defined( HAVE_WIDE_CHARACTER_TYPE )
1354 
1355 /* Opens a set of EWF file(s)
1356  * For reading files should contain all filenames that make up an EWF image
1357  * For writing files should contain the base of the filename, extentions like .e01 will be automatically added
1358  * Returns 1 if successful or -1 on error
1359  */
libewf_handle_open_wide(libewf_handle_t * handle,wchar_t * const filenames[],int number_of_filenames,int access_flags,libcerror_error_t ** error)1360 int libewf_handle_open_wide(
1361      libewf_handle_t *handle,
1362      wchar_t * const filenames[],
1363      int number_of_filenames,
1364      int access_flags,
1365      libcerror_error_t **error )
1366 {
1367 	libbfio_handle_t *file_io_handle          = NULL;
1368 	libbfio_pool_t *file_io_pool              = NULL;
1369 	libewf_internal_handle_t *internal_handle = NULL;
1370 	wchar_t *first_delta_segment_filename     = NULL;
1371 	wchar_t *first_segment_filename           = NULL;
1372 	static char *function                     = "libewf_handle_open_wide";
1373 	size_t filename_length                    = 0;
1374 	int file_io_pool_entry                    = 0;
1375 	int filename_iterator                     = 0;
1376 
1377 	if( handle == NULL )
1378 	{
1379 		libcerror_error_set(
1380 		 error,
1381 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1382 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1383 		 "%s: invalid handle.",
1384 		 function );
1385 
1386 		return( -1 );
1387 	}
1388 	internal_handle = (libewf_internal_handle_t *) handle;
1389 
1390 	if( internal_handle->segment_table != NULL )
1391 	{
1392 		libcerror_error_set(
1393 		 error,
1394 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1395 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1396 		 "%s: invalid handle - segment table already set.",
1397 		 function );
1398 
1399 		return( -1 );
1400 	}
1401 	if( internal_handle->delta_segment_table != NULL )
1402 	{
1403 		libcerror_error_set(
1404 		 error,
1405 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1406 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1407 		 "%s: invalid handle - delta segment table already set.",
1408 		 function );
1409 
1410 		return( -1 );
1411 	}
1412 	if( filenames == NULL )
1413 	{
1414 		libcerror_error_set(
1415 		 error,
1416 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1417 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1418 		 "%s: invalid filenames.",
1419 		 function );
1420 
1421 		return( -1 );
1422 	}
1423 	if( number_of_filenames <= 0 )
1424 	{
1425 		libcerror_error_set(
1426 		 error,
1427 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1428 		 LIBCERROR_ARGUMENT_ERROR_VALUE_ZERO_OR_LESS,
1429 		 "%s: invalid number of files zero or less.",
1430 		 function );
1431 
1432 		return( -1 );
1433 	}
1434 #if !defined( HAVE_WRITE_SUPPORT )
1435 	if( ( access_flags & LIBEWF_ACCESS_FLAG_WRITE ) != 0 )
1436 	{
1437 		libcerror_error_set(
1438 		 error,
1439 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1440 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1441 		 "%s: write access currently not supported - compiled without zlib.",
1442 		 function );
1443 
1444 		return( -1 );
1445 	}
1446 #endif
1447 	if( libbfio_pool_initialize(
1448 	     &file_io_pool,
1449 	     0,
1450 	     internal_handle->maximum_number_of_open_handles,
1451 	     error ) != 1 )
1452 	{
1453 		libcerror_error_set(
1454 		 error,
1455 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1456 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1457 		 "%s: unable to create file IO pool.",
1458 		 function );
1459 
1460 		goto on_error;
1461 	}
1462 	if( ( ( access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
1463 	 || ( ( access_flags & LIBEWF_ACCESS_FLAG_RESUME ) != 0 ) )
1464 	{
1465 		for( filename_iterator = 0;
1466 		     filename_iterator < number_of_filenames;
1467 		     filename_iterator++ )
1468 		{
1469 			filename_length = wide_string_length(
1470 					   filenames[ filename_iterator ] );
1471 
1472 			/* Make sure there is more to the filename than the extension
1473 			 */
1474 			if( filename_length <= 4 )
1475 			{
1476 				libcerror_error_set(
1477 				 error,
1478 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1479 				 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1480 				 "%s: filename: %ls is too small.",
1481 				 function,
1482 				 filenames[ filename_iterator ] );
1483 
1484 				goto on_error;
1485 			}
1486 			if( libbfio_file_initialize(
1487 			     &file_io_handle,
1488 			     error ) != 1 )
1489 			{
1490 				libcerror_error_set(
1491 				 error,
1492 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1493 				 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1494 				 "%s: unable to create file IO handle.",
1495 				 function );
1496 
1497 				goto on_error;
1498 			}
1499 #if defined( HAVE_DEBUG_OUTPUT )
1500 			if( libbfio_handle_set_track_offsets_read(
1501 			     file_io_handle,
1502 			     1,
1503 			     error ) != 1 )
1504 			{
1505 		                libcerror_error_set(
1506 		                 error,
1507 		                 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1508 		                 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1509 		                 "%s: unable to set track offsets read in file IO handle.",
1510 		                 function );
1511 
1512 				goto on_error;
1513 			}
1514 #endif
1515 			if( libbfio_file_set_name_wide(
1516 			     file_io_handle,
1517 			     filenames[ filename_iterator ],
1518 			     filename_length,
1519 			     error ) != 1 )
1520 			{
1521 				libcerror_error_set(
1522 				 error,
1523 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1524 				 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1525 				 "%s: unable to set name in file IO handle.",
1526 				 function );
1527 
1528 				goto on_error;
1529 			}
1530 			if( libbfio_pool_append_handle(
1531 			     file_io_pool,
1532 			     &file_io_pool_entry,
1533 			     file_io_handle,
1534 			     LIBBFIO_OPEN_READ,
1535 			     error ) != 1 )
1536 			{
1537 				libcerror_error_set(
1538 				 error,
1539 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1540 				 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
1541 				 "%s: unable to append file IO handle to pool.",
1542 				 function );
1543 
1544 				goto on_error;
1545 			}
1546 			file_io_handle = NULL;
1547 
1548 #if defined( HAVE_DEBUG_OUTPUT )
1549 			if( libcnotify_verbose != 0 )
1550 			{
1551 				libcnotify_printf(
1552 				 "%s: added file IO pool entry: %d with filename: %ls.\n",
1553 				 function,
1554 				 file_io_pool_entry,
1555 				 filenames[ filename_iterator ] );
1556 			}
1557 #endif
1558 			if( ( filenames[ filename_iterator ][ filename_length - 3 ] == 'e' )
1559 			 || ( filenames[ filename_iterator ][ filename_length - 3 ] == 'E' )
1560 			 || ( filenames[ filename_iterator ][ filename_length - 3 ] == 'l' )
1561 			 || ( filenames[ filename_iterator ][ filename_length - 3 ] == 'L' )
1562 			 || ( filenames[ filename_iterator ][ filename_length - 3 ] == 's' )
1563 			 || ( filenames[ filename_iterator ][ filename_length - 3 ] == 'S' ) )
1564 			{
1565 				if( ( filenames[ filename_iterator ][ filename_length - 2 ] == '0' )
1566 				 && ( filenames[ filename_iterator ][ filename_length - 1 ] == '1' ) )
1567 				{
1568 					first_segment_filename = filenames[ filename_iterator ];
1569 
1570 					if( first_delta_segment_filename == NULL )
1571 					{
1572 						first_delta_segment_filename = filenames[ filename_iterator ];
1573 					}
1574 				}
1575 			}
1576 			else if( ( filenames[ filename_iterator ][ filename_length - 3 ] == 'd' )
1577 			      || ( filenames[ filename_iterator ][ filename_length - 3 ] == 'D' ) )
1578 			{
1579 				if( ( filenames[ filename_iterator ][ filename_length - 2 ] == '0' )
1580 				 && ( filenames[ filename_iterator ][ filename_length - 1 ] == '1' ) )
1581 				{
1582 					first_delta_segment_filename = filenames[ filename_iterator ];
1583 				}
1584 			}
1585 		}
1586 	}
1587 	if( libewf_segment_table_initialize(
1588 	     &( internal_handle->segment_table ),
1589 	     LIBEWF_DEFAULT_SEGMENT_FILE_SIZE,
1590 	     error ) != 1 )
1591 	{
1592 		libcerror_error_set(
1593 		 error,
1594 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1595 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1596 		 "%s: unable to create segment table.",
1597 		 function );
1598 
1599 		goto on_error;
1600 	}
1601 	if( libewf_segment_table_initialize(
1602 	     &( internal_handle->delta_segment_table ),
1603 	     INT64_MAX,
1604 	     error ) != 1 )
1605 	{
1606 		libcerror_error_set(
1607 		 error,
1608 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1609 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1610 		 "%s: unable to create delta segment table.",
1611 		 function );
1612 
1613 		goto on_error;
1614 	}
1615 	if( ( access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
1616 	{
1617 		/* Get the basename of the first segment file
1618 		 */
1619 		if( first_segment_filename != NULL )
1620 		{
1621 			filename_length = wide_string_length(
1622 					   first_segment_filename );
1623 
1624 			/* Set segment table basename
1625 			 */
1626 			if( libewf_segment_table_set_basename_wide(
1627 			     internal_handle->segment_table,
1628 			     first_segment_filename,
1629 			     filename_length - 4,
1630 			     error ) != 1 )
1631 			{
1632 				libcerror_error_set(
1633 				 error,
1634 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1635 				 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1636 				 "%s: unable to set basename in segment table.",
1637 				 function );
1638 
1639 				goto on_error;
1640 			}
1641 		}
1642 		/* Get the basename of the first delta segment file
1643 		 */
1644 		if( first_delta_segment_filename != NULL )
1645 		{
1646 			filename_length = wide_string_length(
1647 					   first_delta_segment_filename );
1648 
1649 			/* Set delta segment table basename
1650 			 */
1651 			if( libewf_segment_table_set_basename_wide(
1652 			     internal_handle->delta_segment_table,
1653 			     first_delta_segment_filename,
1654 			     filename_length - 4,
1655 			     error ) != 1 )
1656 			{
1657 				libcerror_error_set(
1658 				 error,
1659 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1660 				 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1661 				 "%s: unable to set basename in delta segment table.",
1662 				 function );
1663 
1664 				goto on_error;
1665 			}
1666 		}
1667 	}
1668 	else if( ( access_flags & LIBEWF_ACCESS_FLAG_RESUME ) != 0 )
1669 	{
1670 		/* Get the basename of the first segment file
1671 		 */
1672 		if( first_segment_filename != NULL )
1673 		{
1674 			filename_length = wide_string_length(
1675 					   first_segment_filename );
1676 
1677 			/* Set segment table basename
1678 			 */
1679 			if( libewf_segment_table_set_basename_wide(
1680 			     internal_handle->segment_table,
1681 			     first_segment_filename,
1682 			     filename_length - 4,
1683 			     error ) != 1 )
1684 			{
1685 				libcerror_error_set(
1686 				 error,
1687 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1688 				 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1689 				 "%s: unable to set basename in segment table.",
1690 				 function );
1691 
1692 				goto on_error;
1693 			}
1694 		}
1695 	}
1696 	else if( ( access_flags & LIBEWF_ACCESS_FLAG_WRITE ) != 0 )
1697 	{
1698 		/* Get the basename and store it in the segment tables
1699 		 */
1700 		filename_length = wide_string_length(
1701 				   filenames[ 0 ] );
1702 
1703 		/* Set segment table basename
1704 		 */
1705 		if( libewf_segment_table_set_basename_wide(
1706 		     internal_handle->segment_table,
1707 		     filenames[ 0 ],
1708 		     filename_length,
1709 		     error ) != 1 )
1710 		{
1711 			libcerror_error_set(
1712 			 error,
1713 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1714 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1715 			 "%s: unable to set basename in segment table.",
1716 			 function );
1717 
1718 			goto on_error;
1719 		}
1720 	}
1721 	if( libewf_handle_open_file_io_pool(
1722 	     handle,
1723 	     file_io_pool,
1724 	     access_flags,
1725 	     error ) != 1 )
1726 	{
1727 		libcerror_error_set(
1728 		 error,
1729 		 LIBCERROR_ERROR_DOMAIN_IO,
1730 		 LIBCERROR_IO_ERROR_OPEN_FAILED,
1731 		 "%s: unable to open handle using a file IO pool.",
1732 		 function );
1733 
1734 		goto on_error;
1735 	}
1736 	internal_handle->file_io_pool_created_in_library = 1;
1737 
1738 	return( 1 );
1739 
1740 on_error:
1741 	if( internal_handle->delta_segment_table != NULL )
1742 	{
1743 		libewf_segment_table_free(
1744 		 &( internal_handle->delta_segment_table ),
1745 		 NULL );
1746 	}
1747 	if( internal_handle->segment_table != NULL )
1748 	{
1749 		libewf_segment_table_free(
1750 		 &( internal_handle->segment_table ),
1751 		 NULL );
1752 	}
1753 	if( file_io_handle != NULL )
1754 	{
1755 		libbfio_handle_free(
1756 		 &file_io_handle,
1757 		 NULL );
1758 	}
1759 	if( file_io_pool != NULL )
1760 	{
1761 		libbfio_pool_free(
1762 		 &file_io_pool,
1763 		 NULL );
1764 	}
1765 	return( -1 );
1766 }
1767 
1768 #endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
1769 
1770 /* Opens a set of EWF file(s) using a Basic File IO (bfio) pool
1771  * Returns 1 if successful or -1 on error
1772  */
libewf_handle_open_file_io_pool(libewf_handle_t * handle,libbfio_pool_t * file_io_pool,int access_flags,libcerror_error_t ** error)1773 int libewf_handle_open_file_io_pool(
1774      libewf_handle_t *handle,
1775      libbfio_pool_t *file_io_pool,
1776      int access_flags,
1777      libcerror_error_t **error )
1778 {
1779 	libbfio_handle_t *file_io_handle          = NULL;
1780 	libewf_chunk_table_t *chunk_table         = NULL;
1781 	libewf_internal_handle_t *internal_handle = NULL;
1782 	libewf_segment_file_t *segment_file       = NULL;
1783 	static char *function                     = "libewf_handle_open_file_io_pool";
1784 	ssize_t read_count                        = 0;
1785 	uint16_t maximum_delta_segment_number     = 0;
1786 	uint16_t maximum_segment_number           = 0;
1787 	int file_io_pool_entry                    = 0;
1788 	int number_of_file_io_handles             = 0;
1789 
1790 	if( handle == NULL )
1791 	{
1792 		libcerror_error_set(
1793 		 error,
1794 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1795 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1796 		 "%s: invalid handle.",
1797 		 function );
1798 
1799 		return( -1 );
1800 	}
1801 	internal_handle = (libewf_internal_handle_t *) handle;
1802 
1803 	if( internal_handle->io_handle == NULL )
1804 	{
1805 		libcerror_error_set(
1806 		 error,
1807 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1808 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1809 		 "%s: invalid handle - missing IO handle.",
1810 		 function );
1811 
1812 		return( -1 );
1813 	}
1814 	if( internal_handle->file_io_pool != NULL )
1815 	{
1816 		libcerror_error_set(
1817 		 error,
1818 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1819 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1820 		 "%s: invalid handle - file IO pool already set.",
1821 		 function );
1822 
1823 		return( -1 );
1824 	}
1825 	if( internal_handle->segment_files_list != NULL )
1826 	{
1827 		libcerror_error_set(
1828 		 error,
1829 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1830 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1831 		 "%s: invalid handle - segment files list already set.",
1832 		 function );
1833 
1834 		return( -1 );
1835 	}
1836 	if( internal_handle->delta_segment_files_list != NULL )
1837 	{
1838 		libcerror_error_set(
1839 		 error,
1840 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1841 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1842 		 "%s: invalid handle - delta segment files list already set.",
1843 		 function );
1844 
1845 		return( -1 );
1846 	}
1847 	if( internal_handle->chunk_table_list != NULL )
1848 	{
1849 		libcerror_error_set(
1850 		 error,
1851 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1852 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1853 		 "%s: invalid handle - chunk table list already set.",
1854 		 function );
1855 
1856 		return( -1 );
1857 	}
1858 	if( internal_handle->chunk_table_cache != NULL )
1859 	{
1860 		libcerror_error_set(
1861 		 error,
1862 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1863 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1864 		 "%s: invalid handle - chunk table cache already set.",
1865 		 function );
1866 
1867 		return( -1 );
1868 	}
1869 	if( internal_handle->header_sections != NULL )
1870 	{
1871 		libcerror_error_set(
1872 		 error,
1873 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1874 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1875 		 "%s: invalid handle - header sections already set.",
1876 		 function );
1877 
1878 		return( -1 );
1879 	}
1880 	if( internal_handle->hash_sections != NULL )
1881 	{
1882 		libcerror_error_set(
1883 		 error,
1884 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1885 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1886 		 "%s: invalid handle - hash sections already set.",
1887 		 function );
1888 
1889 		return( -1 );
1890 	}
1891 	if( internal_handle->single_files != NULL )
1892 	{
1893 		libcerror_error_set(
1894 		 error,
1895 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1896 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1897 		 "%s: invalid handle - single files already set.",
1898 		 function );
1899 
1900 		return( -1 );
1901 	}
1902 	if( file_io_pool == NULL )
1903 	{
1904 		libcerror_error_set(
1905 		 error,
1906 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1907 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1908 		 "%s: invalid file IO pool.",
1909 		 function );
1910 
1911 		return( -1 );
1912 	}
1913 	if( ( access_flags & ~( LIBEWF_ACCESS_FLAG_READ | LIBEWF_ACCESS_FLAG_WRITE | LIBEWF_ACCESS_FLAG_RESUME ) ) != 0 )
1914 	{
1915 		libcerror_error_set(
1916 		 error,
1917 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1918 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1919 		 "%s: unsupported access flags.",
1920 		 function );
1921 
1922 		return( -1 );
1923 	}
1924 #if !defined( HAVE_WRITE_SUPPORT )
1925 	if( ( access_flags & LIBEWF_ACCESS_FLAG_WRITE ) != 0 )
1926 	{
1927 		libcerror_error_set(
1928 		 error,
1929 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1930 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1931 		 "%s: write access currently not supported - compiled without zlib.",
1932 		 function );
1933 
1934 		return( -1 );
1935 	}
1936 #endif
1937 	if( internal_handle->segment_table == NULL )
1938 	{
1939 		if( libewf_segment_table_initialize(
1940 		     &( internal_handle->segment_table ),
1941 		     LIBEWF_DEFAULT_SEGMENT_FILE_SIZE,
1942 		     error ) != 1 )
1943 		{
1944 			libcerror_error_set(
1945 			 error,
1946 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1947 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1948 			 "%s: unable to create segment table.",
1949 			 function );
1950 
1951 			goto on_error;
1952 		}
1953 	}
1954 	if( internal_handle->delta_segment_table == NULL )
1955 	{
1956 		if( libewf_segment_table_initialize(
1957 		     &( internal_handle->delta_segment_table ),
1958 		     INT64_MAX,
1959 		     error ) != 1 )
1960 		{
1961 			libcerror_error_set(
1962 			 error,
1963 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1964 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1965 			 "%s: unable to create delta segment table.",
1966 			 function );
1967 
1968 			goto on_error;
1969 		}
1970 	}
1971 	if( ( ( access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
1972 	 || ( ( access_flags & LIBEWF_ACCESS_FLAG_RESUME ) != 0 ) )
1973 	{
1974 		if( libewf_read_io_handle_initialize(
1975 		     &( internal_handle->read_io_handle ),
1976 		     error ) != 1 )
1977 		{
1978 			libcerror_error_set(
1979 			 error,
1980 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1981 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1982 			 "%s: unable to create read IO handle.",
1983 			 function );
1984 
1985 			goto on_error;
1986 		}
1987 	}
1988 	if( ( access_flags & LIBEWF_ACCESS_FLAG_WRITE ) != 0 )
1989 	{
1990 		if( libewf_write_io_handle_initialize(
1991 		     &( internal_handle->write_io_handle ),
1992 		     error ) != 1 )
1993 		{
1994 			libcerror_error_set(
1995 			 error,
1996 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1997 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1998 			 "%s: unable to create write IO handle.",
1999 			 function );
2000 
2001 			goto on_error;
2002 		}
2003 		if( libewf_write_io_handle_set_compressed_zero_byte_empty_block(
2004 		     internal_handle->write_io_handle,
2005 		     internal_handle->io_handle,
2006 		     internal_handle->media_values,
2007 		     error ) != 1 )
2008 		{
2009 			libcerror_error_set(
2010 			 error,
2011 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2012 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2013 			 "%s: unable to set compressed zero byte empty block in write IO handle.",
2014 			 function );
2015 
2016 			goto on_error;
2017 		}
2018 	}
2019 	if( libmfdata_file_list_initialize(
2020 	     &( internal_handle->segment_files_list ),
2021 	     NULL,
2022 	     NULL,
2023 	     NULL,
2024 	     &libewf_segment_file_read,
2025 	     0,
2026 	     error ) != 1 )
2027 	{
2028 		libcerror_error_set(
2029 		 error,
2030 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2031 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2032 		 "%s: unable to create segment files list.",
2033 		 function );
2034 
2035 		goto on_error;
2036 	}
2037 	if( libmfdata_file_list_initialize(
2038 	     &( internal_handle->delta_segment_files_list ),
2039 	     NULL,
2040 	     NULL,
2041 	     NULL,
2042 	     &libewf_segment_file_read,
2043 	     0,
2044 	     error ) != 1 )
2045 	{
2046 		libcerror_error_set(
2047 		 error,
2048 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2049 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2050 		 "%s: unable to create delta segment files list.",
2051 		 function );
2052 
2053 		goto on_error;
2054 	}
2055 	if( libfcache_cache_initialize(
2056 	     &( internal_handle->segment_files_cache ),
2057 	     8,
2058 	     error ) != 1 )
2059 	{
2060 		libcerror_error_set(
2061 		 error,
2062 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2063 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2064 		 "%s: unable to segment files table cache.",
2065 		 function );
2066 
2067 		goto on_error;
2068 	}
2069 	if( libewf_chunk_table_initialize(
2070 	     &chunk_table,
2071 	     internal_handle->io_handle,
2072 	     error ) != 1 )
2073 	{
2074 		libcerror_error_set(
2075 		 error,
2076 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2077 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2078 		 "%s: unable to create chunk table.",
2079 		 function );
2080 
2081 		goto on_error;
2082 	}
2083 	if( libmfdata_list_initialize(
2084 	     &( internal_handle->chunk_table_list ),
2085 	     (intptr_t *) chunk_table,
2086 	     (int (*)(intptr_t **, libcerror_error_t **)) &libewf_chunk_table_free,
2087 	     &libewf_chunk_table_clone,
2088 	     &libewf_chunk_table_read_chunk,
2089 	     &libewf_chunk_table_read_offsets,
2090 	     LIBMFDATA_FLAG_IO_HANDLE_MANAGED,
2091 	     error ) != 1 )
2092 	{
2093 		libcerror_error_set(
2094 		 error,
2095 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2096 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2097 		 "%s: unable to create chunk table list.",
2098 		 function );
2099 
2100 		libewf_chunk_table_free(
2101 		 &chunk_table,
2102 		 NULL );
2103 
2104 		goto on_error;
2105 	}
2106 	if( libfcache_cache_initialize(
2107 	     &( internal_handle->chunk_table_cache ),
2108 	     8,
2109 	     error ) != 1 )
2110 	{
2111 		libcerror_error_set(
2112 		 error,
2113 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2114 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2115 		 "%s: unable to create chunk table cache.",
2116 		 function );
2117 
2118 		goto on_error;
2119 	}
2120 	if( libewf_header_sections_initialize(
2121 	     &( internal_handle->header_sections ),
2122 	     error ) != 1 )
2123 	{
2124 		libcerror_error_set(
2125 		 error,
2126 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2127 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2128 		 "%s: unable to create header sections.",
2129 		 function );
2130 
2131 		goto on_error;
2132 	}
2133 	if( libewf_header_values_initialize(
2134 	     &( internal_handle->header_values ),
2135 	     error ) != 1 )
2136 	{
2137 		libcerror_error_set(
2138 		 error,
2139 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2140 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2141 		 "%s: unable to create header values.",
2142 		 function );
2143 
2144 		goto on_error;
2145 	}
2146 	if( libewf_hash_sections_initialize(
2147 	     &( internal_handle->hash_sections ),
2148 	     error ) != 1 )
2149 	{
2150 		libcerror_error_set(
2151 		 error,
2152 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2153 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2154 		 "%s: unable to create hash sections.",
2155 		 function );
2156 
2157 		goto on_error;
2158 	}
2159 	if( libewf_single_files_initialize(
2160 	     &( internal_handle->single_files ),
2161 	     error ) != 1 )
2162 	{
2163 		libcerror_error_set(
2164 		 error,
2165 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2166 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2167 		 "%s: unable to create single files.",
2168 		 function );
2169 
2170 		goto on_error;
2171 	}
2172 	if( internal_handle->read_io_handle != NULL )
2173 	{
2174 		if( libcdata_range_list_empty(
2175 		     internal_handle->read_io_handle->checksum_errors,
2176 		     NULL,
2177 		     error ) != 1 )
2178 		{
2179 			libcerror_error_set(
2180 			 error,
2181 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2182 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2183 			 "%s: unable to empty checksum errors range list.",
2184 			 function );
2185 
2186 			goto on_error;
2187 		}
2188 	}
2189 	if( libcdata_array_empty(
2190 	     internal_handle->sessions,
2191 	     (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
2192 	     error ) != 1 )
2193 	{
2194 		libcerror_error_set(
2195 		 error,
2196 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2197 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2198 		 "%s: unable to empty sessions array.",
2199 		 function );
2200 
2201 		goto on_error;
2202 	}
2203 	if( libcdata_array_empty(
2204 	     internal_handle->tracks,
2205 	     (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
2206 	     error ) != 1 )
2207 	{
2208 		libcerror_error_set(
2209 		 error,
2210 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2211 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2212 		 "%s: unable to empty tracks array.",
2213 		 function );
2214 
2215 		goto on_error;
2216 	}
2217 	if( libcdata_range_list_empty(
2218 	     internal_handle->acquiry_errors,
2219 	     NULL,
2220 	     error ) != 1 )
2221 	{
2222 		libcerror_error_set(
2223 		 error,
2224 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2225 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2226 		 "%s: unable to empty acquiry errors range list.",
2227 		 function );
2228 
2229 		goto on_error;
2230 	}
2231 	if( ( ( access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
2232 	 || ( ( access_flags & LIBEWF_ACCESS_FLAG_RESUME ) != 0 ) )
2233 	{
2234 		if( libbfio_pool_get_number_of_handles(
2235 		     file_io_pool,
2236 		     &number_of_file_io_handles,
2237 		     error ) != 1 )
2238 		{
2239 			libcerror_error_set(
2240 			 error,
2241 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2242 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2243 			 "%s: unable to retrieve the number of handles in the pool.",
2244 			 function );
2245 
2246 			goto on_error;
2247 		}
2248 		if( libewf_segment_file_initialize(
2249 		     &segment_file,
2250 		     error ) != 1 )
2251 		{
2252 			libcerror_error_set(
2253 			 error,
2254 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2255 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2256 			 "%s: unable to create segment file.",
2257 			 function );
2258 
2259 			goto on_error;
2260 		}
2261 		for( file_io_pool_entry = 0;
2262 		     file_io_pool_entry < number_of_file_io_handles;
2263 		     file_io_pool_entry++ )
2264 		{
2265 			if( libbfio_pool_get_handle(
2266 			     file_io_pool,
2267 			     file_io_pool_entry,
2268 			     &file_io_handle,
2269 			     error ) != 1 )
2270 			{
2271 				libcerror_error_set(
2272 				 error,
2273 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2274 				 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2275 				 "%s: unable to retrieve file IO handle: %d from pool.",
2276 				 function,
2277 				 file_io_pool_entry );
2278 
2279 				libewf_segment_file_free(
2280 				 &segment_file,
2281 				 NULL );
2282 
2283 				goto on_error;
2284 			}
2285 #if defined( HAVE_DEBUG_OUTPUT )
2286 			if( libcnotify_verbose != 0 )
2287 			{
2288 				libcnotify_printf(
2289 				 "%s: processing file IO pool entry: %d.\n",
2290 				 function,
2291 				 file_io_pool_entry );
2292 			}
2293 #endif
2294 			read_count = libewf_segment_file_read_file_header(
2295 				      segment_file,
2296 				      file_io_pool,
2297 				      file_io_pool_entry,
2298 				      error );
2299 
2300 			if( read_count < 0 )
2301 			{
2302 				libcerror_error_set(
2303 				 error,
2304 				 LIBCERROR_ERROR_DOMAIN_IO,
2305 				 LIBCERROR_IO_ERROR_READ_FAILED,
2306 				 "%s: unable to read segment file header.",
2307 				 function );
2308 
2309 				libewf_segment_file_free(
2310 				 &segment_file,
2311 				 NULL );
2312 
2313 				goto on_error;
2314 			}
2315 			if( segment_file->segment_number == 0 )
2316 			{
2317 				libcerror_error_set(
2318 				 error,
2319 				 LIBCERROR_ERROR_DOMAIN_INPUT,
2320 				 LIBCERROR_INPUT_ERROR_INVALID_DATA,
2321 				 "%s: invalid segment number: 0 in file IO pool entry: %d.",
2322 				 function,
2323 				 file_io_pool_entry );
2324 
2325 				libewf_segment_file_free(
2326 				 &segment_file,
2327 				 NULL );
2328 
2329 				goto on_error;
2330 			}
2331 			if( ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_EWF )
2332 			 || ( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_LWF ) )
2333 			{
2334 				if( segment_file->segment_number > maximum_segment_number )
2335 				{
2336 					if( libmfdata_file_list_resize(
2337 					     internal_handle->segment_files_list,
2338 					     (int) segment_file->segment_number,
2339 					     error ) != 1 )
2340 					{
2341 						libcerror_error_set(
2342 						 error,
2343 						 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2344 						 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2345 						 "%s: unable to resize data file list.",
2346 						 function );
2347 
2348 						libewf_segment_file_free(
2349 						 &segment_file,
2350 						 NULL );
2351 
2352 						goto on_error;
2353 					}
2354 					maximum_segment_number = segment_file->segment_number;
2355 				}
2356 				if( libmfdata_file_list_set_file_by_index(
2357 				     internal_handle->segment_files_list,
2358 				     (int) ( segment_file->segment_number - 1 ),
2359 				     file_io_pool_entry,
2360 				     error ) != 1 )
2361 				{
2362 					libcerror_error_set(
2363 					 error,
2364 					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2365 					 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2366 					 "%s: unable to set segment file: %" PRIu16 " in list.",
2367 					 function,
2368 					 segment_file->segment_number );
2369 
2370 					libewf_segment_file_free(
2371 					 &segment_file,
2372 					 NULL );
2373 
2374 					goto on_error;
2375 				}
2376 			}
2377 			else if( segment_file->type == LIBEWF_SEGMENT_FILE_TYPE_DWF )
2378 			{
2379 				if( segment_file->segment_number > maximum_delta_segment_number )
2380 				{
2381 					if( libmfdata_file_list_resize(
2382 					     internal_handle->delta_segment_files_list,
2383 					     (int) segment_file->segment_number,
2384 					     error ) != 1 )
2385 					{
2386 						libcerror_error_set(
2387 						 error,
2388 						 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2389 						 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
2390 						 "%s: unable to resize delta segment files list.",
2391 						 function );
2392 
2393 						libewf_segment_file_free(
2394 						 &segment_file,
2395 						 NULL );
2396 
2397 						goto on_error;
2398 					}
2399 					maximum_delta_segment_number = segment_file->segment_number;
2400 				}
2401 				if( libmfdata_file_list_set_file_by_index(
2402 				     internal_handle->delta_segment_files_list,
2403 				     (int) ( segment_file->segment_number - 1 ),
2404 				     file_io_pool_entry,
2405 				     error ) != 1 )
2406 				{
2407 					libcerror_error_set(
2408 					 error,
2409 					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2410 					 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2411 					 "%s: unable to set delta segment file: %" PRIu16 " in list.",
2412 					 function,
2413 					 segment_file->segment_number );
2414 
2415 					libewf_segment_file_free(
2416 					 &segment_file,
2417 					 NULL );
2418 
2419 					goto on_error;
2420 				}
2421 				/* Re-open the delta segment file with write access
2422 				 */
2423 				if( ( access_flags & LIBEWF_ACCESS_FLAG_WRITE ) != 0 )
2424 				{
2425 					if( libbfio_pool_reopen(
2426 					     file_io_pool,
2427 					     file_io_pool_entry,
2428 					     LIBBFIO_OPEN_READ_WRITE,
2429 					     error ) != 1 )
2430 					{
2431 						libcerror_error_set(
2432 						 error,
2433 						 LIBCERROR_ERROR_DOMAIN_IO,
2434 						 LIBCERROR_IO_ERROR_OPEN_FAILED,
2435 						 "%s: unable to reopen file IO pool entry: %d.",
2436 						 function,
2437 						 file_io_pool_entry );
2438 
2439 						libewf_segment_file_free(
2440 						 &segment_file,
2441 						 NULL );
2442 
2443 						goto on_error;
2444 					}
2445 				}
2446 			}
2447 		}
2448 		if( libewf_segment_file_free(
2449 		     &segment_file,
2450 		     error ) != 1 )
2451 		{
2452 			libcerror_error_set(
2453 			 error,
2454 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2455 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2456 			 "%s: unable to free segment file.",
2457 			 function );
2458 
2459 			goto on_error;
2460 		}
2461 		if( libewf_handle_open_read_segment_files(
2462 		     internal_handle,
2463 		     file_io_pool,
2464 		     chunk_table,
2465 		     error ) != 1 )
2466 		{
2467 			libcerror_error_set(
2468 			 error,
2469 			 LIBCERROR_ERROR_DOMAIN_IO,
2470 			 LIBCERROR_IO_ERROR_READ_FAILED,
2471 			 "%s: unable to read segment files.",
2472 			 function );
2473 
2474 			if( ( access_flags & LIBEWF_ACCESS_FLAG_RESUME ) == 0 )
2475 			{
2476 				goto on_error;
2477 			}
2478 #if defined( HAVE_DEBUG_OUTPUT )
2479 			if( libcnotify_verbose != 0 )
2480 			{
2481 				if( ( error != NULL )
2482 				 && ( *error != NULL ) )
2483 				{
2484 					libcnotify_print_error_backtrace(
2485 					 *error );
2486 				}
2487 			}
2488 #endif
2489 			libcerror_error_free(
2490 			 error );
2491 		}
2492 		if( ( access_flags & LIBEWF_ACCESS_FLAG_RESUME ) == 0 )
2493 		{
2494 			if( libewf_handle_open_read_delta_segment_files(
2495 			     internal_handle,
2496 			     file_io_pool,
2497 			     error ) != 1 )
2498 			{
2499 				libcerror_error_set(
2500 				 error,
2501 				 LIBCERROR_ERROR_DOMAIN_IO,
2502 				 LIBCERROR_IO_ERROR_READ_FAILED,
2503 				 "%s: unable to read delta segment files.",
2504 				 function );
2505 
2506 				goto on_error;
2507 			}
2508 		}
2509 		/* Determine the EWF format
2510 		 */
2511 		if( libewf_header_sections_parse(
2512 		     internal_handle->header_sections,
2513 		     internal_handle->io_handle,
2514 		     internal_handle->header_values,
2515 		     &( internal_handle->io_handle->format ),
2516 		     error ) == -1 )
2517 		{
2518 			libcerror_error_set(
2519 			 error,
2520 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2521 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2522 			 "%s: unable to determine format.",
2523 			 function );
2524 
2525 			goto on_error;
2526 		}
2527 		if( internal_handle->io_handle->ewf_format == EWF_FORMAT_S01 )
2528 		{
2529 			internal_handle->io_handle->format = LIBEWF_FORMAT_SMART;
2530 		}
2531 		if( internal_handle->media_values == NULL )
2532 		{
2533 			libcerror_error_set(
2534 			 error,
2535 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2536 			 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2537 			 "%s: invalid handle - missing media values.",
2538 			 function );
2539 
2540 			goto on_error;
2541 		}
2542 		if( internal_handle->single_files->ltree_data != NULL )
2543 		{
2544 			if( libewf_single_files_parse(
2545 			     internal_handle->single_files,
2546 			     &( internal_handle->media_values->media_size ),
2547 			     &( internal_handle->io_handle->format ),
2548 			     error ) != 1 )
2549 			{
2550 				libcerror_error_set(
2551 				 error,
2552 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2553 				 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2554 				 "%s: unable to parse single files.",
2555 				 function );
2556 
2557 				goto on_error;
2558 			}
2559 		}
2560 		else
2561 		{
2562 			if( libewf_internal_handle_get_media_values(
2563 			     internal_handle,
2564 			     &( internal_handle->media_values->media_size ),
2565 			     error ) != 1 )
2566 			{
2567 				libcerror_error_set(
2568 				 error,
2569 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2570 				 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2571 				 "%s: unable to determine media values.",
2572 				 function );
2573 
2574 				goto on_error;
2575 			}
2576 		}
2577 	}
2578 	/* Make sure format specific values are set
2579 	 */
2580 	if( internal_handle->io_handle->format != 0 )
2581 	{
2582 		if( libewf_internal_handle_set_format(
2583 		     internal_handle,
2584 		     internal_handle->io_handle->format,
2585 		     error ) != 1 )
2586 		{
2587 			libcerror_error_set(
2588 			 error,
2589 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2590 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2591 			 "%s: unable to set format.",
2592 			 function );
2593 
2594 			goto on_error;
2595 		}
2596 	}
2597 	if( ( ( access_flags & LIBEWF_ACCESS_FLAG_WRITE ) != 0 )
2598 	 && ( ( access_flags & LIBEWF_ACCESS_FLAG_RESUME ) != 0 ) )
2599 	{
2600 		if( internal_handle->write_io_handle->values_initialized == 0 )
2601 		{
2602 			if( libewf_write_io_handle_initialize_values(
2603 			     internal_handle->write_io_handle,
2604 			     internal_handle->io_handle,
2605 			     internal_handle->media_values,
2606 			     internal_handle->segment_table,
2607 			     error ) != 1 )
2608 			{
2609 				libcerror_error_set(
2610 				 error,
2611 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2612 				 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2613 				 "%s: unable to initialize write IO handle values.",
2614 				 function );
2615 
2616 				goto on_error;
2617 			}
2618 		}
2619 		if( libewf_write_io_handle_initialize_resume(
2620 		     internal_handle->write_io_handle,
2621 		     internal_handle->io_handle,
2622 		     file_io_pool,
2623 		     internal_handle->media_values,
2624 		     internal_handle->segment_files_list,
2625 		     internal_handle->segment_files_cache,
2626 		     internal_handle->chunk_table_list,
2627 		     chunk_table,
2628 		     internal_handle->segment_table,
2629 		     error ) != 1 )
2630 		{
2631 			libcerror_error_set(
2632 			 error,
2633 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2634 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2635 			 "%s: unable to initialize write IO handle to resume.",
2636 			 function );
2637 
2638 			goto on_error;
2639 		}
2640 	}
2641 	internal_handle->io_handle->access_flags = access_flags;
2642 	internal_handle->file_io_pool            = file_io_pool;
2643 
2644 	return( 1 );
2645 
2646 on_error:
2647 	if( internal_handle->single_files != NULL )
2648 	{
2649 		libewf_single_files_free(
2650 		 &( internal_handle->single_files ),
2651 		 NULL );
2652 	}
2653 	if( internal_handle->hash_sections != NULL )
2654 	{
2655 		libewf_hash_sections_free(
2656 		 &( internal_handle->hash_sections ),
2657 		 NULL );
2658 	}
2659 	if( internal_handle->header_values != NULL )
2660 	{
2661 		libfvalue_table_free(
2662 		 &( internal_handle->header_values ),
2663 		 NULL );
2664 	}
2665 	if( internal_handle->header_sections != NULL )
2666 	{
2667 		libewf_header_sections_free(
2668 		 &( internal_handle->header_sections ),
2669 		 NULL );
2670 	}
2671 	if( internal_handle->chunk_table_cache != NULL )
2672 	{
2673 		libfcache_cache_free(
2674 		 &( internal_handle->chunk_table_cache ),
2675 		 NULL );
2676 	}
2677 	if( internal_handle->chunk_table_list != NULL )
2678 	{
2679 		libmfdata_list_free(
2680 		 &( internal_handle->chunk_table_list ),
2681 		 NULL );
2682 	}
2683 	if( internal_handle->segment_files_cache != NULL )
2684 	{
2685 		libfcache_cache_free(
2686 		 &( internal_handle->segment_files_cache ),
2687 		 NULL );
2688 	}
2689 	if( internal_handle->segment_files_list != NULL )
2690 	{
2691 		libmfdata_file_list_free(
2692 		 &( internal_handle->segment_files_list ),
2693 		 NULL );
2694 	}
2695 	if( internal_handle->delta_segment_files_list != NULL )
2696 	{
2697 		libmfdata_file_list_free(
2698 		 &( internal_handle->delta_segment_files_list ),
2699 		 NULL );
2700 	}
2701 	if( internal_handle->write_io_handle != NULL )
2702 	{
2703 		libewf_write_io_handle_free(
2704 		 &( internal_handle->write_io_handle ),
2705 		 error );
2706 	}
2707 	if( internal_handle->read_io_handle != NULL )
2708 	{
2709 		libewf_read_io_handle_free(
2710 		 &( internal_handle->read_io_handle ),
2711 		 error );
2712 	}
2713 	return( -1 );
2714 }
2715 
2716 /* Opens the segment files for reading
2717  * Returns 1 if successful or -1 on error
2718  */
libewf_handle_open_read_segment_files(libewf_internal_handle_t * internal_handle,libbfio_pool_t * file_io_pool,libewf_chunk_table_t * chunk_table,libcerror_error_t ** error)2719 int libewf_handle_open_read_segment_files(
2720      libewf_internal_handle_t *internal_handle,
2721      libbfio_pool_t *file_io_pool,
2722      libewf_chunk_table_t *chunk_table,
2723      libcerror_error_t **error )
2724 {
2725 	libewf_section_t *section           = NULL;
2726 	libewf_segment_file_t *segment_file = NULL;
2727 	static char *function               = "libewf_handle_open_read_segment_files";
2728 	off64_t section_offset              = 0;
2729 	size64_t maximum_segment_size       = 0;
2730 	size64_t segment_file_size          = 0;
2731 	ssize_t read_count                  = 0;
2732 	int file_io_pool_entry              = 0;
2733 	int number_of_segment_files         = 0;
2734 	int known_section                   = 0;
2735 	int last_section                    = 0;
2736 	int last_segment_file               = 0;
2737 	int segment_files_list_index        = 0;
2738 
2739 	if( internal_handle == NULL )
2740 	{
2741 		libcerror_error_set(
2742 		 error,
2743 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2744 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2745 		 "%s: invalid handle.",
2746 		 function );
2747 
2748 		return( -1 );
2749 	}
2750 	if( internal_handle->io_handle == NULL )
2751 	{
2752 		libcerror_error_set(
2753 		 error,
2754 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2755 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2756 		 "%s: invalid handle - missing IO handle.",
2757 		 function );
2758 
2759 		return( -1 );
2760 	}
2761 	if( internal_handle->header_sections == NULL )
2762 	{
2763 		libcerror_error_set(
2764 		 error,
2765 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2766 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2767 		 "%s: invalid handle - missing header sections.",
2768 		 function );
2769 
2770 		return( -1 );
2771 	}
2772 	if( internal_handle->segment_table == NULL )
2773 	{
2774 		libcerror_error_set(
2775 		 error,
2776 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2777 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2778 		 "%s: invalid handle - missing segment table.",
2779 		 function );
2780 
2781 		return( -1 );
2782 	}
2783 	if( internal_handle->single_files == NULL )
2784 	{
2785 		libcerror_error_set(
2786 		 error,
2787 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2788 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2789 		 "%s: invalid handle - missing single files.",
2790 		 function );
2791 
2792 		return( -1 );
2793 	}
2794 	if( libmfdata_file_list_get_number_of_files(
2795 	     internal_handle->segment_files_list,
2796 	     &number_of_segment_files,
2797 	     error ) != 1 )
2798 	{
2799 		libcerror_error_set(
2800 		 error,
2801 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2802 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2803 		 "%s: unable to retrieve number of segment files in list.",
2804 		 function );
2805 
2806 		goto on_error;
2807 	}
2808 	if( number_of_segment_files <= 0 )
2809 	{
2810 		libcerror_error_set(
2811 		 error,
2812 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2813 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2814 		 "%s: number of segment files value out of bounds.",
2815 		 function );
2816 
2817 		goto on_error;
2818 	}
2819 	for( segment_files_list_index = 0;
2820 	     segment_files_list_index < number_of_segment_files;
2821 	     segment_files_list_index++ )
2822 	{
2823 		if( libmfdata_file_list_get_file_by_index(
2824 		     internal_handle->segment_files_list,
2825 		     segment_files_list_index,
2826 		     &file_io_pool_entry,
2827 		     error ) != 1 )
2828 		{
2829 			libcerror_error_set(
2830 			 error,
2831 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2832 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2833 			 "%s: unable to retrieve segment file: %d from list.",
2834 			 function,
2835 			 segment_files_list_index + 1 );
2836 
2837 			goto on_error;
2838 		}
2839 		if( libbfio_pool_get_size(
2840 		     file_io_pool,
2841 		     file_io_pool_entry,
2842 		     &segment_file_size,
2843 		     error ) != 1 )
2844 		{
2845 			libcerror_error_set(
2846 			 error,
2847 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2848 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2849 			 "%s: unable to retrieve size of file IO pool entry: %d.",
2850 			 function,
2851 			 file_io_pool_entry );
2852 
2853 			goto on_error;
2854 		}
2855 		if( ( segment_files_list_index == 0 )
2856 		 && ( number_of_segment_files > 1 ) )
2857 		{
2858 			/* Round the maximum segment size to nearest number of KiB
2859 			 */
2860 			maximum_segment_size = ( segment_file_size >> 10 ) << 10;
2861 
2862 			if( libewf_segment_table_set_maximum_segment_size(
2863 			     internal_handle->segment_table,
2864 			     maximum_segment_size,
2865 			     error ) != 1 )
2866 			{
2867 				libcerror_error_set(
2868 				 error,
2869 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2870 				 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2871 				 "%s: unable to set maximum segment size in segment table.",
2872 				 function );
2873 
2874 				goto on_error;
2875 			}
2876 		}
2877 		if( libewf_segment_file_initialize(
2878 		     &segment_file,
2879 		     error ) != 1 )
2880 		{
2881 			libcerror_error_set(
2882 			 error,
2883 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2884 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2885 			 "%s: unable to create segment file.",
2886 			 function );
2887 
2888 			goto on_error;
2889 		}
2890 		read_count = libewf_segment_file_read_file_header(
2891 			      segment_file,
2892 			      file_io_pool,
2893 			      file_io_pool_entry,
2894 			      error );
2895 
2896 		if( read_count < 0 )
2897 		{
2898 			libcerror_error_set(
2899 			 error,
2900 			 LIBCERROR_ERROR_DOMAIN_IO,
2901 			 LIBCERROR_IO_ERROR_READ_FAILED,
2902 			 "%s: unable to read segment file header.",
2903 			 function );
2904 
2905 			libewf_segment_file_free(
2906 			 &segment_file,
2907 			 NULL );
2908 
2909 			goto on_error;
2910 		}
2911 		if( ( segment_file->type != LIBEWF_SEGMENT_FILE_TYPE_EWF )
2912 		 && ( segment_file->type != LIBEWF_SEGMENT_FILE_TYPE_LWF ) )
2913 		{
2914 			libcerror_error_set(
2915 			 error,
2916 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2917 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2918 			 "%s: unsupported segment file type.",
2919 			 function );
2920 
2921 			libewf_segment_file_free(
2922 			 &segment_file,
2923 			 NULL );
2924 
2925 			goto on_error;
2926 		}
2927 		if( segment_file->segment_number != ( segment_files_list_index + 1 ) )
2928 		{
2929 			libcerror_error_set(
2930 			 error,
2931 			 LIBCERROR_ERROR_DOMAIN_INPUT,
2932 			 LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
2933 			 "%s: segment number mismatch.",
2934 			 function );
2935 
2936 			libewf_segment_file_free(
2937 			 &segment_file,
2938 			 NULL );
2939 
2940 			goto on_error;
2941 		}
2942 		/* The segment file is cached here in case of resume
2943 		 */
2944 		if( libmfdata_file_list_set_file_value_by_index(
2945 		     internal_handle->segment_files_list,
2946 		     internal_handle->segment_files_cache,
2947 		     segment_files_list_index,
2948 		     (intptr_t *) segment_file,
2949 		     (int (*)(intptr_t **, libcerror_error_t **)) &libewf_segment_file_free,
2950 		     LIBMFDATA_FILE_VALUE_FLAG_MANAGED,
2951 		     error ) != 1 )
2952 		{
2953 			libcerror_error_set(
2954 			 error,
2955 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2956 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2957 			 "%s: unable to set segment file: %d in list.",
2958 			 function,
2959 			 segment_files_list_index + 1 );
2960 
2961 			libewf_segment_file_free(
2962 			 &segment_file,
2963 			 NULL );
2964 
2965 			goto on_error;
2966 		}
2967 		/* The segment file is now handled by the segment files list
2968 		 */
2969 		section_offset = (off64_t) read_count;
2970 		last_section   = 0;
2971 
2972 		while( (size64_t) section_offset < segment_file_size )
2973 		{
2974 			if( libewf_section_initialize(
2975 			     &section,
2976 			     error ) != 1 )
2977 			{
2978 				libcerror_error_set(
2979 				 error,
2980 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2981 				 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2982 				 "%s: unable to create section.",
2983 				 function );
2984 
2985 				goto on_error;
2986 			}
2987 			read_count = libewf_section_start_read(
2988 			              section,
2989 			              file_io_pool,
2990 			              file_io_pool_entry,
2991 			              section_offset,
2992 			              error );
2993 
2994 			if( read_count == -1 )
2995 			{
2996 				libcerror_error_set(
2997 				 error,
2998 				 LIBCERROR_ERROR_DOMAIN_IO,
2999 				 LIBCERROR_IO_ERROR_READ_FAILED,
3000 				 "%s: unable to read section start.",
3001 				 function );
3002 
3003 				if( libewf_section_free(
3004 				     &section,
3005 				     error ) != 1 )
3006 				{
3007 					libcerror_error_set(
3008 					 error,
3009 					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3010 					 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3011 					 "%s: unable to free section.",
3012 					 function );
3013 
3014 					goto on_error;
3015 				}
3016 #if defined( HAVE_DEBUG_OUTPUT )
3017 				if( libcnotify_verbose != 0 )
3018 				{
3019 					if( ( error != NULL )
3020 					 && ( *error != NULL ) )
3021 					{
3022 						libcnotify_print_error_backtrace(
3023 						 *error );
3024 					}
3025 				}
3026 #endif
3027 				libcerror_error_free(
3028 				 error );
3029 
3030 				segment_file->flags |= LIBEWF_SEGMENT_FILE_FLAG_CORRUPTED;
3031 
3032 				internal_handle->segment_table->flags |= LIBEWF_SEGMENT_TABLE_FLAG_CORRUPTED;
3033 
3034 				break;
3035 			}
3036 			if( section->type_length == 4 )
3037 			{
3038 				if( memory_compare(
3039 				     (void *) section->type,
3040 				     (void *) "data",
3041 				     4 ) == 0 )
3042 				{
3043 #if defined( HAVE_VERBOSE_OUTPUT )
3044                 			if( libcnotify_verbose != 0 )
3045 				        {
3046 						if( internal_handle->io_handle->ewf_format == EWF_FORMAT_S01 )
3047 				                {
3048 				                        libcnotify_printf(
3049 				                         "%s: found data section in EWF-S01 format.\n",
3050 				                         function );
3051 				                }
3052 				        }
3053 #endif
3054 					read_count = libewf_section_data_read(
3055 						      section,
3056 						      internal_handle->io_handle,
3057 						      file_io_pool,
3058 						      file_io_pool_entry,
3059 						      internal_handle->media_values,
3060 						      error );
3061 
3062 					known_section = 1;
3063 				}
3064 				else if( memory_compare(
3065 					  (void *) section->type,
3066 					  (void *) "disk",
3067 					  4 ) == 0 )
3068 				{
3069 					read_count = libewf_segment_file_read_volume_section(
3070 						      segment_file,
3071 						      section,
3072 						      internal_handle->io_handle,
3073 						      file_io_pool,
3074 						      file_io_pool_entry,
3075 						      internal_handle->media_values,
3076 						      internal_handle->chunk_table_list,
3077 						      error );
3078 
3079 					/* Check if the EWF file format is that of EnCase1
3080 					 * this allows the table read function to reduce verbose
3081 					 * output of additional data in table section
3082 					 */
3083 					if( ( internal_handle->io_handle->ewf_format == EWF_FORMAT_E01 )
3084 					 && ( internal_handle->header_sections->number_of_header_sections == 1 ) )
3085 					{
3086 						internal_handle->io_handle->format = LIBEWF_FORMAT_ENCASE1;
3087 					}
3088 					known_section = 1;
3089 				}
3090 				else if( memory_compare(
3091 					  (void *) section->type,
3092 					  (void *) "done",
3093 					  4 ) == 0 )
3094 				{
3095 					if( ( segment_files_list_index + 1 ) != number_of_segment_files )
3096 					{
3097 						libcerror_error_set(
3098 						 error,
3099 						 LIBCERROR_ERROR_DOMAIN_INPUT,
3100 						 LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
3101 						 "%s: last segment number mismatch.",
3102 						 function );
3103 
3104 						goto on_error;
3105 					}
3106 					/* Nothing to do for the done section
3107 					 */
3108 					known_section     = 1;
3109 					last_section      = 1;
3110 					last_segment_file = 1;
3111 				}
3112 				else if( memory_compare(
3113 					  (void *) section->type,
3114 					  (void *) "hash",
3115 					  4 ) == 0 )
3116 				{
3117 					read_count = libewf_section_hash_read(
3118 						      section,
3119 						      file_io_pool,
3120 						      file_io_pool_entry,
3121 						      internal_handle->hash_sections,
3122 						      error );
3123 
3124 					known_section = 1;
3125 				}
3126 				else if( memory_compare(
3127 					  (void *) section->type,
3128 					  (void *) "next",
3129 					  4 ) == 0 )
3130 				{
3131 					/* Nothing to do for the next section
3132 					 */
3133 					known_section = 1;
3134 					last_section  = 1;
3135 				}
3136 			}
3137 			else if( section->type_length == 5 )
3138 			{
3139 				if( memory_compare(
3140 				     (void *) section->type,
3141 				     (void *) "ltree",
3142 				     5 ) == 0 )
3143 				{
3144 					if( internal_handle->io_handle->ewf_format != EWF_FORMAT_L01 )
3145 				        {
3146 #if defined( HAVE_VERBOSE_OUTPUT )
3147                 				if( libcnotify_verbose != 0 )
3148 				                {
3149 				                        libcnotify_printf(
3150 				                         "%s: found ltree section in EWF-E01 or EWF-S01 format.\n",
3151 				                         function );
3152 				                }
3153 #endif
3154 						internal_handle->io_handle->ewf_format = EWF_FORMAT_L01;
3155 				        }
3156 					read_count = libewf_section_ltree_read(
3157 						      section,
3158 						      file_io_pool,
3159 						      file_io_pool_entry,
3160 						      &( internal_handle->single_files->ltree_data ),
3161 						      &( internal_handle->single_files->ltree_data_size ),
3162 						      error );
3163 
3164 					known_section = 1;
3165 				}
3166 				else if( memory_compare(
3167 					  (void *) section->type,
3168 					  (void *) "table",
3169 					  5 ) == 0 )
3170 				{
3171 					read_count = libewf_segment_file_read_table_section(
3172 						      segment_file,
3173 						      section,
3174 						      internal_handle->io_handle,
3175 						      file_io_pool,
3176 						      file_io_pool_entry,
3177 						      internal_handle->media_values,
3178 						      chunk_table,
3179 						      internal_handle->chunk_table_list,
3180 						      error );
3181 
3182 					known_section = 1;
3183 				}
3184 				else if( memory_compare(
3185 					  (void *) section->type,
3186 					  (void *) "xhash",
3187 					  5 ) == 0 )
3188 				{
3189 #if defined( HAVE_VERBOSE_OUTPUT )
3190                 			if( libcnotify_verbose != 0 )
3191 				        {
3192 						if( internal_handle->io_handle->ewf_format == EWF_FORMAT_S01 )
3193 				                {
3194 				                        libcnotify_printf(
3195 				                         "%s: found xhash section in EWF-S01 format.\n",
3196 				                         function );
3197 				                }
3198 				        }
3199 #endif
3200 					read_count = libewf_section_xhash_read(
3201 						      section,
3202 						      file_io_pool,
3203 						      file_io_pool_entry,
3204 						      internal_handle->hash_sections,
3205 						      error );
3206 
3207 					known_section = 1;
3208 				}
3209 			}
3210 			else if( section->type_length == 6 )
3211 			{
3212 				if( memory_compare(
3213 				     (void *) section->type,
3214 				     (void *) "digest",
3215 				     6 ) == 0 )
3216 				{
3217 #if defined( HAVE_VERBOSE_OUTPUT )
3218                 			if( libcnotify_verbose != 0 )
3219 				        {
3220 						if( internal_handle->io_handle->ewf_format == EWF_FORMAT_S01 )
3221 				                {
3222 				                        libcnotify_printf(
3223 				                         "%s: found digest section in EWF-S01 format.\n",
3224 				                         function );
3225 				                }
3226 				        }
3227 #endif
3228 					read_count = libewf_section_digest_read(
3229 						      section,
3230 						      file_io_pool,
3231 						      file_io_pool_entry,
3232 						      internal_handle->hash_sections,
3233 						      error );
3234 
3235 					known_section = 1;
3236 				}
3237 				else if( memory_compare(
3238 					  (void *) section->type,
3239 					  (void *) "error2",
3240 					  6 ) == 0 )
3241 				{
3242 #if defined( HAVE_VERBOSE_OUTPUT )
3243                 			if( libcnotify_verbose != 0 )
3244 				        {
3245 						if( internal_handle->io_handle->ewf_format == EWF_FORMAT_S01 )
3246 				                {
3247 				                        libcnotify_printf(
3248 				                         "%s: found error2 section in EWF-S01 format.\n",
3249 				                         function );
3250 				                }
3251 				        }
3252 #endif
3253 					read_count = libewf_section_error2_read(
3254 						      section,
3255 						      file_io_pool,
3256 						      file_io_pool_entry,
3257 						      internal_handle->acquiry_errors,
3258 						      error );
3259 
3260 					known_section = 1;
3261 				}
3262 				else if( memory_compare(
3263 					  (void *) section->type,
3264 					  (void *) "header",
3265 					  6 ) == 0 )
3266 				{
3267 					read_count = libewf_section_header_read(
3268 						      section,
3269 						      file_io_pool,
3270 						      file_io_pool_entry,
3271 						      internal_handle->header_sections,
3272 						      error );
3273 
3274 					known_section = 1;
3275 				}
3276 				else if( memory_compare(
3277 					  (void *) section->type,
3278 					  (void *) "table2",
3279 					  6 ) == 0 )
3280 				{
3281 					read_count = libewf_segment_file_read_table2_section(
3282 						      segment_file,
3283 						      section,
3284 						      internal_handle->io_handle,
3285 						      file_io_pool,
3286 						      file_io_pool_entry,
3287 						      chunk_table,
3288 						      internal_handle->chunk_table_list,
3289 						      error );
3290 
3291 					known_section = 1;
3292 				}
3293 				else if( memory_compare(
3294 					  (void *) section->type,
3295 					  (void *) "volume",
3296 					  6 ) == 0 )
3297 				{
3298 					read_count = libewf_segment_file_read_volume_section(
3299 						      segment_file,
3300 						      section,
3301 						      internal_handle->io_handle,
3302 						      file_io_pool,
3303 						      file_io_pool_entry,
3304 						      internal_handle->media_values,
3305 						      internal_handle->chunk_table_list,
3306 						      error );
3307 
3308 					/* Check if the EWF file format is that of EnCase1
3309 					 * this allows the table read function to reduce verbose
3310 					 * output of additional data in table section
3311 					 */
3312 					if( ( internal_handle->io_handle->ewf_format == EWF_FORMAT_E01 )
3313 					 && ( internal_handle->header_sections->number_of_header_sections == 1 ) )
3314 					{
3315 						internal_handle->io_handle->format = LIBEWF_FORMAT_ENCASE1;
3316 					}
3317 					known_section = 1;
3318 				}
3319 			}
3320 			else if( section->type_length == 7 )
3321 			{
3322 				if( memory_compare(
3323 				     (void *) section->type,
3324 				     (void *) "header2",
3325 				     7 ) == 0 )
3326 				{
3327 					read_count = libewf_section_header2_read(
3328 						      section,
3329 						      file_io_pool,
3330 						      file_io_pool_entry,
3331 						      internal_handle->header_sections,
3332 						      error );
3333 
3334 					known_section = 1;
3335 				}
3336 				else if( memory_compare(
3337 					  (void *) section->type,
3338 					  (void *) "sectors",
3339 					  7 ) == 0 )
3340 				{
3341 #if defined( HAVE_VERBOSE_OUTPUT )
3342                 			if( libcnotify_verbose != 0 )
3343 				        {
3344 						if( internal_handle->io_handle->ewf_format == EWF_FORMAT_S01 )
3345 				                {
3346 				                        libcnotify_printf(
3347 				                         "%s: found sectors section in EWF-S01 format.\n",
3348 				                         function );
3349 				                }
3350 				        }
3351 #endif
3352 					/* Nothing to do for the sectors section
3353 					 */
3354 					known_section = 1;
3355 				}
3356 				else if( memory_compare(
3357 					  (void *) section->type,
3358 					  (void *) "session",
3359 					  7 ) == 0 )
3360 				{
3361 #if defined( HAVE_VERBOSE_OUTPUT )
3362                 			if( libcnotify_verbose != 0 )
3363 				        {
3364 						if( internal_handle->io_handle->ewf_format == EWF_FORMAT_S01 )
3365 				                {
3366 				                        libcnotify_printf(
3367 				                         "%s: found session section in EWF-S01 format.\n",
3368 				                         function );
3369 				                }
3370 				        }
3371 #endif
3372 					read_count = libewf_section_session_read(
3373 						      section,
3374 						      file_io_pool,
3375 						      file_io_pool_entry,
3376 						      internal_handle->media_values,
3377 						      internal_handle->sessions,
3378 						      internal_handle->tracks,
3379 						      error );
3380 
3381 					known_section = 1;
3382 				}
3383 				else if( memory_compare(
3384 					  (void *) section->type,
3385 					  (void *) "xheader",
3386 					  7 ) == 0 )
3387 				{
3388 					read_count = libewf_section_xheader_read(
3389 						      section,
3390 						      file_io_pool,
3391 						      file_io_pool_entry,
3392 						      internal_handle->header_sections,
3393 						      error );
3394 
3395 					known_section = 1;
3396 				}
3397 			}
3398 			if( known_section == 0 )
3399 			{
3400 #if defined( HAVE_VERBOSE_OUTPUT )
3401 				if( libcnotify_verbose != 0 )
3402 				{
3403 					libcnotify_printf(
3404 					 "%s: unsupported section type: %s.\n",
3405 					 function,
3406 					 (char *) section->type );
3407 				}
3408 #elif defined( HAVE_DEBUG_OUTPUT )
3409 				read_count = libewf_section_debug_read(
3410 					      section,
3411 					      file_io_pool,
3412 					      file_io_pool_entry,
3413 					      error );
3414 #endif
3415 			}
3416 			if( read_count == -1 )
3417 			{
3418 				libcerror_error_set(
3419 				 error,
3420 				 LIBCERROR_ERROR_DOMAIN_IO,
3421 				 LIBCERROR_IO_ERROR_READ_FAILED,
3422 				 "%s: unable to read section: %s.",
3423 				 function,
3424 				 (char *) section->type );
3425 
3426 				goto on_error;
3427 			}
3428 			section_offset += section->size;
3429 
3430 			if( ( last_section != 0 )
3431 			 && ( section->size == 0 ) )
3432 			{
3433 				section_offset += sizeof( ewf_section_start_t );
3434 			}
3435 			if( libcdata_list_append_value(
3436 			     segment_file->section_list,
3437 			     (intptr_t *) section,
3438 			     error ) != 1 )
3439 			{
3440 				libcerror_error_set(
3441 				 error,
3442 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3443 				 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
3444 				 "%s: unable to append section to list.",
3445 				 function );
3446 
3447 				goto on_error;
3448 			}
3449 			section = NULL;
3450 
3451 			segment_file->last_section_offset = section_offset;
3452 
3453 			if( last_section != 0 )
3454 			{
3455 				break;
3456 			}
3457 		}
3458 		if( ( segment_file->flags & LIBEWF_SEGMENT_FILE_FLAG_CORRUPTED ) == 0 )
3459 		{
3460 			if( last_section == 0 )
3461 			{
3462 				libcerror_error_set(
3463 				 error,
3464 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3465 				 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3466 				 "%s: missing next or done section.",
3467 				 function );
3468 
3469 #if defined( HAVE_DEBUG_OUTPUT )
3470 				if( libcnotify_verbose != 0 )
3471 				{
3472 					if( ( error != NULL )
3473 					 && ( *error != NULL ) )
3474 					{
3475 						libcnotify_print_error_backtrace(
3476 						 *error );
3477 					}
3478 				}
3479 #endif
3480 				libcerror_error_free(
3481 				 error );
3482 
3483 				segment_file->flags |= LIBEWF_SEGMENT_FILE_FLAG_CORRUPTED;
3484 
3485 				internal_handle->segment_table->flags |= LIBEWF_SEGMENT_TABLE_FLAG_CORRUPTED;
3486 
3487 				break;
3488 			}
3489 #if defined( HAVE_DEBUG_OUTPUT )
3490 			else if( libcnotify_verbose != 0 )
3491 			{
3492 				if( (size64_t) section_offset < segment_file_size )
3493 				{
3494 					libcnotify_printf(
3495 					 "%s: trailing data in segment file: %" PRIu16 "\n",
3496 					 function,
3497 					 segment_files_list_index );
3498 				}
3499 			}
3500 #endif
3501 		}
3502 		segment_file = NULL;
3503 	}
3504 	if( last_segment_file == 0 )
3505 	{
3506 		libcerror_error_set(
3507 		 error,
3508 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3509 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3510 		 "%s: missing done section.",
3511 		 function );
3512 
3513 #if defined( HAVE_DEBUG_OUTPUT )
3514 		if( libcnotify_verbose != 0 )
3515 		{
3516 			if( ( error != NULL )
3517 			 && ( *error != NULL ) )
3518 			{
3519 				libcnotify_print_error_backtrace(
3520 				 *error );
3521 			}
3522 		}
3523 #endif
3524 		libcerror_error_free(
3525 		 error );
3526 
3527 		internal_handle->segment_table->flags |= LIBEWF_SEGMENT_TABLE_FLAG_CORRUPTED;
3528 	}
3529 	return( 1 );
3530 
3531 on_error:
3532 	if( section != NULL )
3533 	{
3534 		libewf_section_free(
3535 		 &section,
3536 		 NULL );
3537 	}
3538 	return( -1 );
3539 }
3540 
3541 /* Opens the delta segment files for reading
3542  * Returns 1 if successful or -1 on error
3543  */
libewf_handle_open_read_delta_segment_files(libewf_internal_handle_t * internal_handle,libbfio_pool_t * file_io_pool,libcerror_error_t ** error)3544 int libewf_handle_open_read_delta_segment_files(
3545      libewf_internal_handle_t *internal_handle,
3546      libbfio_pool_t *file_io_pool,
3547      libcerror_error_t **error )
3548 {
3549 	libewf_section_t *section           = NULL;
3550 	libewf_segment_file_t *segment_file = NULL;
3551 	static char *function               = "libewf_handle_open_read_delta_segment_files";
3552 	off64_t section_offset              = 0;
3553 	size64_t maximum_segment_size       = 0;
3554 	size64_t segment_file_size          = 0;
3555 	ssize_t read_count                  = 0;
3556 	int file_io_pool_entry              = 0;
3557 	int number_of_segment_files         = 0;
3558 	int known_section                   = 0;
3559 	int last_section                    = 0;
3560 	int last_segment_file               = 0;
3561 	int segment_files_list_index        = 0;
3562 
3563 	if( internal_handle == NULL )
3564 	{
3565 		libcerror_error_set(
3566 		 error,
3567 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3568 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3569 		 "%s: invalid handle.",
3570 		 function );
3571 
3572 		return( -1 );
3573 	}
3574 	if( internal_handle->delta_segment_table == NULL )
3575 	{
3576 		libcerror_error_set(
3577 		 error,
3578 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3579 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3580 		 "%s: invalid handle - missing delta segment table.",
3581 		 function );
3582 
3583 		return( -1 );
3584 	}
3585 	if( libmfdata_file_list_get_number_of_files(
3586 	     internal_handle->delta_segment_files_list,
3587 	     &number_of_segment_files,
3588 	     error ) != 1 )
3589 	{
3590 		libcerror_error_set(
3591 		 error,
3592 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3593 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3594 		 "%s: unable to retrieve number of delta segment files in list.",
3595 		 function );
3596 
3597 		goto on_error;
3598 	}
3599 	if( number_of_segment_files <= 1 )
3600 	{
3601 		return( 1 );
3602 	}
3603 	for( segment_files_list_index = 0;
3604 	     segment_files_list_index < number_of_segment_files;
3605 	     segment_files_list_index++ )
3606 	{
3607 		if( libmfdata_file_list_get_file_by_index(
3608 		     internal_handle->segment_files_list,
3609 		     segment_files_list_index,
3610 		     &file_io_pool_entry,
3611 		     error ) != 1 )
3612 		{
3613 			libcerror_error_set(
3614 			 error,
3615 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3616 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3617 			 "%s: unable to retrieve data file: %d from segment files list.",
3618 			 function,
3619 			 segment_files_list_index + 1 );
3620 
3621 			goto on_error;
3622 		}
3623 		if( libbfio_pool_get_size(
3624 		     file_io_pool,
3625 		     file_io_pool_entry,
3626 		     &segment_file_size,
3627 		     error ) != 1 )
3628 		{
3629 			libcerror_error_set(
3630 			 error,
3631 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3632 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3633 			 "%s: unable to retrieve size of file IO pool entry: %d.",
3634 			 function,
3635 			 file_io_pool_entry );
3636 
3637 			goto on_error;
3638 		}
3639 		if( ( segment_files_list_index == 0 )
3640 		 && ( number_of_segment_files > 1 ) )
3641 		{
3642 			/* Round the maximum segment size to nearest number of KiB
3643 			 */
3644 			maximum_segment_size = ( segment_file_size >> 10 ) << 10;
3645 
3646 			if( libewf_segment_table_set_maximum_segment_size(
3647 			     internal_handle->delta_segment_table,
3648 			     maximum_segment_size,
3649 			     error ) != 1 )
3650 			{
3651 				libcerror_error_set(
3652 				 error,
3653 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3654 				 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3655 				 "%s: unable to set maximum segment size in delta segment table.",
3656 				 function );
3657 
3658 				goto on_error;
3659 			}
3660 		}
3661 		if( libewf_segment_file_initialize(
3662 		     &segment_file,
3663 		     error ) != 1 )
3664 		{
3665 			libcerror_error_set(
3666 			 error,
3667 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3668 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3669 			 "%s: unable to create segment file.",
3670 			 function );
3671 
3672 			goto on_error;
3673 		}
3674 		read_count = libewf_segment_file_read_file_header(
3675 			      segment_file,
3676 			      file_io_pool,
3677 			      file_io_pool_entry,
3678 			      error );
3679 
3680 		if( read_count < 0 )
3681 		{
3682 			libcerror_error_set(
3683 			 error,
3684 			 LIBCERROR_ERROR_DOMAIN_IO,
3685 			 LIBCERROR_IO_ERROR_READ_FAILED,
3686 			 "%s: unable to read segment file header.",
3687 			 function );
3688 
3689 			libewf_segment_file_free(
3690 			 &segment_file,
3691 			 NULL );
3692 
3693 			goto on_error;
3694 		}
3695 		if( segment_file->type != LIBEWF_SEGMENT_FILE_TYPE_DWF )
3696 		{
3697 			libcerror_error_set(
3698 			 error,
3699 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3700 			 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3701 			 "%s: unsupported segment file type.",
3702 			 function );
3703 
3704 			libewf_segment_file_free(
3705 			 &segment_file,
3706 			 NULL );
3707 
3708 			goto on_error;
3709 		}
3710 		if( segment_file->segment_number != ( segment_files_list_index + 1 ) )
3711 		{
3712 			libcerror_error_set(
3713 			 error,
3714 			 LIBCERROR_ERROR_DOMAIN_INPUT,
3715 			 LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
3716 			 "%s: segment number mismatch.",
3717 			 function );
3718 
3719 			libewf_segment_file_free(
3720 			 &segment_file,
3721 			 NULL );
3722 
3723 			goto on_error;
3724 		}
3725 		if( libmfdata_file_list_set_file_value_by_index(
3726 		     internal_handle->segment_files_list,
3727 		     internal_handle->segment_files_cache,
3728 		     segment_files_list_index,
3729 		     (intptr_t *) segment_file,
3730 		     (int (*)(intptr_t **, libcerror_error_t **)) &libewf_segment_file_free,
3731 		     LIBMFDATA_FILE_VALUE_FLAG_MANAGED,
3732 		     error ) != 1 )
3733 		{
3734 			libcerror_error_set(
3735 			 error,
3736 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3737 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3738 			 "%s: unable to set segment file: %d in segment files list.",
3739 			 function,
3740 			 segment_files_list_index + 1 );
3741 
3742 			goto on_error;
3743 		}
3744 		section_offset = (off64_t) read_count;
3745 		last_section   = 0;
3746 
3747 		while( (size64_t) section_offset < segment_file_size )
3748 		{
3749 			if( libewf_section_initialize(
3750 			     &section,
3751 			     error ) != 1 )
3752 			{
3753 				libcerror_error_set(
3754 				 error,
3755 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3756 				 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3757 				 "%s: unable to create section.",
3758 				 function );
3759 
3760 				goto on_error;
3761 			}
3762 			read_count = libewf_section_start_read(
3763 			              section,
3764 			              file_io_pool,
3765 			              file_io_pool_entry,
3766 			              section_offset,
3767 			              error );
3768 
3769 			if( read_count == -1 )
3770 			{
3771 				libcerror_error_set(
3772 				 error,
3773 				 LIBCERROR_ERROR_DOMAIN_IO,
3774 				 LIBCERROR_IO_ERROR_READ_FAILED,
3775 				 "%s: unable to read section start.",
3776 				 function );
3777 
3778 				goto on_error;
3779 			}
3780 			if( section->type_length == 4 )
3781 			{
3782 				if( memory_compare(
3783 				     (void *) section->type,
3784 				     (void *) "done",
3785 				     4 ) == 0 )
3786 				{
3787 					if( ( segment_files_list_index + 1 ) != number_of_segment_files )
3788 					{
3789 						libcerror_error_set(
3790 						 error,
3791 						 LIBCERROR_ERROR_DOMAIN_INPUT,
3792 						 LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
3793 						 "%s: last segment number mismatch.",
3794 						 function );
3795 
3796 						goto on_error;
3797 					}
3798 					/* Nothing to do for the done section
3799 					 */
3800 					known_section     = 1;
3801 					last_section      = 1;
3802 					last_segment_file = 1;
3803 				}
3804 				else if( memory_compare(
3805 				          (void *) section->type,
3806 				          (void *) "next",
3807 				          4 ) == 0 )
3808 				{
3809 					/* Nothing to do for the next section
3810 					 */
3811 					known_section = 1;
3812 					last_section  = 1;
3813 				}
3814 			}
3815 			else if( section->type_length == 11 )
3816 			{
3817 				if( memory_compare(
3818 				     (void *) section->type,
3819 				     (void *) "delta_chunk",
3820 				     11 ) == 0 )
3821 				{
3822 					read_count = libewf_segment_file_read_delta_chunk_section(
3823 						      segment_file,
3824 						      section,
3825 						      file_io_pool,
3826 						      file_io_pool_entry,
3827 						      internal_handle->chunk_table_list,
3828 						      error );
3829 
3830 					known_section = 1;
3831 				}
3832 			}
3833 			if( known_section == 0 )
3834 			{
3835 #if defined( HAVE_VERBOSE_OUTPUT )
3836 				if( libcnotify_verbose != 0 )
3837 				{
3838 					libcnotify_printf(
3839 					 "%s: unsupported section type: %s.\n",
3840 					 function,
3841 					 (char *) section->type );
3842 				}
3843 #elif defined( HAVE_DEBUG_OUTPUT )
3844 				read_count = libewf_section_debug_read(
3845 					      section,
3846 					      file_io_pool,
3847 					      file_io_pool_entry,
3848 					      error );
3849 #endif
3850 			}
3851 			if( read_count == -1 )
3852 			{
3853 				libcerror_error_set(
3854 				 error,
3855 				 LIBCERROR_ERROR_DOMAIN_IO,
3856 				 LIBCERROR_IO_ERROR_READ_FAILED,
3857 				 "%s: unable to read section: %s.",
3858 				 function,
3859 				 (char *) section->type );
3860 
3861 				goto on_error;
3862 			}
3863 			section_offset += section->size;
3864 
3865 			if( ( last_section != 0 )
3866 			 && ( section->size == 0 ) )
3867 			{
3868 				section_offset += sizeof( ewf_section_start_t );
3869 			}
3870 			if( libcdata_list_append_value(
3871 			     segment_file->section_list,
3872 			     (intptr_t *) section,
3873 			     error ) != 1 )
3874 			{
3875 				libcerror_error_set(
3876 				 error,
3877 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3878 				 LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
3879 				 "%s: unable to append section to list.",
3880 				 function );
3881 
3882 				goto on_error;
3883 			}
3884 			section = NULL;
3885 
3886 			if( last_section != 0 )
3887 			{
3888 				break;
3889 			}
3890 		}
3891 		if( last_section == 0 )
3892 		{
3893 			libcerror_error_set(
3894 			 error,
3895 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3896 			 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3897 			 "%s: missing next or done section.",
3898 			 function );
3899 
3900 			goto on_error;
3901 		}
3902 #if defined( HAVE_DEBUG_OUTPUT )
3903 		if( libcnotify_verbose != 0 )
3904 		{
3905 			if( (size64_t) section_offset < segment_file_size )
3906 			{
3907 				libcnotify_printf(
3908 				 "%s: trailing data in segment file: %" PRIu16 "\n",
3909 				 function,
3910 				 segment_files_list_index );
3911 			}
3912 		}
3913 #endif
3914 		segment_file = NULL;
3915 	}
3916 	if( last_segment_file == 0 )
3917 	{
3918 		libcerror_error_set(
3919 		 error,
3920 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
3921 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3922 		 "%s: missing done section.",
3923 		 function );
3924 
3925 		goto on_error;
3926 	}
3927 	return( 1 );
3928 
3929 on_error:
3930 	if( section != NULL )
3931 	{
3932 		libewf_section_free(
3933 		 &section,
3934 		 NULL );
3935 	}
3936 	return( -1 );
3937 }
3938 
3939 /* Closes the EWF handle
3940  * Returns 0 if successful or -1 on error
3941  */
libewf_handle_close(libewf_handle_t * handle,libcerror_error_t ** error)3942 int libewf_handle_close(
3943      libewf_handle_t *handle,
3944      libcerror_error_t **error )
3945 {
3946 	libewf_internal_handle_t *internal_handle = NULL;
3947 	static char *function                     = "libewf_handle_close";
3948 	ssize_t write_count                       = 0;
3949 	int result                                = 0;
3950 
3951 	if( handle == NULL )
3952 	{
3953 		libcerror_error_set(
3954 		 error,
3955 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3956 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3957 		 "%s: invalid handle.",
3958 		 function );
3959 
3960 		return( -1 );
3961 	}
3962 	internal_handle = (libewf_internal_handle_t *) handle;
3963 
3964 	if( ( internal_handle->write_io_handle != NULL )
3965 	 && ( internal_handle->write_io_handle->write_finalized == 0 ) )
3966 	{
3967 		write_count = libewf_handle_write_finalize(
3968 		               handle,
3969 		               error );
3970 
3971 		if( write_count < 0 )
3972 		{
3973 			libcerror_error_set(
3974 			 error,
3975 			 LIBCERROR_ERROR_DOMAIN_IO,
3976 			 LIBCERROR_IO_ERROR_WRITE_FAILED,
3977 			 "%s: unable to finalize write.",
3978 			 function );
3979 
3980 			result = -1;
3981 		}
3982 	}
3983 	if( internal_handle->file_io_pool_created_in_library != 0 )
3984 	{
3985 		if( libbfio_pool_close_all(
3986 		     internal_handle->file_io_pool,
3987 		     error ) != 0 )
3988 		{
3989 			libcerror_error_set(
3990 			 error,
3991 			 LIBCERROR_ERROR_DOMAIN_IO,
3992 			 LIBCERROR_IO_ERROR_CLOSE_FAILED,
3993 			 "%s: unable to close all file IO pool handles.",
3994 			 function );
3995 
3996 			result = -1;
3997 		}
3998 		if( libbfio_pool_free(
3999 		     &( internal_handle->file_io_pool ),
4000 		     error ) != 1 )
4001 		{
4002 			libcerror_error_set(
4003 			 error,
4004 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4005 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4006 			 "%s: unable to free file IO pool.",
4007 			 function );
4008 
4009 			result = -1;
4010 		}
4011 		internal_handle->file_io_pool_created_in_library = 0;
4012 	}
4013 	internal_handle->file_io_pool = NULL;
4014 
4015 	if( libewf_io_handle_clear(
4016 	     internal_handle->io_handle,
4017 	     error ) != 1 )
4018 	{
4019 		libcerror_error_set(
4020 		 error,
4021 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4022 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4023 		 "%s: unable to clear IO handle.",
4024 		 function );
4025 
4026 		result = -1;
4027 	}
4028 	if( internal_handle->chunk_data != NULL )
4029 	{
4030 		if( libewf_chunk_data_free(
4031 		     &( internal_handle->chunk_data ),
4032 		     error ) != 1 )
4033 		{
4034 			libcerror_error_set(
4035 			 error,
4036 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4037 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4038 			 "%s: unable to free chunk data.",
4039 			 function );
4040 
4041 			result = -1;
4042 		}
4043 	}
4044 	if( internal_handle->read_io_handle != NULL )
4045 	{
4046 		if( libewf_read_io_handle_free(
4047 		     &( internal_handle->read_io_handle ),
4048 		     error ) != 1 )
4049 		{
4050 			libcerror_error_set(
4051 			 error,
4052 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4053 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4054 			 "%s: unable to free read IO handle.",
4055 			 function );
4056 
4057 			result = -1;
4058 		}
4059 	}
4060 	if( internal_handle->write_io_handle != NULL )
4061 	{
4062 		if( libewf_write_io_handle_free(
4063 		     &( internal_handle->write_io_handle ),
4064 		     error ) != 1 )
4065 		{
4066 			libcerror_error_set(
4067 			 error,
4068 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4069 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4070 			 "%s: unable to free write IO handle.",
4071 			 function );
4072 
4073 			result = -1;
4074 		}
4075 	}
4076 	if( internal_handle->segment_files_list != NULL )
4077 	{
4078 		if( libmfdata_file_list_free(
4079 		     &( internal_handle->segment_files_list ),
4080 		     error ) != 1 )
4081 		{
4082 			libcerror_error_set(
4083 			 error,
4084 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4085 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4086 			 "%s: unable to free segment files list.",
4087 			 function );
4088 
4089 			result = -1;
4090 		}
4091 	}
4092 	if( internal_handle->delta_segment_files_list != NULL )
4093 	{
4094 		if( libmfdata_file_list_free(
4095 		     &( internal_handle->delta_segment_files_list ),
4096 		     error ) != 1 )
4097 		{
4098 			libcerror_error_set(
4099 			 error,
4100 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4101 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4102 			 "%s: unable to free delta segment files list.",
4103 			 function );
4104 
4105 			result = -1;
4106 		}
4107 	}
4108 	if( internal_handle->segment_files_cache != NULL )
4109 	{
4110 		if( libfcache_cache_free(
4111 		     &( internal_handle->segment_files_cache ),
4112 		     error ) != 1 )
4113 		{
4114 			libcerror_error_set(
4115 			 error,
4116 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4117 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4118 			 "%s: unable to free segment files cache.",
4119 			 function );
4120 
4121 			result = -1;
4122 		}
4123 	}
4124 	if( internal_handle->segment_table != NULL )
4125 	{
4126 		if( libewf_segment_table_free(
4127 		     &( internal_handle->segment_table ),
4128 		     error ) != 1 )
4129 		{
4130 			libcerror_error_set(
4131 			 error,
4132 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4133 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4134 			 "%s: unable to free segment table.",
4135 			 function );
4136 
4137 			result = -1;
4138 		}
4139 	}
4140 	if( internal_handle->delta_segment_table != NULL )
4141 	{
4142 		if( libewf_segment_table_free(
4143 		     &( internal_handle->delta_segment_table ),
4144 		     error ) != 1 )
4145 		{
4146 			libcerror_error_set(
4147 			 error,
4148 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4149 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4150 			 "%s: unable to free delta segment table.",
4151 			 function );
4152 
4153 			result = -1;
4154 		}
4155 	}
4156 	if( internal_handle->chunk_table_list != NULL )
4157 	{
4158 		if( libmfdata_list_free(
4159 		     &( internal_handle->chunk_table_list ),
4160 		     error ) != 1 )
4161 		{
4162 			libcerror_error_set(
4163 			 error,
4164 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4165 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4166 			 "%s: unable to free chunk table list.",
4167 			 function );
4168 
4169 			result = -1;
4170 		}
4171 	}
4172 	if( internal_handle->chunk_table_cache != NULL )
4173 	{
4174 		if( libfcache_cache_free(
4175 		     &( internal_handle->chunk_table_cache ),
4176 		     error ) != 1 )
4177 		{
4178 			libcerror_error_set(
4179 			 error,
4180 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4181 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4182 			 "%s: unable to free chunk table cache.",
4183 			 function );
4184 
4185 			result = -1;
4186 		}
4187 	}
4188 	if( internal_handle->header_sections != NULL )
4189 	{
4190 		if( libewf_header_sections_free(
4191 		     &( internal_handle->header_sections ),
4192 		     error ) != 1 )
4193 		{
4194 			libcerror_error_set(
4195 			 error,
4196 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4197 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4198 			 "%s: unable to free header sections.",
4199 			 function );
4200 
4201 			result = -1;
4202 		}
4203 	}
4204 	if( internal_handle->hash_sections != NULL )
4205 	{
4206 		if( libewf_hash_sections_free(
4207 		     &( internal_handle->hash_sections ),
4208 		     error ) != 1 )
4209 		{
4210 			libcerror_error_set(
4211 			 error,
4212 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4213 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4214 			 "%s: unable to free hash sections.",
4215 			 function );
4216 
4217 			result = -1;
4218 		}
4219 	}
4220 	if( internal_handle->header_values != NULL )
4221 	{
4222 		if( libfvalue_table_free(
4223 		     &( internal_handle->header_values ),
4224 		     error ) != 1 )
4225 		{
4226 			libcerror_error_set(
4227 			 error,
4228 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4229 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4230 			 "%s: unable to free header values.",
4231 			 function );
4232 
4233 			result = -1;
4234 		}
4235 	}
4236 	if( internal_handle->hash_values != NULL )
4237 	{
4238 		if( libfvalue_table_free(
4239 		     &( internal_handle->hash_values ),
4240 		     error ) != 1 )
4241 		{
4242 			libcerror_error_set(
4243 			 error,
4244 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4245 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4246 			 "%s: unable to free hash values.",
4247 			 function );
4248 
4249 			result = -1;
4250 		}
4251 	}
4252 	if( internal_handle->single_files != NULL )
4253 	{
4254 		if( libewf_single_files_free(
4255 		     &( internal_handle->single_files ),
4256 		     error ) != 1 )
4257 		{
4258 			libcerror_error_set(
4259 			 error,
4260 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4261 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4262 			 "%s: unable to free single files.",
4263 			 function );
4264 
4265 			result = -1;
4266 		}
4267 	}
4268 	if( internal_handle->read_io_handle != NULL )
4269 	{
4270 		if( libcdata_range_list_empty(
4271 		     internal_handle->read_io_handle->checksum_errors,
4272 		     NULL,
4273 		     error ) != 1 )
4274 		{
4275 			libcerror_error_set(
4276 			 error,
4277 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4278 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4279 			 "%s: unable to empty checksum errors range list.",
4280 			 function );
4281 
4282 			result = -1;
4283 		}
4284 	}
4285 	if( libcdata_array_empty(
4286 	     internal_handle->sessions,
4287 	     (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
4288 	     error ) != 1 )
4289 	{
4290 		libcerror_error_set(
4291 		 error,
4292 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4293 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4294 		 "%s: unable to empty sessions array.",
4295 		 function );
4296 
4297 		result = -1;
4298 	}
4299 	if( libcdata_array_empty(
4300 	     internal_handle->tracks,
4301 	     (int (*)(intptr_t **, libcerror_error_t **)) &libewf_sector_range_free,
4302 	     error ) != 1 )
4303 	{
4304 		libcerror_error_set(
4305 		 error,
4306 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4307 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4308 		 "%s: unable to empty tracks array.",
4309 		 function );
4310 
4311 		result = -1;
4312 	}
4313 	if( libcdata_range_list_empty(
4314 	     internal_handle->acquiry_errors,
4315 	     NULL,
4316 	     error ) != 1 )
4317 	{
4318 		libcerror_error_set(
4319 		 error,
4320 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4321 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4322 		 "%s: unable to empty acquiry errors range list.",
4323 		 function );
4324 
4325 		result = -1;
4326 	}
4327 	return( result );
4328 }
4329 
4330 /* Prepares chunk of (media) data after reading it according to the handle settings
4331  * It applies decompression if necessary and validates the chunk checksum
4332  * This function should be used after libewf_handle_read_chunk
4333  * The value chunk_buffer_size contains the size of the chunk
4334  * Returns the resulting chunk size or -1 on error
4335  */
libewf_handle_prepare_read_chunk(libewf_handle_t * handle,void * chunk_buffer,size_t chunk_buffer_size,void * uncompressed_chunk_buffer,size_t * uncompressed_chunk_buffer_size,int8_t is_compressed,uint32_t chunk_checksum,int8_t read_checksum,libcerror_error_t ** error)4336 ssize_t libewf_handle_prepare_read_chunk(
4337          libewf_handle_t *handle,
4338          void *chunk_buffer,
4339          size_t chunk_buffer_size,
4340          void *uncompressed_chunk_buffer,
4341          size_t *uncompressed_chunk_buffer_size,
4342          int8_t is_compressed,
4343          uint32_t chunk_checksum,
4344          int8_t read_checksum,
4345          libcerror_error_t **error )
4346 {
4347 	uint8_t *checksum_buffer     = NULL;
4348 	static char *function        = "libewf_handle_prepare_read_chunk";
4349 	uint32_t calculated_checksum = 0;
4350 
4351 	if( handle == NULL )
4352 	{
4353 		libcerror_error_set(
4354 		 error,
4355 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4356 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4357 		 "%s: invalid handle.",
4358 		 function );
4359 
4360 		return( -1 );
4361 	}
4362 	if( chunk_buffer == NULL )
4363 	{
4364 		libcerror_error_set(
4365 		 error,
4366 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4367 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4368 		 "%s: invalid chunk buffer.",
4369 		 function );
4370 
4371 		return( -1 );
4372 	}
4373 	if( ( chunk_buffer_size == 0 )
4374 	 || ( chunk_buffer_size > (size_t) SSIZE_MAX ) )
4375 	{
4376 		libcerror_error_set(
4377 		 error,
4378 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4379 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4380 		 "%s: invalid chunk buffer size value out of bounds.",
4381 		 function );
4382 
4383 		return( -1 );
4384 	}
4385 	if( uncompressed_chunk_buffer_size == NULL )
4386 	{
4387 		libcerror_error_set(
4388 		 error,
4389 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4390 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4391 		 "%s: invalid uncompressed chunk buffer size.",
4392 		 function );
4393 
4394 		return( -1 );
4395 	}
4396 	if( is_compressed == 0 )
4397 	{
4398 		if( chunk_buffer_size < sizeof( uint32_t ) )
4399 		{
4400 			libcerror_error_set(
4401 			 error,
4402 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4403 			 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4404 			 "%s: invalid chunk buffer size value out of bounds.",
4405 			 function );
4406 
4407 			return( -1 );
4408 		}
4409 		chunk_buffer_size -= sizeof( uint32_t );
4410 
4411 		if( read_checksum == 0 )
4412 		{
4413 			checksum_buffer = &( ( (uint8_t *) chunk_buffer )[ chunk_buffer_size ] );
4414 
4415 			byte_stream_copy_to_uint32_little_endian(
4416 			 checksum_buffer,
4417 			 chunk_checksum );
4418 		}
4419 		if( libewf_checksum_calculate_adler32(
4420 		     &calculated_checksum,
4421 		     chunk_buffer,
4422 		     chunk_buffer_size,
4423 		     1,
4424 		     error ) != 1 )
4425 		{
4426 			libcerror_error_set(
4427 			 error,
4428 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4429 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4430 			 "%s: unable to calculate checksum.",
4431 			 function );
4432 
4433 			return( -1 );
4434 		}
4435 		if( chunk_checksum != calculated_checksum )
4436 		{
4437 			libcerror_error_set(
4438 			 error,
4439 			 LIBCERROR_ERROR_DOMAIN_INPUT,
4440 			 LIBCERROR_INPUT_ERROR_CHECKSUM_MISMATCH,
4441 			 "%s: chunk data checksum does not match (stored: 0x%08" PRIx32 " calculated: 0x%08" PRIx32 ").",
4442 			 function,
4443 			 chunk_checksum,
4444 			 calculated_checksum );
4445 
4446 			return( -1 );
4447 		}
4448 		*uncompressed_chunk_buffer_size = chunk_buffer_size;
4449 	}
4450 	else
4451 	{
4452 		if( uncompressed_chunk_buffer == NULL )
4453 		{
4454 			libcerror_error_set(
4455 			 error,
4456 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4457 			 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4458 			 "%s: invalid uncompressed chunk buffer.",
4459 			 function );
4460 
4461 			return( -1 );
4462 		}
4463 		if( uncompressed_chunk_buffer == chunk_buffer )
4464 		{
4465 			libcerror_error_set(
4466 			 error,
4467 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4468 			 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4469 			 "%s: invalid uncompressed chunk buffer is the same as chunk buffer.",
4470 			 function );
4471 
4472 			return( -1 );
4473 		}
4474 		if( *uncompressed_chunk_buffer_size > (size_t) SSIZE_MAX )
4475 		{
4476 			libcerror_error_set(
4477 			 error,
4478 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4479 			 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4480 			 "%s: invalid uncompressed chunk buffer size value exceeds maximum.",
4481 			 function );
4482 
4483 			return( -1 );
4484 		}
4485 		if( libewf_decompress_data(
4486 		     chunk_buffer,
4487 		     chunk_buffer_size,
4488 		     uncompressed_chunk_buffer,
4489 		     uncompressed_chunk_buffer_size,
4490 		     error ) != 1 )
4491 		{
4492 			libcerror_error_set(
4493 			 error,
4494 			 LIBCERROR_ERROR_DOMAIN_COMPRESSION,
4495 			 LIBCERROR_COMPRESSION_ERROR_DECOMPRESS_FAILED,
4496 			 "%s: unable to decompress chunk buffer.",
4497 			 function );
4498 
4499 			return( -1 );
4500 		}
4501 	}
4502 	return( (ssize_t) *uncompressed_chunk_buffer_size );
4503 }
4504 
4505 /* Reads a chunk of (media) data from the current offset into a buffer
4506  * Will read until the requested size is filled or the entire chunk is read
4507  * The values read_checksum and chunk_checksum are used for uncompressed chunks only
4508  * The value chunk_checksum is set to a runtime version of the value in the checksum_buffer
4509  * The value read_checksum is set if the checksum has been read into checksum_buffer
4510  * The value chunk_buffer_size contains the size of the chunk buffer
4511  * Returns the number of bytes read or -1 on error
4512  */
libewf_handle_read_chunk(libewf_handle_t * handle,void * chunk_buffer,size_t chunk_buffer_size,int8_t * is_compressed,void * checksum_buffer,uint32_t * chunk_checksum,int8_t * read_checksum,libcerror_error_t ** error)4513 ssize_t libewf_handle_read_chunk(
4514          libewf_handle_t *handle,
4515          void *chunk_buffer,
4516          size_t chunk_buffer_size,
4517          int8_t *is_compressed,
4518          void *checksum_buffer,
4519          uint32_t *chunk_checksum,
4520          int8_t *read_checksum,
4521          libcerror_error_t **error )
4522 {
4523 	libewf_chunk_data_t *chunk_data           = NULL;
4524 	libewf_internal_handle_t *internal_handle = NULL;
4525 	uint8_t *chunk_data_buffer                = NULL;
4526 	static char *function                     = "libewf_handle_read_chunk";
4527 	size_t data_size                          = 0;
4528 	size_t read_size                          = 0;
4529 	uint64_t chunk_index                      = 0;
4530 
4531 	if( handle == NULL )
4532 	{
4533 		libcerror_error_set(
4534 		 error,
4535 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4536 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4537 		 "%s: invalid handle.",
4538 		 function );
4539 
4540 		return( -1 );
4541 	}
4542 	internal_handle = (libewf_internal_handle_t *) handle;
4543 
4544 	if( internal_handle->io_handle == NULL )
4545 	{
4546 		libcerror_error_set(
4547 		 error,
4548 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4549 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4550 		 "%s: invalid handle - missing IO handle.",
4551 		 function );
4552 
4553 		return( -1 );
4554 	}
4555 	if( internal_handle->chunk_data != NULL )
4556 	{
4557 		libcerror_error_set(
4558 		 error,
4559 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4560 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
4561 		 "%s: invalid handle - chunk data set.",
4562 		 function );
4563 
4564 		return( -1 );
4565 	}
4566 	if( internal_handle->io_handle->current_offset < 0 )
4567 	{
4568 		libcerror_error_set(
4569 		 error,
4570 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4571 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4572 		 "%s: invalid handle - invalid IO handle - current offset value out of bounds.",
4573 		 function );
4574 
4575 		return( -1 );
4576 	}
4577 	if( internal_handle->media_values == NULL )
4578 	{
4579 		libcerror_error_set(
4580 		 error,
4581 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4582 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4583 		 "%s: invalid handle - missing media values.",
4584 		 function );
4585 
4586 		return( -1 );
4587 	}
4588 	if( internal_handle->media_values->chunk_size == 0 )
4589 	{
4590 		libcerror_error_set(
4591 		 error,
4592 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4593 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4594 		 "%s: invalid handle - invalid media values - missing chunk size.",
4595 		 function );
4596 
4597 		return( -1 );
4598 	}
4599 	if( chunk_buffer == NULL )
4600 	{
4601 		libcerror_error_set(
4602 		 error,
4603 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4604 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4605 		 "%s: invalid chunk buffer.",
4606 		 function );
4607 
4608 		return( -1 );
4609 	}
4610 	if( ( chunk_buffer_size == 0 )
4611 	 || ( chunk_buffer_size > (size_t) SSIZE_MAX ) )
4612 	{
4613 		libcerror_error_set(
4614 		 error,
4615 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4616 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4617 		 "%s: invalid chunk buffer size value out of bounds.",
4618 		 function );
4619 
4620 		return( -1 );
4621 	}
4622 	if( is_compressed == NULL )
4623 	{
4624 		libcerror_error_set(
4625 		 error,
4626 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4627 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4628 		 "%s: invalid is compressed.",
4629 		 function );
4630 
4631 		return( -1 );
4632 	}
4633 	if( checksum_buffer == NULL )
4634 	{
4635 		libcerror_error_set(
4636 		 error,
4637 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4638 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4639 		 "%s: invalid checksum buffer.",
4640 		 function );
4641 
4642 		return( -1 );
4643 	}
4644 	if( chunk_checksum == NULL )
4645 	{
4646 		libcerror_error_set(
4647 		 error,
4648 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4649 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4650 		 "%s: invalid chunk checksum.",
4651 		 function );
4652 
4653 		return( -1 );
4654 	}
4655 	if( read_checksum == NULL )
4656 	{
4657 		libcerror_error_set(
4658 		 error,
4659 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4660 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4661 		 "%s: invalid read checksum.",
4662 		 function );
4663 
4664 		return( -1 );
4665 	}
4666 	if( (size64_t) internal_handle->io_handle->current_offset >= internal_handle->media_values->media_size )
4667 	{
4668 		return( 0 );
4669 	}
4670 	chunk_index = internal_handle->io_handle->current_offset / internal_handle->media_values->chunk_size;
4671 
4672 	if( chunk_index >= (uint64_t) INT_MAX )
4673 	{
4674 		libcerror_error_set(
4675 		 error,
4676 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4677 		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
4678 		 "%s: invalid chunk index value exceeds maximum.",
4679 		 function );
4680 
4681 		return( -1 );
4682 	}
4683 	/* This function will expand element groups
4684 	 */
4685 	if( libmfdata_list_get_element_value_by_index(
4686 	     internal_handle->chunk_table_list,
4687 	     internal_handle->file_io_pool,
4688 	     internal_handle->chunk_table_cache,
4689 	     (int) chunk_index,
4690 	     (intptr_t **) &chunk_data,
4691 	     0,
4692 	     error ) != 1 )
4693 	{
4694 		libcerror_error_set(
4695 		 error,
4696 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4697 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4698 		 "%s: unable to retrieve chunk data: %" PRIu64 ".",
4699 		 function,
4700 		 chunk_index );
4701 
4702 		return( -1 );
4703 	}
4704 	if( chunk_data == NULL )
4705 	{
4706 		libcerror_error_set(
4707 		 error,
4708 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4709 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4710 		 "%s: missing chunk data: %" PRIu64 ".",
4711 		 function,
4712 		 chunk_index );
4713 
4714 		return( -1 );
4715 	}
4716 	chunk_data_buffer = chunk_data->data;
4717 	read_size         = chunk_data->data_size;
4718 	*is_compressed    = chunk_data->is_compressed;
4719 	*read_checksum    = 0;
4720 
4721 	if( chunk_data->is_compressed == 0 )
4722 	{
4723 		if( chunk_data->is_packed != 0 )
4724 		{
4725 			if( ( chunk_data->data_size < sizeof( uint32_t ) )
4726 			 || ( chunk_data->data_size > (size_t) SSIZE_MAX ) )
4727 			{
4728 				libcerror_error_set(
4729 				 error,
4730 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4731 				 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4732 				 "%s: invalid chunk data size value out of bounds.",
4733 				 function );
4734 
4735 				return( -1 );
4736 			}
4737 			read_size -= sizeof( uint32_t );
4738 		}
4739 		if( chunk_buffer_size < read_size )
4740 		{
4741 			libcerror_error_set(
4742 			 error,
4743 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4744 			 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
4745 			 "%s: invalid chunk buffer size value too small.",
4746 			 function );
4747 
4748 			return( -1 );
4749 		}
4750 		/* If the chunk and checksum buffers are not aligned
4751 		 * read the chunk and checksum separately
4752 		 */
4753 	 	if( &( ( (uint8_t *) chunk_buffer )[ read_size ] ) != checksum_buffer )
4754 		{
4755 			*read_checksum = 1;
4756 		}
4757 		else
4758 		{
4759 			read_size += sizeof( uint32_t );
4760 		}
4761 	}
4762 	else if( chunk_data->is_packed == 0 )
4763 	{
4764 		chunk_data_buffer = chunk_data->compressed_data;
4765 		read_size         = chunk_data->compressed_data_size;
4766 	}
4767 	if( memory_copy(
4768 	     chunk_buffer,
4769 	     chunk_data_buffer,
4770 	     read_size ) == NULL )
4771 	{
4772 		libcerror_error_set(
4773 		 error,
4774 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
4775 		 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
4776 		 "%s: unable to copy chunk data to chunk buffer.",
4777 		 function );
4778 
4779 		return( -1 );
4780 	}
4781 	if( *read_checksum != 0 )
4782 	{
4783 		if( memory_copy(
4784 		     checksum_buffer,
4785 		     &( chunk_data_buffer[ read_size ] ),
4786 		     sizeof( uint32_t ) ) == NULL )
4787 		{
4788 			libcerror_error_set(
4789 			 error,
4790 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
4791 			 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
4792 			 "%s: unable to copy chunk checksum data in chunk buffer.",
4793 			 function );
4794 
4795 			return( -1 );
4796 		}
4797 		read_size += sizeof( uint32_t );
4798 
4799 		byte_stream_copy_to_uint32_little_endian(
4800 		 (uint8_t *) checksum_buffer,
4801 		 *chunk_checksum );
4802 	}
4803 	if( chunk_data->is_packed == 0 )
4804 	{
4805 		data_size = chunk_data->data_size;
4806 	}
4807 	else
4808 	{
4809 		data_size = (size_t) internal_handle->media_values->chunk_size;
4810 
4811 		if( (size64_t) ( internal_handle->io_handle->current_offset + data_size ) >= internal_handle->media_values->media_size )
4812 		{
4813 			data_size = (size_t) ( internal_handle->media_values->media_size - internal_handle->io_handle->current_offset );
4814 		}
4815 	}
4816 	internal_handle->io_handle->current_offset += (off64_t) data_size;
4817 
4818 	return( (ssize_t) read_size );
4819 }
4820 
4821 /* Reads (media) data at the current offset into a buffer
4822  * Returns the number of bytes read or -1 on error
4823  */
libewf_handle_read_buffer(libewf_handle_t * handle,void * buffer,size_t buffer_size,libcerror_error_t ** error)4824 ssize_t libewf_handle_read_buffer(
4825          libewf_handle_t *handle,
4826          void *buffer,
4827          size_t buffer_size,
4828          libcerror_error_t **error )
4829 {
4830 	libewf_chunk_data_t *chunk_data           = NULL;
4831 	libewf_internal_handle_t *internal_handle = NULL;
4832 	static char *function                     = "libewf_handle_read_buffer";
4833 	off64_t chunk_offset                      = 0;
4834 	size_t buffer_offset                      = 0;
4835 	size_t read_size                          = 0;
4836 	ssize_t total_read_count                  = 0;
4837 	uint64_t chunk_index                      = 0;
4838 	uint64_t chunk_data_offset                = 0;
4839 
4840 	if( handle == NULL )
4841 	{
4842 		libcerror_error_set(
4843 		 error,
4844 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4845 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4846 		 "%s: invalid handle.",
4847 		 function );
4848 
4849 		return( -1 );
4850 	}
4851 	internal_handle = (libewf_internal_handle_t *) handle;
4852 
4853 	if( internal_handle->io_handle == NULL )
4854 	{
4855 		libcerror_error_set(
4856 		 error,
4857 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4858 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4859 		 "%s: invalid handle - missing IO handle.",
4860 		 function );
4861 
4862 		return( -1 );
4863 	}
4864 	if( internal_handle->chunk_data != NULL )
4865 	{
4866 		libcerror_error_set(
4867 		 error,
4868 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4869 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
4870 		 "%s: invalid handle - chunk data set.",
4871 		 function );
4872 
4873 		return( -1 );
4874 	}
4875 	if( internal_handle->io_handle->current_offset < 0 )
4876 	{
4877 		libcerror_error_set(
4878 		 error,
4879 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4880 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4881 		 "%s: invalid handle - invalid IO handle - current offset value out of bounds.",
4882 		 function );
4883 
4884 		return( -1 );
4885 	}
4886 	if( internal_handle->media_values == NULL )
4887 	{
4888 		libcerror_error_set(
4889 		 error,
4890 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4891 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4892 		 "%s: invalid handle - missing media values.",
4893 		 function );
4894 
4895 		return( -1 );
4896 	}
4897 	if( internal_handle->media_values->chunk_size == 0 )
4898 	{
4899 		libcerror_error_set(
4900 		 error,
4901 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4902 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4903 		 "%s: invalid handle - invalid media values - missing chunk size.",
4904 		 function );
4905 
4906 		return( -1 );
4907 	}
4908 	if( buffer == NULL )
4909 	{
4910 		libcerror_error_set(
4911 		 error,
4912 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4913 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4914 		 "%s: invalid buffer.",
4915 		 function );
4916 
4917 		return( -1 );
4918 	}
4919 	if( buffer_size > (size_t) SSIZE_MAX )
4920 	{
4921 		libcerror_error_set(
4922 		 error,
4923 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4924 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
4925 		 "%s: invalid buffer size value exceeds maximum.",
4926 		 function );
4927 
4928 		return( -1 );
4929 	}
4930 	if( (size64_t) internal_handle->io_handle->current_offset >= internal_handle->media_values->media_size )
4931 	{
4932 		return( 0 );
4933 	}
4934 	if( (size64_t) ( internal_handle->io_handle->current_offset + buffer_size ) >= internal_handle->media_values->media_size )
4935 	{
4936 		buffer_size = (size_t) ( internal_handle->media_values->media_size - internal_handle->io_handle->current_offset );
4937 	}
4938 	chunk_index = internal_handle->io_handle->current_offset / internal_handle->media_values->chunk_size;
4939 
4940 	if( chunk_index >= (uint64_t) INT_MAX )
4941 	{
4942 		libcerror_error_set(
4943 		 error,
4944 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4945 		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
4946 		 "%s: invalid chunk index value exceeds maximum.",
4947 		 function );
4948 
4949 		return( -1 );
4950 	}
4951 	chunk_offset = chunk_index * internal_handle->media_values->chunk_size;
4952 
4953 	chunk_data_offset = internal_handle->io_handle->current_offset - chunk_offset;
4954 
4955 	if( chunk_data_offset >= (uint64_t) SSIZE_MAX )
4956 	{
4957 		libcerror_error_set(
4958 		 error,
4959 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4960 		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
4961 		 "%s: invalid chunk data offset value exceeds maximum.",
4962 		 function );
4963 
4964 		return( -1 );
4965 	}
4966 	internal_handle->io_handle->abort = 0;
4967 
4968 	while( buffer_size > 0 )
4969 	{
4970 		if( libewf_read_io_handle_read_chunk_data(
4971 		     internal_handle->read_io_handle,
4972 		     internal_handle->file_io_pool,
4973 		     internal_handle->media_values,
4974 		     internal_handle->chunk_table_list,
4975 		     internal_handle->chunk_table_cache,
4976 		     (int) chunk_index,
4977 		     chunk_offset,
4978 		     &chunk_data,
4979 		     error ) != 1 )
4980 		{
4981 			libcerror_error_set(
4982 			 error,
4983 			 LIBCERROR_ERROR_DOMAIN_IO,
4984 			 LIBCERROR_IO_ERROR_READ_FAILED,
4985 			 "%s: unable to read chunk data: %" PRIu64 ".",
4986 			 function,
4987 			 chunk_index );
4988 
4989 			return( -1 );
4990 		}
4991 		if( chunk_data == NULL )
4992 		{
4993 			libcerror_error_set(
4994 			 error,
4995 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
4996 			 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4997 			 "%s: missing chunk data: %" PRIu64 ".",
4998 			 function,
4999 			 chunk_index );
5000 
5001 			return( -1 );
5002 		}
5003 		if( chunk_data_offset > chunk_data->data_size )
5004 		{
5005 			libcerror_error_set(
5006 			 error,
5007 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5008 			 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5009 			 "%s: chunk offset exceeds chunk data size.",
5010 			 function );
5011 
5012 			return( -1 );
5013 		}
5014 		read_size = (size_t) ( chunk_data->data_size - chunk_data_offset );
5015 
5016 		if( read_size > buffer_size )
5017 		{
5018 			read_size = buffer_size;
5019 		}
5020 		if( read_size == 0 )
5021 		{
5022 			break;
5023 		}
5024 		if( memory_copy(
5025 		     &( ( (uint8_t *) buffer )[ buffer_offset ] ),
5026 		     &( ( chunk_data->data )[ chunk_data_offset ] ),
5027 		     read_size ) == NULL )
5028 		{
5029 			libcerror_error_set(
5030 			 error,
5031 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
5032 			 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
5033 			 "%s: unable to copy chunk data to buffer.",
5034 			 function );
5035 
5036 			return( -1 );
5037 		}
5038 		buffer_offset    += read_size;
5039 		buffer_size      -= read_size;
5040 		total_read_count += (ssize_t) read_size;
5041 		chunk_index      += 1;
5042 		chunk_offset     += internal_handle->media_values->chunk_size;
5043 		chunk_data_offset = 0;
5044 
5045 		internal_handle->io_handle->current_offset += (off64_t) read_size;
5046 
5047 		if( (size64_t) internal_handle->io_handle->current_offset >= internal_handle->media_values->media_size )
5048 		{
5049 			break;
5050 		}
5051 		if( internal_handle->io_handle->abort != 0 )
5052 		{
5053 			break;
5054 		}
5055 	}
5056 	return( total_read_count );
5057 }
5058 
5059 /* Reads (media) data at a specific offset
5060  * Returns the number of bytes read or -1 on error
5061  */
libewf_handle_read_random(libewf_handle_t * handle,void * buffer,size_t buffer_size,off64_t offset,libcerror_error_t ** error)5062 ssize_t libewf_handle_read_random(
5063          libewf_handle_t *handle,
5064          void *buffer,
5065          size_t buffer_size,
5066          off64_t offset,
5067          libcerror_error_t **error )
5068 {
5069 	static char *function = "libewf_handle_read_random";
5070 	ssize_t read_count    = 0;
5071 
5072 	if( libewf_handle_seek_offset(
5073 	     handle,
5074 	     offset,
5075 	     SEEK_SET,
5076 	     error ) == -1 )
5077 	{
5078 		libcerror_error_set(
5079 		 error,
5080 		 LIBCERROR_ERROR_DOMAIN_IO,
5081 		 LIBCERROR_IO_ERROR_SEEK_FAILED,
5082 		 "%s: unable to seek offset.",
5083 		 function );
5084 
5085 		return( -1 );
5086 	}
5087 	read_count = libewf_handle_read_buffer(
5088 	              handle,
5089 	              buffer,
5090 	              buffer_size,
5091 	              error );
5092 
5093 	if( read_count < 0 )
5094 	{
5095 		libcerror_error_set(
5096 		 error,
5097 		 LIBCERROR_ERROR_DOMAIN_IO,
5098 		 LIBCERROR_IO_ERROR_READ_FAILED,
5099 		 "%s: unable to read buffer.",
5100 		 function );
5101 
5102 		return( -1 );
5103 	}
5104 	return( read_count );
5105 }
5106 
5107 /* Prepares a chunk of (media) data before writing according to the handle settings
5108  * This function should be used before libewf_handle_write_chunk
5109  * The chunk_buffer_size should contain the actual chunk size
5110  * The function sets the chunk checksum, is compressed and write checksum values
5111  * Returns the resulting chunk size or -1 on error
5112  */
libewf_handle_prepare_write_chunk(libewf_handle_t * handle,void * chunk_buffer,size_t chunk_buffer_size,void * compressed_chunk_buffer,size_t * compressed_chunk_buffer_size,int8_t * is_compressed,uint32_t * chunk_checksum,int8_t * write_checksum,libcerror_error_t ** error)5113 ssize_t libewf_handle_prepare_write_chunk(
5114          libewf_handle_t *handle,
5115          void *chunk_buffer,
5116          size_t chunk_buffer_size,
5117          void *compressed_chunk_buffer,
5118          size_t *compressed_chunk_buffer_size,
5119          int8_t *is_compressed,
5120          uint32_t *chunk_checksum,
5121          int8_t *write_checksum,
5122          libcerror_error_t **error )
5123 {
5124 	libewf_internal_handle_t *internal_handle = NULL;
5125 	static char *function                     = "libewf_handle_prepare_write_chunk";
5126 	size_t chunk_write_size                   = 0;
5127 	uint64_t chunk_index                      = 0;
5128 	int8_t compression_level                  = 0;
5129 	int chunk_exists                          = 0;
5130 	int is_empty_zero_block                   = 0;
5131 	int result                                = 0;
5132 
5133 	if( handle == NULL )
5134 	{
5135 		libcerror_error_set(
5136 		 error,
5137 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5138 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5139 		 "%s: invalid handle.",
5140 		 function );
5141 
5142 		return( -1 );
5143 	}
5144 	internal_handle = (libewf_internal_handle_t *) handle;
5145 
5146 	if( internal_handle->io_handle == NULL )
5147 	{
5148 		libcerror_error_set(
5149 		 error,
5150 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5151 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5152 		 "%s: invalid handle - missing IO handle.",
5153 		 function );
5154 
5155 		return( -1 );
5156 	}
5157 	if( internal_handle->io_handle->current_offset < 0 )
5158 	{
5159 		libcerror_error_set(
5160 		 error,
5161 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5162 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5163 		 "%s: invalid handle - invalid IO handle - current offset value out of bounds.",
5164 		 function );
5165 
5166 		return( -1 );
5167 	}
5168 	if( internal_handle->media_values == NULL )
5169 	{
5170 		libcerror_error_set(
5171 		 error,
5172 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5173 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5174 		 "%s: invalid handle - missing media values.",
5175 		 function );
5176 
5177 		return( -1 );
5178 	}
5179 	if( internal_handle->media_values->chunk_size == 0 )
5180 	{
5181 		libcerror_error_set(
5182 		 error,
5183 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5184 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5185 		 "%s: invalid handle - invalid media values - missing chunk size.",
5186 		 function );
5187 
5188 		return( -1 );
5189 	}
5190 	if( chunk_buffer == NULL )
5191 	{
5192 		libcerror_error_set(
5193 		 error,
5194 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5195 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5196 		 "%s: invalid chunk buffer.",
5197 		 function );
5198 
5199 		return( -1 );
5200 	}
5201 	if( chunk_buffer_size > (size_t) SSIZE_MAX )
5202 	{
5203 		libcerror_error_set(
5204 		 error,
5205 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5206 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
5207 		 "%s: invalid chunk buffer size value exceeds maximum.",
5208 		 function );
5209 
5210 		return( -1 );
5211 	}
5212 	if( chunk_buffer_size > (size_t) internal_handle->media_values->chunk_size )
5213 	{
5214 		libcerror_error_set(
5215 		 error,
5216 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5217 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_LARGE,
5218 		 "%s: invalid chunk buffer size: %" PRIzd " value exceeds media values chunk size: %" PRIu32 ".",
5219 		 function,
5220 		 chunk_buffer_size,
5221 		 internal_handle->media_values->chunk_size );
5222 
5223 		return( -1 );
5224 	}
5225 	if( chunk_checksum == NULL )
5226 	{
5227 		libcerror_error_set(
5228 		 error,
5229 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5230 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5231 		 "%s: invalid chunk checksum.",
5232 		 function );
5233 
5234 		return( -1 );
5235 	}
5236 	if( is_compressed == NULL )
5237 	{
5238 		libcerror_error_set(
5239 		 error,
5240 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5241 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5242 		 "%s: invalid is compressed.",
5243 		 function );
5244 
5245 		return( -1 );
5246 	}
5247 	if( write_checksum == NULL )
5248 	{
5249 		libcerror_error_set(
5250 		 error,
5251 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5252 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5253 		 "%s: invalid write checksum.",
5254 		 function );
5255 
5256 		return( -1 );
5257 	}
5258 	if( chunk_buffer_size == 0 )
5259 	{
5260 		return( 0 );
5261 	}
5262 	if( internal_handle->read_io_handle != NULL )
5263 	{
5264 		chunk_index = internal_handle->io_handle->current_offset / internal_handle->media_values->chunk_size;
5265 
5266 		if( chunk_index >= (uint64_t) INT_MAX )
5267 		{
5268 			libcerror_error_set(
5269 			 error,
5270 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5271 			 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
5272 			 "%s: invalid chunk index value exceeds maximum.",
5273 			 function );
5274 
5275 			return( -1 );
5276 		}
5277 		chunk_exists = libmfdata_list_is_set(
5278 		                internal_handle->chunk_table_list,
5279 		                (int) chunk_index,
5280 		                error );
5281 
5282 		if( chunk_exists == -1 )
5283 		{
5284 			libcerror_error_set(
5285 			 error,
5286 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5287 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5288 			 "%s: unable to determine if the chunk: %" PRIu64 " exists in the chunk table list.",
5289 			 function,
5290 			 chunk_index );
5291 
5292 			return( -1 );
5293 		}
5294 		else if( chunk_exists == 0 )
5295 		{
5296 			if( ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
5297 			 && ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_RESUME ) == 0 ) )
5298 			{
5299 				libcerror_error_set(
5300 				 error,
5301 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5302 				 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5303 				 "%s: missing chunk: %" PRIu64 ".",
5304 				 function,
5305 				 chunk_index );
5306 
5307 				return( -1 );
5308 			}
5309 		}
5310 	}
5311 	*is_compressed = 0;
5312 
5313 	if( chunk_exists == 0 )
5314 	{
5315 		compression_level = internal_handle->io_handle->compression_level;
5316 
5317 		/* Skip the empty block check only if the compression is none and
5318 		 * the empty block compression flag is not set.
5319 		 */
5320 		if( ( compression_level != EWF_COMPRESSION_NONE )
5321 		 || ( ( internal_handle->io_handle->compression_flags & LIBEWF_FLAG_COMPRESS_EMPTY_BLOCK ) != 0 ) )
5322 		{
5323 			result = libewf_empty_block_test(
5324 				  chunk_buffer,
5325 				  chunk_buffer_size,
5326 				  error );
5327 
5328 			if( result == -1 )
5329 			{
5330 				libcerror_error_set(
5331 				 error,
5332 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5333 				 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5334 				 "%s: unable to determine if chunk buffer is empty.",
5335 				 function );
5336 
5337 				return( -1 );
5338 			}
5339 			else if( result == 1 )
5340 			{
5341 				if( ( (uint8_t *) chunk_buffer )[ 0 ] == 0 )
5342 				{
5343 					is_empty_zero_block = 1;
5344 				}
5345 				else if( compression_level == EWF_COMPRESSION_NONE )
5346 				{
5347 					compression_level = EWF_COMPRESSION_DEFAULT;
5348 				}
5349 			}
5350 		}
5351 		if( ( internal_handle->io_handle->ewf_format == EWF_FORMAT_S01 )
5352 		 || ( compression_level != EWF_COMPRESSION_NONE )
5353 		 || ( is_empty_zero_block != 0 ) )
5354 		{
5355 			if( compressed_chunk_buffer == NULL )
5356 			{
5357 				libcerror_error_set(
5358 				 error,
5359 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5360 				 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5361 				 "%s: invalid compressed chunk buffer.",
5362 				 function );
5363 
5364 				return( -1 );
5365 			}
5366 			if( compressed_chunk_buffer == chunk_buffer )
5367 			{
5368 				libcerror_error_set(
5369 				 error,
5370 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5371 				 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5372 				 "%s: invalid compressed chunk buffer is the same as chunk buffer.",
5373 				 function );
5374 
5375 				return( -1 );
5376 			}
5377 			if( compressed_chunk_buffer_size == NULL )
5378 			{
5379 				libcerror_error_set(
5380 				 error,
5381 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5382 				 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5383 				 "%s: invalid compressed chunk buffer size.",
5384 				 function );
5385 
5386 				return( -1 );
5387 			}
5388 			/* The compressed data size contains the maximum allowed buffer size on entry
5389 			 */
5390 			if( *compressed_chunk_buffer_size > (size_t) SSIZE_MAX )
5391 			{
5392 				libcerror_error_set(
5393 				 error,
5394 				 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5395 				 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
5396 				 "%s: invalid compressed chunk buffer size value exceeds maximum.",
5397 				 function );
5398 
5399 				return( -1 );
5400 			}
5401 			/* Use the cached version of the zero byte empty block data if available
5402 			 */
5403 			if( ( is_empty_zero_block != 0 )
5404 			 && ( (size_t) internal_handle->media_values->chunk_size == chunk_buffer_size )
5405 			 && ( internal_handle->write_io_handle->compressed_zero_byte_empty_block != NULL ) )
5406 			{
5407 				if( memory_copy(
5408 				     compressed_chunk_buffer,
5409 				     internal_handle->write_io_handle->compressed_zero_byte_empty_block,
5410 				     internal_handle->write_io_handle->compressed_zero_byte_empty_block_size ) == NULL )
5411 				{
5412 					libcerror_error_set(
5413 					 error,
5414 					 LIBCERROR_ERROR_DOMAIN_MEMORY,
5415 					 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
5416 					 "%s: unable to copy compressed zero byte empty block to compressed chunk buffer.",
5417 					 function );
5418 
5419 					return( -1 );
5420 				}
5421 				*compressed_chunk_buffer_size = internal_handle->write_io_handle->compressed_zero_byte_empty_block_size;
5422 			}
5423 			else
5424 			{
5425 				result = libewf_compress_data(
5426 					  (uint8_t *) compressed_chunk_buffer,
5427 					  compressed_chunk_buffer_size,
5428 					  compression_level,
5429 					  (uint8_t *) chunk_buffer,
5430 					  chunk_buffer_size,
5431 					  error );
5432 
5433 				if( result != 1 )
5434 				{
5435 					libcerror_error_set(
5436 					 error,
5437 					 LIBCERROR_ERROR_DOMAIN_COMPRESSION,
5438 					 LIBCERROR_COMPRESSION_ERROR_COMPRESS_FAILED,
5439 					 "%s: unable to compress chunk.",
5440 					 function );
5441 
5442 					return( -1 );
5443 				}
5444 			}
5445 			if( ( internal_handle->io_handle->ewf_format == EWF_FORMAT_S01 )
5446 			 || ( *compressed_chunk_buffer_size < chunk_buffer_size ) )
5447 			{
5448 				*is_compressed = 1;
5449 			}
5450 		}
5451 	}
5452 	if( *is_compressed == 0 )
5453 	{
5454 		if( libewf_checksum_calculate_adler32(
5455 		     chunk_checksum,
5456 		     chunk_buffer,
5457 		     chunk_buffer_size,
5458 		     1,
5459 		     error ) != 1 )
5460 		{
5461 			libcerror_error_set(
5462 			 error,
5463 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5464 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5465 			 "%s: unable to calculate checksum.",
5466 			 function );
5467 
5468 			return( -1 );
5469 		}
5470 		chunk_write_size = chunk_buffer_size;
5471 
5472 		*write_checksum = 1;
5473 	}
5474 	else
5475 	{
5476 		/* Zlib creates its own checksum
5477 		 */
5478 		if( memory_copy(
5479 		     chunk_checksum,
5480 		     &( ( (uint8_t *) compressed_chunk_buffer )[ *compressed_chunk_buffer_size - sizeof( uint32_t ) ] ),
5481 		     sizeof( uint32_t ) ) == NULL )
5482 		{
5483 			libcerror_error_set(
5484 			 error,
5485 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
5486 			 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
5487 			 "%s: unable to set checksum.",
5488 			 function );
5489 
5490 			return( -1 );
5491 		}
5492 		chunk_write_size = *compressed_chunk_buffer_size;
5493 
5494 		*write_checksum = 0;
5495 	}
5496 	return( (ssize_t) chunk_write_size );
5497 }
5498 
5499 /* Writes a chunk of (media) data in EWF format at the current offset
5500  * the necessary settings of the write values must have been made
5501  * chunk_buffer_size contains the size of the data within the buffer while
5502  * data_size contains the size of the actual input data
5503  * Will initialize write if necessary
5504  * Returns the number of input bytes written, 0 when no longer bytes can be written or -1 on error
5505  */
libewf_handle_write_chunk(libewf_handle_t * handle,const void * chunk_buffer,size_t chunk_buffer_size,size_t data_size,int8_t is_compressed,void * checksum_buffer,uint32_t chunk_checksum,int8_t write_checksum,libcerror_error_t ** error)5506 ssize_t libewf_handle_write_chunk(
5507          libewf_handle_t *handle,
5508          const void *chunk_buffer,
5509          size_t chunk_buffer_size,
5510          size_t data_size,
5511          int8_t is_compressed,
5512          void *checksum_buffer,
5513          uint32_t chunk_checksum,
5514          int8_t write_checksum,
5515          libcerror_error_t **error )
5516 {
5517 	libewf_internal_handle_t *internal_handle = NULL;
5518 	static char *function                     = "libewf_handle_write_chunk";
5519 	ssize_t write_count                       = 0;
5520 	uint64_t chunk_index                      = 0;
5521 	int chunk_exists                          = 0;
5522 
5523 #if defined( HAVE_DEBUG_OUTPUT )
5524 	int number_of_chunks                      = 0;
5525 #endif
5526 
5527 	if( handle == NULL )
5528 	{
5529 		libcerror_error_set(
5530 		 error,
5531 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5532 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5533 		 "%s: invalid handle.",
5534 		 function );
5535 
5536 		return( -1 );
5537 	}
5538 	internal_handle = (libewf_internal_handle_t *) handle;
5539 
5540 	if( internal_handle->io_handle == NULL )
5541 	{
5542 		libcerror_error_set(
5543 		 error,
5544 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5545 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5546 		 "%s: invalid handle - missing IO handle.",
5547 		 function );
5548 
5549 		return( -1 );
5550 	}
5551 	if( internal_handle->chunk_data != NULL )
5552 	{
5553 		libcerror_error_set(
5554 		 error,
5555 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5556 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
5557 		 "%s: invalid handle - chunk data set.",
5558 		 function );
5559 
5560 		return( -1 );
5561 	}
5562 	if( internal_handle->io_handle->current_offset < 0 )
5563 	{
5564 		libcerror_error_set(
5565 		 error,
5566 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5567 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5568 		 "%s: invalid handle - invalid IO handle - current offset value out of bounds.",
5569 		 function );
5570 
5571 		return( -1 );
5572 	}
5573 	if( internal_handle->media_values == NULL )
5574 	{
5575 		libcerror_error_set(
5576 		 error,
5577 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5578 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5579 		 "%s: invalid handle - missing media values.",
5580 		 function );
5581 
5582 		return( -1 );
5583 	}
5584 	if( internal_handle->media_values->chunk_size == 0 )
5585 	{
5586 		libcerror_error_set(
5587 		 error,
5588 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5589 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5590 		 "%s: invalid handle - invalid media values - missing chunk size.",
5591 		 function );
5592 
5593 		return( -1 );
5594 	}
5595 	if( internal_handle->write_io_handle == NULL )
5596 	{
5597 		libcerror_error_set(
5598 		 error,
5599 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5600 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5601 		 "%s: invalid handle - missing subhandle write.",
5602 		 function );
5603 
5604 		return( -1 );
5605 	}
5606 	if( internal_handle->write_io_handle->values_initialized == 0 )
5607 	{
5608 		if( libewf_write_io_handle_initialize_values(
5609 		     internal_handle->write_io_handle,
5610 		     internal_handle->io_handle,
5611 		     internal_handle->media_values,
5612 		     internal_handle->segment_table,
5613 		     error ) != 1 )
5614 		{
5615 			libcerror_error_set(
5616 			 error,
5617 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5618 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5619 			 "%s: unable to initialize write IO handle values.",
5620 			 function );
5621 
5622 			return( -1 );
5623 		}
5624 	}
5625 	if( chunk_buffer == NULL )
5626 	{
5627 		libcerror_error_set(
5628 		 error,
5629 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5630 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5631 		 "%s: invalid chunk buffer.",
5632 		 function );
5633 
5634 		return( -1 );
5635 	}
5636 	if( data_size > internal_handle->media_values->chunk_size )
5637 	{
5638 		libcerror_error_set(
5639 		 error,
5640 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5641 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5642 		 "%s: data size cannot be larger than maximum chunk size.",
5643 		 function );
5644 
5645 		return( -1 );
5646 	}
5647 	if( ( internal_handle->media_values->media_size != 0 )
5648 	 && ( (size64_t) internal_handle->io_handle->current_offset >= internal_handle->media_values->media_size ) )
5649 	{
5650 		return( 0 );
5651 	}
5652 	if( chunk_buffer_size == 0 )
5653 	{
5654 		return( 0 );
5655 	}
5656 	chunk_index = internal_handle->io_handle->current_offset / internal_handle->media_values->chunk_size;
5657 
5658 	if( chunk_index >= (uint64_t) INT_MAX )
5659 	{
5660 		libcerror_error_set(
5661 		 error,
5662 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5663 		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
5664 		 "%s: invalid chunk index value exceeds maximum.",
5665 		 function );
5666 
5667 		return( -1 );
5668 	}
5669 	if( ( internal_handle->media_values->media_size != 0 )
5670 	 && ( (size64_t) ( internal_handle->io_handle->current_offset + data_size ) >= internal_handle->media_values->media_size ) )
5671 	{
5672 		data_size = (size_t) ( internal_handle->media_values->media_size - internal_handle->io_handle->current_offset );
5673 	}
5674 #if defined( HAVE_DEBUG_OUTPUT )
5675 	if( libcnotify_verbose != 0 )
5676 	{
5677 		if( libmfdata_list_get_number_of_elements(
5678 		     internal_handle->chunk_table_list,
5679 		     &number_of_chunks,
5680 		     error ) != 1 )
5681 		{
5682 			libcerror_error_set(
5683 			 error,
5684 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5685 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5686 			 "%s: unable to retrieve the number of chunks in the chunk table list.",
5687 			 function );
5688 
5689 			return( -1 );
5690 		}
5691 		libcnotify_printf(
5692 		 "%s: writing chunk: %" PRIu64 " of total: %d.\n",
5693 		 function,
5694 		 chunk_index,
5695 		 number_of_chunks );
5696 
5697 		libcnotify_printf(
5698 		 "%s: writing chunk buffer of size: %" PRIzd " with data of size: %" PRIzd ".\n",
5699 		 function,
5700 		 chunk_buffer_size,
5701 		 data_size );
5702 	}
5703 #endif
5704 	if( ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
5705 	 && ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_RESUME ) == 0 ) )
5706 	{
5707 		chunk_exists = libmfdata_list_is_set(
5708 		                internal_handle->chunk_table_list,
5709 		                (int) chunk_index,
5710 		                error );
5711 
5712 		if( chunk_exists == -1 )
5713 		{
5714 			libcerror_error_set(
5715 			 error,
5716 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5717 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5718 			 "%s: unable to determine if the chunk: %" PRIu64 " exists in the chunk table list.",
5719 			 function,
5720 			 chunk_index );
5721 
5722 			return( -1 );
5723 		}
5724 		else if( chunk_exists == 0 )
5725 		{
5726 			libcerror_error_set(
5727 			 error,
5728 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5729 			 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5730 			 "%s: missing chunk: %" PRIu64 ".",
5731 			 function,
5732 			 chunk_index );
5733 
5734 			return( -1 );
5735 		}
5736 		write_count = libewf_write_io_handle_write_existing_chunk(
5737 		               internal_handle->write_io_handle,
5738 		               internal_handle->io_handle,
5739 		               internal_handle->file_io_pool,
5740 		               internal_handle->media_values,
5741 		               internal_handle->delta_segment_files_list,
5742 		               internal_handle->segment_files_cache,
5743 		               internal_handle->delta_segment_table,
5744 		               internal_handle->chunk_table_list,
5745 		               internal_handle->header_sections,
5746 		               (int) chunk_index,
5747 		               (uint8_t *) chunk_buffer,
5748 		               chunk_buffer_size,
5749 		               data_size,
5750 		               is_compressed,
5751 		               (uint8_t *) checksum_buffer,
5752 		               chunk_checksum,
5753 		               write_checksum,
5754 		               error );
5755 	}
5756 	else
5757 	{
5758 		write_count = libewf_write_io_handle_write_new_chunk(
5759 		               internal_handle->write_io_handle,
5760 		               internal_handle->io_handle,
5761 		               internal_handle->file_io_pool,
5762 		               internal_handle->media_values,
5763 		               internal_handle->segment_files_list,
5764 		               internal_handle->segment_files_cache,
5765 		               internal_handle->segment_table,
5766 		               internal_handle->chunk_table_list,
5767 		               internal_handle->header_values,
5768 		               internal_handle->hash_values,
5769 		               internal_handle->header_sections,
5770 		               internal_handle->hash_sections,
5771 		               internal_handle->sessions,
5772 		               internal_handle->tracks,
5773 		               internal_handle->acquiry_errors,
5774 		               (int) chunk_index,
5775 		               (uint8_t *) chunk_buffer,
5776 		               chunk_buffer_size,
5777 		               data_size,
5778 		               is_compressed,
5779 		               (uint8_t *) checksum_buffer,
5780 		               chunk_checksum,
5781 		               write_checksum,
5782 		               error );
5783 	}
5784 	if( write_count < 0 )
5785 	{
5786 		libcerror_error_set(
5787 		 error,
5788 		 LIBCERROR_ERROR_DOMAIN_IO,
5789 		 LIBCERROR_IO_ERROR_WRITE_FAILED,
5790 		 "%s: unable to write raw chunk data.",
5791 		 function );
5792 
5793 		return( -1 );
5794 	}
5795 	internal_handle->io_handle->current_offset += (off64_t) data_size;
5796 
5797 	return( (ssize_t) chunk_buffer_size );
5798 }
5799 
5800 /* Writes (media) data at the current offset
5801  * the necessary settings of the write values must have been made
5802  * Will initialize write if necessary
5803  * Returns the number of input bytes written, 0 when no longer bytes can be written or -1 on error
5804  */
libewf_handle_write_buffer(libewf_handle_t * handle,const void * buffer,size_t buffer_size,libcerror_error_t ** error)5805 ssize_t libewf_handle_write_buffer(
5806          libewf_handle_t *handle,
5807          const void *buffer,
5808          size_t buffer_size,
5809          libcerror_error_t **error )
5810 {
5811 	libewf_chunk_data_t *chunk_data           = NULL;
5812 	libewf_internal_handle_t *internal_handle = NULL;
5813 	static char *function                     = "libewf_handle_write_buffer";
5814 	off64_t chunk_offset                      = 0;
5815 	size_t buffer_offset                      = 0;
5816 	size_t chunk_data_size                    = 0;
5817 	size_t write_size                         = 0;
5818 	ssize_t write_count                       = 0;
5819 	uint64_t chunk_index                      = 0;
5820 	uint64_t chunk_data_offset                = 0;
5821 	int chunk_exists                          = 0;
5822 	int write_chunk                           = 0;
5823 
5824 	if( handle == NULL )
5825 	{
5826 		libcerror_error_set(
5827 		 error,
5828 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5829 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5830 		 "%s: invalid handle.",
5831 		 function );
5832 
5833 		return( -1 );
5834 	}
5835 	internal_handle = (libewf_internal_handle_t *) handle;
5836 
5837 	if( internal_handle->io_handle == NULL )
5838 	{
5839 		libcerror_error_set(
5840 		 error,
5841 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5842 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5843 		 "%s: invalid handle - missing IO handle.",
5844 		 function );
5845 
5846 		return( -1 );
5847 	}
5848 	if( internal_handle->io_handle->current_offset < 0 )
5849 	{
5850 		libcerror_error_set(
5851 		 error,
5852 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5853 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5854 		 "%s: invalid handle - invalid IO handle - current offset value out of bounds.",
5855 		 function );
5856 
5857 		return( -1 );
5858 	}
5859 	if( ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
5860 	 && ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_RESUME ) == 0 ) )
5861 	{
5862 		if( internal_handle->chunk_data != NULL )
5863 		{
5864 			libcerror_error_set(
5865 			 error,
5866 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5867 			 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
5868 			 "%s: invalid handle - chunk data set.",
5869 			 function );
5870 
5871 			return( -1 );
5872 		}
5873 	}
5874 	if( internal_handle->media_values == NULL )
5875 	{
5876 		libcerror_error_set(
5877 		 error,
5878 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5879 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5880 		 "%s: invalid handle - missing media values.",
5881 		 function );
5882 
5883 		return( -1 );
5884 	}
5885 	if( internal_handle->media_values->chunk_size == 0 )
5886 	{
5887 		libcerror_error_set(
5888 		 error,
5889 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5890 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5891 		 "%s: invalid handle - invalid media values - missing chunk size.",
5892 		 function );
5893 
5894 		return( -1 );
5895 	}
5896 	if( internal_handle->write_io_handle == NULL )
5897 	{
5898 		libcerror_error_set(
5899 		 error,
5900 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5901 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5902 		 "%s: invalid handle - missing subhandle write.",
5903 		 function );
5904 
5905 		return( -1 );
5906 	}
5907 	if( internal_handle->write_io_handle->values_initialized == 0 )
5908 	{
5909 		if( libewf_write_io_handle_initialize_values(
5910 		     internal_handle->write_io_handle,
5911 		     internal_handle->io_handle,
5912 		     internal_handle->media_values,
5913 		     internal_handle->segment_table,
5914 		     error ) != 1 )
5915 		{
5916 			libcerror_error_set(
5917 			 error,
5918 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5919 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5920 			 "%s: unable to initialize write IO handle values.",
5921 			 function );
5922 
5923 			return( -1 );
5924 		}
5925 	}
5926 	if( buffer == NULL )
5927 	{
5928 		libcerror_error_set(
5929 		 error,
5930 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5931 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5932 		 "%s: invalid buffer.",
5933 		 function );
5934 
5935 		return( -1 );
5936 	}
5937 	if( buffer_size > (size_t) SSIZE_MAX )
5938 	{
5939 		libcerror_error_set(
5940 		 error,
5941 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5942 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
5943 		 "%s: invalid buffer size value exceeds maximum.",
5944 		 function );
5945 
5946 		return( -1 );
5947 	}
5948 	if( internal_handle->io_handle->current_offset < 0 )
5949 	{
5950 		libcerror_error_set(
5951 		 error,
5952 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5953 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5954 		 "%s: invalid offset value out of bounds.",
5955 		 function );
5956 
5957 		return( -1 );
5958 	}
5959 	if( ( internal_handle->media_values->media_size != 0 )
5960 	 && ( (size64_t) internal_handle->io_handle->current_offset >= internal_handle->media_values->media_size ) )
5961 	{
5962 		return( 0 );
5963 	}
5964 	if( ( internal_handle->media_values->media_size != 0 )
5965 	 && ( (size64_t) ( internal_handle->io_handle->current_offset + buffer_size ) >= internal_handle->media_values->media_size ) )
5966 	{
5967 		buffer_size = (size_t) ( internal_handle->media_values->media_size - internal_handle->io_handle->current_offset );
5968 	}
5969 	chunk_index = internal_handle->io_handle->current_offset / internal_handle->media_values->chunk_size;
5970 
5971 	if( chunk_index >= (uint64_t) INT_MAX )
5972 	{
5973 		libcerror_error_set(
5974 		 error,
5975 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5976 		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
5977 		 "%s: invalid chunk index value exceeds maximum.",
5978 		 function );
5979 
5980 		return( -1 );
5981 	}
5982 	chunk_offset = chunk_index * internal_handle->media_values->chunk_size;
5983 
5984 	chunk_data_offset = internal_handle->io_handle->current_offset - chunk_offset;
5985 
5986 	if( chunk_data_offset >= (uint64_t) SSIZE_MAX )
5987 	{
5988 		libcerror_error_set(
5989 		 error,
5990 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
5991 		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
5992 		 "%s: invalid chunk data offset value exceeds maximum.",
5993 		 function );
5994 
5995 		return( -1 );
5996 	}
5997 	internal_handle->io_handle->abort = 0;
5998 
5999 	while( buffer_size > 0 )
6000 	{
6001 		chunk_exists = libmfdata_list_is_set(
6002 				internal_handle->chunk_table_list,
6003 				(int) chunk_index,
6004 				error );
6005 
6006 		if( chunk_exists == -1 )
6007 		{
6008 			libcerror_error_set(
6009 			 error,
6010 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6011 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6012 			 "%s: unable to determine if the chunk: %" PRIu64 " exists in the chunk table list.",
6013 			 function,
6014 			 chunk_index );
6015 
6016 			return( -1 );
6017 		}
6018 		if( ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
6019 		 && ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_RESUME ) == 0 ) )
6020 		{
6021 			if( chunk_exists == 0 )
6022 			{
6023 				libcerror_error_set(
6024 				 error,
6025 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6026 				 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6027 				 "%s: missing chunk: %" PRIu64 ".",
6028 				 function,
6029 				 chunk_index );
6030 
6031 				return( -1 );
6032 			}
6033 			if( ( chunk_data_offset != 0 )
6034 			 || ( buffer_size < internal_handle->media_values->chunk_size ) )
6035 			{
6036 				if( libewf_read_io_handle_read_chunk_data(
6037 				     internal_handle->read_io_handle,
6038 				     internal_handle->file_io_pool,
6039 				     internal_handle->media_values,
6040 				     internal_handle->chunk_table_list,
6041 				     internal_handle->chunk_table_cache,
6042 				     (int) chunk_index,
6043 				     chunk_offset,
6044 				     &chunk_data,
6045 				     error ) != 1 )
6046 				{
6047 					libcerror_error_set(
6048 					 error,
6049 					 LIBCERROR_ERROR_DOMAIN_IO,
6050 					 LIBCERROR_IO_ERROR_READ_FAILED,
6051 					 "%s: unable to read chunk data: %" PRIu64 ".",
6052 					 function,
6053 					 chunk_index );
6054 
6055 					return( -1 );
6056 				}
6057 				if( chunk_data == NULL )
6058 				{
6059 					libcerror_error_set(
6060 					 error,
6061 					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6062 					 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6063 					 "%s: missing chunk data: %" PRIu64 ".",
6064 					 function,
6065 					 chunk_index );
6066 
6067 					return( -1 );
6068 				}
6069 				if( chunk_data_offset > chunk_data->data_size )
6070 				{
6071 					libcerror_error_set(
6072 					 error,
6073 					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6074 					 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
6075 					 "%s: chunk offset exceeds chunk data size.",
6076 					 function );
6077 
6078 					return( -1 );
6079 				}
6080 				write_size = (size_t) ( chunk_data->data_size - chunk_data_offset );
6081 
6082 				if( write_size > buffer_size )
6083 				{
6084 					write_size = buffer_size;
6085 				}
6086 				if( write_size == 0 )
6087 				{
6088 					break;
6089 				}
6090 #if defined( HAVE_DEBUG_OUTPUT )
6091 				if( libcnotify_verbose != 0 )
6092 				{
6093 					libcnotify_printf(
6094 					 "%s: updating chunk data: %" PRIu64 " at offset: %" PRIu64 " with size: %" PRIzd ".\n",
6095 					 function,
6096 					 chunk_index,
6097 					 chunk_data_offset,
6098 					 write_size );
6099 				}
6100 #endif
6101 			}
6102 			else
6103 			{
6104 				/* Reserve 4 bytes for the chunk checksum
6105 				 */
6106 				if( libewf_chunk_data_initialize(
6107 				     &chunk_data,
6108 				     (size_t) internal_handle->media_values->chunk_size + sizeof( uint32_t ),
6109 				     error ) != 1 )
6110 				{
6111 					libcerror_error_set(
6112 					 error,
6113 					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6114 					 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6115 					 "%s: unable to create chunk data: %" PRIu64 ".",
6116 					 function,
6117 					 chunk_index );
6118 
6119 					return( -1 );
6120 				}
6121 				if( chunk_data == NULL )
6122 				{
6123 					libcerror_error_set(
6124 					 error,
6125 					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6126 					 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6127 					 "%s: missing chunk data: %" PRIu64 ".",
6128 					 function,
6129 					 chunk_index );
6130 
6131 					return( -1 );
6132 				}
6133 				if( libmfdata_list_set_element_value_by_index(
6134 				     internal_handle->chunk_table_list,
6135 				     internal_handle->chunk_table_cache,
6136 				     (int) chunk_index,
6137 				     (intptr_t *) chunk_data,
6138 				     (int (*)(intptr_t **, libcerror_error_t **)) &libewf_chunk_data_free,
6139 				     LIBMFDATA_LIST_ELEMENT_VALUE_FLAG_MANAGED,
6140 				     error ) != 1 )
6141 				{
6142 					libcerror_error_set(
6143 					 error,
6144 					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6145 					 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6146 					 "%s: unable to set chunk data: %" PRIu64 ".",
6147 					 function,
6148 					 chunk_index );
6149 
6150 					libewf_chunk_data_free(
6151 					 &chunk_data,
6152 					 NULL );
6153 
6154 					return( -1 );
6155 				}
6156 				chunk_data->data_size = internal_handle->media_values->chunk_size;
6157 
6158 				write_size = chunk_data->data_size;
6159 			}
6160 			if( memory_copy(
6161 			     &( ( chunk_data->data )[ chunk_data_offset ] ),
6162 			     &( ( (uint8_t *) buffer )[ buffer_offset ] ),
6163 			     write_size ) == NULL )
6164 			{
6165 				libcerror_error_set(
6166 				 error,
6167 				 LIBCERROR_ERROR_DOMAIN_MEMORY,
6168 				 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
6169 				 "%s: unable to copy buffer to chunk data.",
6170 				 function );
6171 
6172 				return( -1 );
6173 			}
6174 			buffer_offset += write_size;
6175 			buffer_size   -= write_size;
6176 
6177 			chunk_data_size = chunk_data->data_size;
6178 
6179 			if( libewf_chunk_data_pack(
6180 			     chunk_data,
6181 			     EWF_COMPRESSION_NONE,
6182 			     0,
6183 			     EWF_FORMAT_D01,
6184 			     internal_handle->media_values->chunk_size,
6185 			     internal_handle->write_io_handle->compressed_zero_byte_empty_block,
6186 			     internal_handle->write_io_handle->compressed_zero_byte_empty_block_size,
6187 			     error ) != 1 )
6188 			{
6189 				libcerror_error_set(
6190 				 error,
6191 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6192 				 LIBCERROR_RUNTIME_ERROR_GENERIC,
6193 				 "%s: unable to pack chunk data: %" PRIu64 ".",
6194 				 function,
6195 				 chunk_index );
6196 
6197 				return( -1 );
6198 			}
6199 			write_count = libewf_write_io_handle_write_existing_chunk(
6200 				       internal_handle->write_io_handle,
6201 				       internal_handle->io_handle,
6202 				       internal_handle->file_io_pool,
6203 				       internal_handle->media_values,
6204 				       internal_handle->delta_segment_files_list,
6205 				       internal_handle->segment_files_cache,
6206 				       internal_handle->delta_segment_table,
6207 				       internal_handle->chunk_table_list,
6208 				       internal_handle->header_sections,
6209 				       (int) chunk_index,
6210 				       chunk_data->data,
6211 				       chunk_data->data_size,
6212 				       chunk_data_size,
6213 				       0,
6214 				       NULL,
6215 				       0,
6216 				       0,
6217 				       error );
6218 
6219 			if( write_count <= 0 )
6220 			{
6221 				libcerror_error_set(
6222 				 error,
6223 				 LIBCERROR_ERROR_DOMAIN_IO,
6224 				 LIBCERROR_IO_ERROR_WRITE_FAILED,
6225 				 "%s: unable to write existing chunk.",
6226 				 function );
6227 
6228 				return( -1 );
6229 			}
6230 		}
6231 		else
6232 		{
6233 			if( internal_handle->write_io_handle->write_finalized != 0 )
6234 			{
6235 				break;
6236 			}
6237 			if( chunk_exists != 0 )
6238 			{
6239 				libcerror_error_set(
6240 				 error,
6241 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6242 				 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
6243 				 "%s: chunk: %" PRIu64 " already set.",
6244 				 function,
6245 				 chunk_index );
6246 
6247 				return( -1 );
6248 			}
6249 			if( internal_handle->chunk_data == NULL )
6250 			{
6251 				/* Reserve 4 bytes for the chunk checksum
6252 				 */
6253 				if( libewf_chunk_data_initialize(
6254 				     &( internal_handle->chunk_data ),
6255 				     (size_t) internal_handle->media_values->chunk_size + sizeof( uint32_t ),
6256 				     error ) != 1 )
6257 				{
6258 					libcerror_error_set(
6259 					 error,
6260 					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6261 					 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6262 					 "%s: unable to create chunk data: %" PRIu64 ".",
6263 					 function,
6264 					 chunk_index );
6265 
6266 					return( -1 );
6267 				}
6268 				if( internal_handle->chunk_data == NULL )
6269 				{
6270 					libcerror_error_set(
6271 					 error,
6272 					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6273 					 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6274 					 "%s: missing chunk data: %" PRIu64 ".",
6275 					 function,
6276 					 chunk_index );
6277 
6278 					return( -1 );
6279 				}
6280 			}
6281 			if( internal_handle->chunk_data == NULL )
6282 			{
6283 				libcerror_error_set(
6284 				 error,
6285 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6286 				 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6287 				 "%s: internal handle - missing chunk data: %" PRIu64 ".",
6288 				 function,
6289 				 chunk_index );
6290 
6291 				return( -1 );
6292 			}
6293 			if( chunk_data_offset > internal_handle->media_values->chunk_size )
6294 			{
6295 				libcerror_error_set(
6296 				 error,
6297 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6298 				 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
6299 				 "%s: chunk offset exceeds chunk data size.",
6300 				 function );
6301 
6302 				return( -1 );
6303 			}
6304 			write_size = (size_t) ( internal_handle->media_values->chunk_size - chunk_data_offset );
6305 
6306 			if( write_size > buffer_size )
6307 			{
6308 				write_size = buffer_size;
6309 			}
6310 			if( write_size == 0 )
6311 			{
6312 				break;
6313 			}
6314 			if( memory_copy(
6315 			     &( ( internal_handle->chunk_data->data )[ chunk_data_offset ] ),
6316 			     &( ( (uint8_t *) buffer )[ buffer_offset ] ),
6317 			     write_size ) == NULL )
6318 			{
6319 				libcerror_error_set(
6320 				 error,
6321 				 LIBCERROR_ERROR_DOMAIN_MEMORY,
6322 				 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
6323 				 "%s: unable to copy buffer to chunk data.",
6324 				 function );
6325 
6326 				return( -1 );
6327 			}
6328 			internal_handle->chunk_data->data_size = (size_t) ( chunk_data_offset + write_size );
6329 
6330 			buffer_offset += write_size;
6331 			buffer_size   -= write_size;
6332 
6333 			if( internal_handle->chunk_data->data_size == internal_handle->media_values->chunk_size )
6334 			{
6335 				write_chunk = 1;
6336 			}
6337 			else if( ( internal_handle->media_values->media_size != 0 )
6338 			      && ( ( (size64_t) internal_handle->io_handle->current_offset + write_size ) == internal_handle->media_values->media_size ) )
6339 			{
6340 				write_chunk = 1;
6341 			}
6342 			else
6343 			{
6344 				write_chunk = 0;
6345 			}
6346 			if( write_chunk != 0 )
6347 			{
6348 				chunk_data_size = internal_handle->chunk_data->data_size;
6349 
6350 				if( libewf_chunk_data_pack(
6351 				     internal_handle->chunk_data,
6352 				     internal_handle->io_handle->compression_level,
6353 				     internal_handle->io_handle->compression_flags,
6354 				     internal_handle->io_handle->ewf_format,
6355 				     internal_handle->media_values->chunk_size,
6356 				     internal_handle->write_io_handle->compressed_zero_byte_empty_block,
6357 				     internal_handle->write_io_handle->compressed_zero_byte_empty_block_size,
6358 				     error ) != 1 )
6359 				{
6360 					libcerror_error_set(
6361 					 error,
6362 					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6363 					 LIBCERROR_RUNTIME_ERROR_GENERIC,
6364 					 "%s: unable to pack chunk data: %" PRIu64 ".",
6365 					 function,
6366 					 chunk_index );
6367 
6368 					return( -1 );
6369 				}
6370 				write_count = libewf_write_io_handle_write_new_chunk(
6371 					       internal_handle->write_io_handle,
6372 					       internal_handle->io_handle,
6373 					       internal_handle->file_io_pool,
6374 					       internal_handle->media_values,
6375 					       internal_handle->segment_files_list,
6376 					       internal_handle->segment_files_cache,
6377 					       internal_handle->segment_table,
6378 					       internal_handle->chunk_table_list,
6379 					       internal_handle->header_values,
6380 					       internal_handle->hash_values,
6381 					       internal_handle->header_sections,
6382 					       internal_handle->hash_sections,
6383 					       internal_handle->sessions,
6384 					       internal_handle->tracks,
6385 					       internal_handle->acquiry_errors,
6386 					       (int) chunk_index,
6387 					       internal_handle->chunk_data->data,
6388 					       internal_handle->chunk_data->data_size,
6389 					       chunk_data_size,
6390 					       internal_handle->chunk_data->is_compressed,
6391 					       NULL,
6392 					       0,
6393 					       0,
6394 					       error );
6395 
6396 				if( write_count <= 0 )
6397 				{
6398 					libcerror_error_set(
6399 					 error,
6400 					 LIBCERROR_ERROR_DOMAIN_IO,
6401 					 LIBCERROR_IO_ERROR_WRITE_FAILED,
6402 					 "%s: unable to write new chunk.",
6403 					 function );
6404 
6405 					return( -1 );
6406 				}
6407 				if( libmfdata_list_set_element_value_by_index(
6408 				     internal_handle->chunk_table_list,
6409 				     internal_handle->chunk_table_cache,
6410 				     (int) chunk_index,
6411 				     (intptr_t *) internal_handle->chunk_data,
6412 				     (int (*)(intptr_t **, libcerror_error_t **)) &libewf_chunk_data_free,
6413 				     LIBMFDATA_LIST_ELEMENT_VALUE_FLAG_MANAGED,
6414 				     error ) != 1 )
6415 				{
6416 					libcerror_error_set(
6417 					 error,
6418 					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6419 					 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6420 					 "%s: unable to set chunk data: %" PRIu64 ".",
6421 					 function,
6422 					 chunk_index );
6423 
6424 					return( -1 );
6425 				}
6426 				internal_handle->chunk_data = NULL;
6427 			}
6428 		}
6429 		chunk_index      += 1;
6430 		chunk_offset     += internal_handle->media_values->chunk_size;
6431 		chunk_data_offset = 0;
6432 
6433 		internal_handle->io_handle->current_offset += (off64_t) write_size;
6434 
6435 		if( ( internal_handle->media_values->media_size != 0 )
6436 		 && ( (size64_t) internal_handle->io_handle->current_offset >= internal_handle->media_values->media_size ) )
6437 		{
6438 			break;
6439 		}
6440 		if( internal_handle->io_handle->abort != 0 )
6441 		{
6442 			break;
6443 		}
6444 	}
6445 	return( (ssize_t) buffer_offset );
6446 }
6447 
6448 /* Writes (media) data at a specific offset,
6449  * the necessary settings of the write values must have been made
6450  * Will initialize write if necessary
6451  * Returns the number of input bytes written, 0 when no longer bytes can be written or -1 on error
6452  */
libewf_handle_write_random(libewf_handle_t * handle,const void * buffer,size_t buffer_size,off64_t offset,libcerror_error_t ** error)6453 ssize_t libewf_handle_write_random(
6454          libewf_handle_t *handle,
6455          const void *buffer,
6456          size_t buffer_size,
6457          off64_t offset,
6458          libcerror_error_t **error )
6459 {
6460 	static char *function = "libewf_handle_write_random";
6461 	ssize_t write_count   = 0;
6462 
6463 	if( libewf_handle_seek_offset(
6464 	     handle,
6465 	     offset,
6466 	     SEEK_SET,
6467 	     error ) == -1 )
6468 	{
6469 		libcerror_error_set(
6470 		 error,
6471 		 LIBCERROR_ERROR_DOMAIN_IO,
6472 		 LIBCERROR_IO_ERROR_SEEK_FAILED,
6473 		 "%s: unable to seek offset.",
6474 		 function );
6475 
6476 		return( -1 );
6477 	}
6478 	write_count = libewf_handle_write_buffer(
6479 	               handle,
6480 	               buffer,
6481 	               buffer_size,
6482 	               error );
6483 
6484 	if( write_count < 0 )
6485 	{
6486 		libcerror_error_set(
6487 		 error,
6488 		 LIBCERROR_ERROR_DOMAIN_IO,
6489 		 LIBCERROR_IO_ERROR_WRITE_FAILED,
6490 		 "%s: unable to write buffer.",
6491 		 function );
6492 
6493 		return( -1 );
6494 	}
6495 	return( write_count );
6496 }
6497 
6498 /* Finalizes the write by correcting the EWF the meta data in the segment files
6499  * This function is required after write from stream
6500  * Returns the number of bytes written or -1 on error
6501  */
libewf_handle_write_finalize(libewf_handle_t * handle,libcerror_error_t ** error)6502 ssize_t libewf_handle_write_finalize(
6503          libewf_handle_t *handle,
6504          libcerror_error_t **error )
6505 {
6506 	libewf_internal_handle_t *internal_handle = NULL;
6507 	libewf_segment_file_t *segment_file       = NULL;
6508 	static char *function                     = "libewf_handle_write_finalize";
6509 	void *reallocation                        = NULL;
6510 	off64_t segment_file_offset               = 0;
6511 	size_t chunk_data_size                    = 0;
6512 	ssize_t write_count                       = 0;
6513 	ssize_t write_finalize_count              = 0;
6514 	uint64_t chunk_index                      = 0;
6515 	int file_io_pool_entry                    = -1;
6516 	int number_of_segment_files               = 0;
6517 	int segment_files_list_index              = 0;
6518 
6519 	if( handle == NULL )
6520 	{
6521 		libcerror_error_set(
6522 		 error,
6523 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6524 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6525 		 "%s: invalid handle.",
6526 		 function );
6527 
6528 		return( -1 );
6529 	}
6530 	internal_handle = (libewf_internal_handle_t *) handle;
6531 
6532 	if( internal_handle->io_handle == NULL )
6533 	{
6534 		libcerror_error_set(
6535 		 error,
6536 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6537 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6538 		 "%s: invalid handle - missing IO handle.",
6539 		 function );
6540 
6541 		return( -1 );
6542 	}
6543 	if( internal_handle->io_handle->current_offset < 0 )
6544 	{
6545 		libcerror_error_set(
6546 		 error,
6547 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6548 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
6549 		 "%s: invalid handle - invalid IO handle - current offset value out of bounds.",
6550 		 function );
6551 
6552 		return( -1 );
6553 	}
6554 	if( ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
6555 	 && ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_RESUME ) == 0 ) )
6556 	{
6557 		if( internal_handle->chunk_data != NULL )
6558 		{
6559 			libcerror_error_set(
6560 			 error,
6561 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6562 			 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
6563 			 "%s: invalid handle - chunk data set.",
6564 			 function );
6565 
6566 			return( -1 );
6567 		}
6568 	}
6569 	if( internal_handle->write_io_handle == NULL )
6570 	{
6571 		libcerror_error_set(
6572 		 error,
6573 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6574 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6575 		 "%s: invalid handle - missing write IO handle.",
6576 		 function );
6577 
6578 		return( -1 );
6579 	}
6580 	if( internal_handle->media_values == NULL )
6581 	{
6582 		libcerror_error_set(
6583 		 error,
6584 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6585 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6586 		 "%s: invalid handle - missing media values.",
6587 		 function );
6588 
6589 		return( -1 );
6590 	}
6591 	if( internal_handle->media_values->chunk_size == 0 )
6592 	{
6593 		libcerror_error_set(
6594 		 error,
6595 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6596 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6597 		 "%s: invalid handle - invalid media values - missing chunk size.",
6598 		 function );
6599 
6600 		return( -1 );
6601 	}
6602 	if( internal_handle->write_io_handle->write_finalized != 0 )
6603 	{
6604 		return( 0 );
6605 	}
6606 	if( ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
6607 	 && ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_RESUME ) == 0 ) )
6608 	{
6609 		return( 0 );
6610 	}
6611 	chunk_index = internal_handle->io_handle->current_offset
6612 	            / internal_handle->media_values->chunk_size;
6613 
6614 	if( chunk_index >= (uint64_t) INT_MAX )
6615 	{
6616 		libcerror_error_set(
6617 		 error,
6618 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6619 		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
6620 		 "%s: invalid chunk index value exceeds maximum.",
6621 		 function );
6622 
6623 		return( -1 );
6624 	}
6625 	if( internal_handle->chunk_data != NULL )
6626 	{
6627 		chunk_data_size = internal_handle->chunk_data->data_size;
6628 
6629 		if( libewf_chunk_data_pack(
6630 		     internal_handle->chunk_data,
6631 		     internal_handle->io_handle->compression_level,
6632 		     internal_handle->io_handle->compression_flags,
6633 		     internal_handle->io_handle->ewf_format,
6634 		     internal_handle->media_values->chunk_size,
6635 		     internal_handle->write_io_handle->compressed_zero_byte_empty_block,
6636 		     internal_handle->write_io_handle->compressed_zero_byte_empty_block_size,
6637 		     error ) != 1 )
6638 		{
6639 			libcerror_error_set(
6640 			 error,
6641 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6642 			 LIBCERROR_RUNTIME_ERROR_GENERIC,
6643 			 "%s: unable to pack chunk data: %" PRIu64 ".",
6644 			 function,
6645 			 chunk_index );
6646 
6647 			return( -1 );
6648 		}
6649 		write_count = libewf_write_io_handle_write_new_chunk(
6650 			       internal_handle->write_io_handle,
6651 			       internal_handle->io_handle,
6652 			       internal_handle->file_io_pool,
6653 			       internal_handle->media_values,
6654 			       internal_handle->segment_files_list,
6655 			       internal_handle->segment_files_cache,
6656 			       internal_handle->segment_table,
6657 			       internal_handle->chunk_table_list,
6658 			       internal_handle->header_values,
6659 			       internal_handle->hash_values,
6660 			       internal_handle->header_sections,
6661 			       internal_handle->hash_sections,
6662 			       internal_handle->sessions,
6663 			       internal_handle->tracks,
6664 			       internal_handle->acquiry_errors,
6665 			       (int) chunk_index,
6666 			       internal_handle->chunk_data->data,
6667 			       internal_handle->chunk_data->data_size,
6668 			       chunk_data_size,
6669 			       internal_handle->chunk_data->is_compressed,
6670 			       NULL,
6671 			       0,
6672 			       0,
6673 			       error );
6674 
6675 		if( write_count <= 0 )
6676 		{
6677 			libcerror_error_set(
6678 			 error,
6679 			 LIBCERROR_ERROR_DOMAIN_IO,
6680 			 LIBCERROR_IO_ERROR_WRITE_FAILED,
6681 			 "%s: unable to write new chunk.",
6682 			 function );
6683 
6684 			return( -1 );
6685 		}
6686 		write_finalize_count += write_count;
6687 
6688 		if( libmfdata_list_set_element_value_by_index(
6689 		     internal_handle->chunk_table_list,
6690 		     internal_handle->chunk_table_cache,
6691 		     (int) chunk_index,
6692 		     (intptr_t *) internal_handle->chunk_data,
6693 		     (int (*)(intptr_t **, libcerror_error_t **)) &libewf_chunk_data_free,
6694 		     LIBMFDATA_LIST_ELEMENT_VALUE_FLAG_MANAGED,
6695 		     error ) != 1 )
6696 		{
6697 			libcerror_error_set(
6698 			 error,
6699 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6700 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6701 			 "%s: unable to set chunk data: %" PRIu64 ".",
6702 			 function,
6703 			 chunk_index );
6704 
6705 			return( -1 );
6706 		}
6707 		internal_handle->chunk_data = NULL;
6708 	}
6709 	/* Check if all media data has been written
6710 	 */
6711 	if( ( internal_handle->media_values->media_size != 0 )
6712 	 && ( internal_handle->write_io_handle->input_write_count < (ssize64_t) internal_handle->media_values->media_size ) )
6713 	{
6714 		return( write_finalize_count );
6715 	}
6716 	if( libmfdata_file_list_get_number_of_files(
6717 	     internal_handle->segment_files_list,
6718 	     &number_of_segment_files,
6719 	     error ) != 1 )
6720 	{
6721 		libcerror_error_set(
6722 		 error,
6723 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6724 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6725 		 "%s: unable to retrieve number of segment files.",
6726 		 function );
6727 
6728 		return( -1 );
6729 	}
6730 	if( ( number_of_segment_files < 0 )
6731 	 || ( number_of_segment_files > (int) UINT16_MAX ) )
6732 	{
6733 		libcerror_error_set(
6734 		 error,
6735 	 	 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6736 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
6737 		 "%s: invalid number of segment files value out of bounds.",
6738 		 function );
6739 
6740 		return( -1 );
6741 	}
6742 	if( number_of_segment_files == 0 )
6743 	{
6744 		/* No segment file need to be created
6745 		 */
6746 		if( internal_handle->media_values->media_size != 0 )
6747 		{
6748 			return( write_finalize_count );
6749 		}
6750 		/* Create the headers if required
6751 		 */
6752 		if( internal_handle->header_sections == NULL )
6753 		{
6754 			libcerror_error_set(
6755 			 error,
6756 			 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6757 			 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6758 			 "%s: invalid header sections.",
6759 			 function );
6760 
6761 			return( -1 );
6762 		}
6763 		if( ( internal_handle->header_sections->header == NULL )
6764 		 && ( internal_handle->header_sections->header2 == NULL )
6765 		 && ( internal_handle->header_sections->xheader == NULL ) )
6766 		{
6767 			if( libewf_header_sections_generate(
6768 			     internal_handle->header_sections,
6769 			     internal_handle->header_values,
6770 			     time( NULL ),
6771 			     internal_handle->io_handle->compression_level,
6772 			     internal_handle->io_handle->format,
6773 			     internal_handle->io_handle->header_codepage,
6774 			     error ) == -1 )
6775 			{
6776 				libcerror_error_set(
6777 				 error,
6778 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6779 				 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6780 				 "%s: unable to create header(s).",
6781 				 function );
6782 
6783 				return( -1 );
6784 			}
6785 		}
6786 		if( libewf_write_io_handle_create_segment_file(
6787 		     internal_handle->io_handle,
6788 		     internal_handle->file_io_pool,
6789 		     internal_handle->segment_files_list,
6790 		     internal_handle->segment_files_cache,
6791 		     internal_handle->segment_table,
6792 		     1,
6793 		     internal_handle->write_io_handle->maximum_number_of_segments,
6794 		     LIBEWF_SEGMENT_FILE_TYPE_EWF,
6795 		     &segment_file,
6796 		     &segment_files_list_index,
6797 		     &file_io_pool_entry,
6798 		     error ) != 1 )
6799 		{
6800 			libcerror_error_set(
6801 			 error,
6802 			 LIBCERROR_ERROR_DOMAIN_IO,
6803 			 LIBCERROR_IO_ERROR_OPEN_FAILED,
6804 			 "%s: unable to create segment file: 1.",
6805 			 function );
6806 
6807 			return( -1 );
6808 		}
6809 		write_count = libewf_segment_file_write_start(
6810 		               segment_file,
6811 		               internal_handle->io_handle,
6812 		               internal_handle->file_io_pool,
6813 		               file_io_pool_entry,
6814 		               internal_handle->media_values,
6815 		               internal_handle->header_sections,
6816 		               &( internal_handle->write_io_handle->data_section ),
6817 		               error );
6818 
6819 		if( write_count == -1 )
6820 		{
6821 			libcerror_error_set(
6822 			 error,
6823 			 LIBCERROR_ERROR_DOMAIN_IO,
6824 			 LIBCERROR_IO_ERROR_WRITE_FAILED,
6825 			 "%s: unable to write segment file start.",
6826 			 function );
6827 
6828 			return( -1 );
6829 		}
6830 		write_finalize_count += write_count;
6831 	}
6832 	else
6833 	{
6834 		segment_files_list_index = number_of_segment_files - 1;
6835 
6836 		if( libmfdata_file_list_get_file_by_index(
6837 		     internal_handle->segment_files_list,
6838 		     segment_files_list_index,
6839 		     &file_io_pool_entry,
6840 		     error ) != 1 )
6841 		{
6842 			libcerror_error_set(
6843 			 error,
6844 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6845 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6846 			 "%s: unable to retrieve segment file: %d from list.",
6847 			 function,
6848 			 segment_files_list_index + 1 );
6849 
6850 			return( -1 );
6851 		}
6852 		if( libmfdata_file_list_get_file_value_by_index(
6853 		     internal_handle->segment_files_list,
6854 		     internal_handle->file_io_pool,
6855 		     internal_handle->segment_files_cache,
6856 		     segment_files_list_index,
6857 		     (intptr_t **) &segment_file,
6858 		     0,
6859 		     error ) != 1 )
6860 		{
6861 			libcerror_error_set(
6862 			 error,
6863 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6864 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6865 			 "%s: unable to retrieve segment file: %d value from list.",
6866 			 function,
6867 			 segment_files_list_index + 1 );
6868 
6869 			return( -1 );
6870 		}
6871 		if( segment_file == NULL )
6872 		{
6873 			libcerror_error_set(
6874 			 error,
6875 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6876 			 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6877 			 "%s: missing segment file: %d.",
6878 			 function,
6879 			 segment_files_list_index + 1 );
6880 
6881 			return( -1 );
6882 		}
6883 	}
6884 	/* Set segment file to the correct offset if write is resumed
6885 	 */
6886 	if( internal_handle->write_io_handle->resume_segment_file_offset > 0 )
6887 	{
6888 		if( libbfio_pool_seek_offset(
6889 		     internal_handle->file_io_pool,
6890 		     file_io_pool_entry,
6891 		     internal_handle->write_io_handle->resume_segment_file_offset,
6892 		     SEEK_SET,
6893 		     error ) == -1 )
6894 		{
6895 			libcerror_error_set(
6896 			 error,
6897 			 LIBCERROR_ERROR_DOMAIN_IO,
6898 			 LIBCERROR_IO_ERROR_OPEN_FAILED,
6899 			 "%s: unable to seek resume segment file offset: %" PRIi64 " in segment file: %d.",
6900 			 function,
6901 			 internal_handle->write_io_handle->resume_segment_file_offset,
6902 			 segment_files_list_index + 1 );
6903 
6904 			return( -1 );
6905 		}
6906 		internal_handle->write_io_handle->resume_segment_file_offset = 0;
6907 	}
6908 	/* Check if the last segment file is still open for writing
6909 	 */
6910 	if( ( segment_file->flags & LIBEWF_SEGMENT_FILE_FLAG_WRITE_OPEN ) != 0 )
6911 	{
6912 		if( libbfio_pool_get_offset(
6913 		     internal_handle->file_io_pool,
6914 		     file_io_pool_entry,
6915 		     &segment_file_offset,
6916 		     error ) != 1 )
6917 		{
6918 			libcerror_error_set(
6919 			 error,
6920 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
6921 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6922 			 "%s: unable to retrieve current offset in segment file.",
6923 			 function );
6924 
6925 			return( -1 );
6926 		}
6927 		/* Check if chunks section needs to be corrected
6928 		 */
6929 		if( internal_handle->write_io_handle->chunks_section_offset != 0 )
6930 		{
6931 			/* Correct the offset, size in the chunks section
6932 			 */
6933 #if defined( HAVE_DEBUG_OUTPUT )
6934 			if( libcnotify_verbose != 0 )
6935 			{
6936 				libcnotify_printf(
6937 				 "%s: correcting chunks section.\n",
6938 				 function );
6939 			}
6940 #endif
6941 			if( internal_handle->write_io_handle->number_of_table_offsets < internal_handle->write_io_handle->number_of_chunks_written_to_section )
6942 			{
6943 				reallocation = memory_reallocate(
6944 				                internal_handle->write_io_handle->table_offsets,
6945 				                sizeof( ewf_table_offset_t ) * internal_handle->write_io_handle->number_of_chunks_written_to_section );
6946 
6947 				if( reallocation == NULL )
6948 				{
6949 					libcerror_error_set(
6950 					 error,
6951 					 LIBCERROR_ERROR_DOMAIN_MEMORY,
6952 					 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
6953 					 "%s: unable to create table offsets.",
6954 					 function );
6955 
6956 					return( -1 );
6957 				}
6958 				internal_handle->write_io_handle->table_offsets           = (ewf_table_offset_t *) reallocation;
6959 				internal_handle->write_io_handle->number_of_table_offsets = internal_handle->write_io_handle->number_of_chunks_written_to_section;
6960 			}
6961 			write_count = libewf_segment_file_write_chunks_section_correction(
6962 				       segment_file,
6963 				       internal_handle->io_handle,
6964 				       internal_handle->file_io_pool,
6965 				       file_io_pool_entry,
6966 				       segment_file_offset,
6967 				       internal_handle->chunk_table_list,
6968 			               internal_handle->write_io_handle->table_offsets,
6969 			               internal_handle->write_io_handle->number_of_table_offsets,
6970 				       internal_handle->write_io_handle->chunks_section_offset,
6971 				       (size64_t) internal_handle->write_io_handle->chunks_section_write_count,
6972 				       internal_handle->write_io_handle->number_of_chunks_written,
6973 				       internal_handle->write_io_handle->number_of_chunks_written_to_section,
6974 			               error );
6975 
6976 			if( write_count == -1 )
6977 			{
6978 				libcerror_error_set(
6979 				 error,
6980 				 LIBCERROR_ERROR_DOMAIN_IO,
6981 				 LIBCERROR_IO_ERROR_WRITE_FAILED,
6982 				 "%s: unable to correct chunks section.",
6983 				 function );
6984 
6985 				return( -1 );
6986 			}
6987 			segment_file_offset  += write_count;
6988 			write_finalize_count += write_count;
6989 		}
6990 		/* Close the segment file
6991 		 */
6992 #if defined( HAVE_DEBUG_OUTPUT )
6993 		if( libcnotify_verbose != 0 )
6994 		{
6995 			libcnotify_printf(
6996 			 "%s: closing last segment file.\n",
6997 			 function );
6998 		}
6999 #endif
7000 		write_count = libewf_segment_file_write_close(
7001 		               segment_file,
7002 		               internal_handle->io_handle,
7003 		               internal_handle->file_io_pool,
7004 		               file_io_pool_entry,
7005 		               segment_file_offset,
7006 		               internal_handle->write_io_handle->number_of_chunks_written_to_segment,
7007 		               1,
7008 		               internal_handle->hash_sections,
7009 		               internal_handle->hash_values,
7010 		               internal_handle->media_values,
7011 		               internal_handle->sessions,
7012 		               internal_handle->tracks,
7013 		               internal_handle->acquiry_errors,
7014 		               &( internal_handle->write_io_handle->data_section ),
7015 		               error );
7016 
7017 		if( write_count == -1 )
7018 		{
7019 			libcerror_error_set(
7020 			 error,
7021 			 LIBCERROR_ERROR_DOMAIN_IO,
7022 			 LIBCERROR_IO_ERROR_WRITE_FAILED,
7023 			 "%s: unable to close segment file.",
7024 			 function );
7025 
7026 			return( -1 );
7027 		}
7028 		write_finalize_count += write_count;
7029 	}
7030 	/* Correct the media values if streamed write was used
7031 	 */
7032 	if( internal_handle->media_values->media_size == 0 )
7033 	{
7034 		/* Determine the media values
7035 		 */
7036 		internal_handle->media_values->number_of_chunks  = internal_handle->write_io_handle->number_of_chunks_written;
7037 		internal_handle->media_values->number_of_sectors = (uint64_t) ( internal_handle->write_io_handle->input_write_count / internal_handle->media_values->bytes_per_sector );
7038 		internal_handle->media_values->media_size        = (size64_t) internal_handle->write_io_handle->input_write_count;
7039 
7040 		/* Flush the data section write cache
7041 		 */
7042 		memory_free(
7043 		 internal_handle->write_io_handle->data_section );
7044 
7045 		internal_handle->write_io_handle->data_section = NULL;
7046 
7047 		/* Correct the sections in the segment files
7048 		 */
7049 		if( libewf_write_io_handle_finalize_write_sections_corrections(
7050 		     internal_handle->io_handle,
7051 		     internal_handle->file_io_pool,
7052 		     internal_handle->write_io_handle->number_of_chunks_written_to_segment,
7053 		     internal_handle->media_values,
7054 		     internal_handle->segment_files_list,
7055 		     internal_handle->segment_files_cache,
7056 		     internal_handle->hash_values,
7057 		     internal_handle->hash_sections,
7058 		     internal_handle->sessions,
7059 		     internal_handle->tracks,
7060 		     internal_handle->acquiry_errors,
7061 		     &( internal_handle->write_io_handle->data_section ),
7062 		     error ) != 1 )
7063 
7064 		{
7065 			libcerror_error_set(
7066 			 error,
7067 			 LIBCERROR_ERROR_DOMAIN_IO,
7068 			 LIBCERROR_IO_ERROR_WRITE_FAILED,
7069 			 "%s: unable to write sections corrections to segment files.",
7070 			 function );
7071 
7072 			return( -1 );
7073 		}
7074 	}
7075 	internal_handle->write_io_handle->write_finalized = 1;
7076 
7077 	return( write_finalize_count );
7078 }
7079 
7080 /* Seeks a certain offset of the (media) data
7081  * Returns the offset if seek is successful or -1 on error
7082  */
libewf_handle_seek_offset(libewf_handle_t * handle,off64_t offset,int whence,libcerror_error_t ** error)7083 off64_t libewf_handle_seek_offset(
7084          libewf_handle_t *handle,
7085          off64_t offset,
7086          int whence,
7087          libcerror_error_t **error )
7088 {
7089 	libewf_internal_handle_t *internal_handle = NULL;
7090 	static char *function                     = "libewf_handle_seek_offset";
7091 
7092 	if( handle == NULL )
7093 	{
7094 		libcerror_error_set(
7095 		 error,
7096 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7097 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7098 		 "%s: invalid handle.",
7099 		 function );
7100 
7101 		return( -1 );
7102 	}
7103 	internal_handle = (libewf_internal_handle_t *) handle;
7104 
7105 	if( internal_handle->io_handle == NULL )
7106 	{
7107 		libcerror_error_set(
7108 		 error,
7109 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7110 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7111 		 "%s: invalid handle - missing IO handle.",
7112 		 function );
7113 
7114 		return( -1 );
7115 	}
7116 	if( internal_handle->chunk_data != NULL )
7117 	{
7118 		libcerror_error_set(
7119 		 error,
7120 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7121 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
7122 		 "%s: invalid handle - chunk data set.",
7123 		 function );
7124 
7125 		return( -1 );
7126 	}
7127 	if( internal_handle->media_values == NULL )
7128 	{
7129 		libcerror_error_set(
7130 		 error,
7131 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7132 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7133 		 "%s: invalid handle - missing media values.",
7134 		 function );
7135 
7136 		return( -1 );
7137 	}
7138 	if( internal_handle->media_values->chunk_size == 0 )
7139 	{
7140 		libcerror_error_set(
7141 		 error,
7142 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7143 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7144 		 "%s: invalid handle - invalid media values - missing chunk size.",
7145 		 function );
7146 
7147 		return( -1 );
7148 	}
7149 	if( ( whence != SEEK_CUR )
7150 	 && ( whence != SEEK_END )
7151 	 && ( whence != SEEK_SET ) )
7152 	{
7153 		libcerror_error_set(
7154 		 error,
7155 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7156 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
7157 		 "%s: unsupported whence.",
7158 		 function );
7159 
7160 		return( -1 );
7161 	}
7162 	if( whence == SEEK_CUR )
7163 	{
7164 		offset += internal_handle->io_handle->current_offset;
7165 	}
7166 	else if( whence == SEEK_END )
7167 	{
7168 		offset += (off64_t) internal_handle->media_values->media_size;
7169 	}
7170 #if defined( HAVE_DEBUG_OUTPUT )
7171 	if( libcnotify_verbose != 0 )
7172 	{
7173 		libcnotify_printf(
7174 		 "%s: seeking media data offset: %" PRIi64 ".\n",
7175 		 function,
7176 		 offset );
7177 	}
7178 #endif
7179 	if( offset < 0 )
7180 	{
7181 		libcerror_error_set(
7182 		 error,
7183 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7184 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
7185 		 "%s: invalid offset value out of bounds.",
7186 		 function );
7187 
7188 		return( -1 );
7189 	}
7190 	internal_handle->io_handle->current_offset = offset;
7191 
7192 	return( offset );
7193 }
7194 
7195 /* Retrieves the current offset of the (media) data
7196  * Returns 1 if successful or -1 on error
7197  */
libewf_handle_get_offset(libewf_handle_t * handle,off64_t * offset,libcerror_error_t ** error)7198 int libewf_handle_get_offset(
7199      libewf_handle_t *handle,
7200      off64_t *offset,
7201      libcerror_error_t **error )
7202 {
7203 	libewf_internal_handle_t *internal_handle = NULL;
7204 	static char *function                     = "libewf_handle_get_offset";
7205 
7206 	if( handle == NULL )
7207 	{
7208 		libcerror_error_set(
7209 		 error,
7210 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7211 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7212 		 "%s: invalid handle.",
7213 		 function );
7214 
7215 		return( -1 );
7216 	}
7217 	internal_handle = (libewf_internal_handle_t *) handle;
7218 
7219 	if( internal_handle->io_handle == NULL )
7220 	{
7221 		libcerror_error_set(
7222 		 error,
7223 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7224 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7225 		 "%s: invalid handle - missing IO handle.",
7226 		 function );
7227 
7228 		return( -1 );
7229 	}
7230 	if( offset == NULL )
7231 	{
7232 		libcerror_error_set(
7233 		 error,
7234 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7235 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7236 		 "%s: invalid offset.",
7237 		 function );
7238 
7239 		return( -1 );
7240 	}
7241 	*offset = internal_handle->io_handle->current_offset;
7242 
7243 	return( 1 );
7244 }
7245 
7246 /* Sets the maximum number of (concurrent) open file handles
7247  * Returns 1 if successful or -1 on error
7248  */
libewf_handle_set_maximum_number_of_open_handles(libewf_handle_t * handle,int maximum_number_of_open_handles,libcerror_error_t ** error)7249 int libewf_handle_set_maximum_number_of_open_handles(
7250      libewf_handle_t *handle,
7251      int maximum_number_of_open_handles,
7252      libcerror_error_t **error )
7253 {
7254 	libewf_internal_handle_t *internal_handle = NULL;
7255 	static char *function                     = "libewf_handle_set_maximum_number_of_open_handles";
7256 
7257 	if( handle == NULL )
7258 	{
7259 		libcerror_error_set(
7260 		 error,
7261 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7262 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7263 		 "%s: invalid handle.",
7264 		 function );
7265 
7266 		return( -1 );
7267 	}
7268 	internal_handle = (libewf_internal_handle_t *) handle;
7269 
7270 	if( internal_handle->file_io_pool != NULL )
7271 	{
7272 		if( libbfio_pool_set_maximum_number_of_open_handles(
7273 		     internal_handle->file_io_pool,
7274 		     maximum_number_of_open_handles,
7275 		     error ) != 1 )
7276 		{
7277 			libcerror_error_set(
7278 			 error,
7279 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7280 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7281 			 "%s: unable to set maximum number of open handles in file IO handle.",
7282 			 function );
7283 
7284 			return( -1 );
7285 		}
7286 	}
7287 	internal_handle->maximum_number_of_open_handles = maximum_number_of_open_handles;
7288 
7289 	return( 1 );
7290 }
7291 
7292 /* Determine if the segment files are corrupted
7293  * Returns 1 if corrupted, 0 if not or -1 on error
7294  */
libewf_handle_segment_files_corrupted(libewf_handle_t * handle,libcerror_error_t ** error)7295 int libewf_handle_segment_files_corrupted(
7296      libewf_handle_t *handle,
7297      libcerror_error_t **error )
7298 {
7299 	libewf_internal_handle_t *internal_handle = NULL;
7300 	static char *function                     = "libewf_handle_segment_files_corrupted";
7301 
7302 	if( handle == NULL )
7303 	{
7304 		libcerror_error_set(
7305 		 error,
7306 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7307 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7308 		 "%s: invalid handle.",
7309 		 function );
7310 
7311 		return( -1 );
7312 	}
7313 	internal_handle = (libewf_internal_handle_t *) handle;
7314 
7315 	if( internal_handle->segment_table == NULL )
7316 	{
7317 		libcerror_error_set(
7318 		 error,
7319 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7320 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7321 		 "%s: invalid handle - missing segment table.",
7322 		 function );
7323 
7324 		return( -1 );
7325 	}
7326 	if( ( internal_handle->segment_table->flags & LIBEWF_SEGMENT_TABLE_FLAG_CORRUPTED ) != 0 )
7327 	{
7328 		return( 1 );
7329 	}
7330 	return( 0 );
7331 }
7332 
7333 /* Retrieves the segment filename size
7334  * The filename size should include the end of string character
7335  * Returns 1 if successful, 0 if value not present or -1 on error
7336  */
libewf_handle_get_segment_filename_size(libewf_handle_t * handle,size_t * filename_size,libcerror_error_t ** error)7337 int libewf_handle_get_segment_filename_size(
7338      libewf_handle_t *handle,
7339      size_t *filename_size,
7340      libcerror_error_t **error )
7341 {
7342 	libewf_internal_handle_t *internal_handle = NULL;
7343 	static char *function                     = "libewf_handle_get_segment_filename_size";
7344 	int result                                = 0;
7345 
7346 	if( handle == NULL )
7347 	{
7348 		libcerror_error_set(
7349 		 error,
7350 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7351 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7352 		 "%s: invalid handle.",
7353 		 function );
7354 
7355 		return( -1 );
7356 	}
7357 	internal_handle = (libewf_internal_handle_t *) handle;
7358 
7359 	if( internal_handle->segment_table == NULL )
7360 	{
7361 		libcerror_error_set(
7362 		 error,
7363 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7364 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7365 		 "%s: invalid handle - missing segment table.",
7366 		 function );
7367 
7368 		return( -1 );
7369 	}
7370 	result = libewf_segment_table_get_basename_size(
7371 	          internal_handle->segment_table,
7372 	          filename_size,
7373 	          error );
7374 
7375 	if( result == -1 )
7376 	{
7377 		libcerror_error_set(
7378 		 error,
7379 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7380 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7381 		 "%s: unable to retrieve segment table basename size.",
7382 		 function );
7383 
7384 		return( -1 );
7385 	}
7386 	return( result );
7387 }
7388 
7389 /* Retrieves the segment filename
7390  * The filename size should include the end of string character
7391  * Returns 1 if successful, 0 if value not present or -1 on error
7392  */
libewf_handle_get_segment_filename(libewf_handle_t * handle,char * filename,size_t filename_size,libcerror_error_t ** error)7393 int libewf_handle_get_segment_filename(
7394      libewf_handle_t *handle,
7395      char *filename,
7396      size_t filename_size,
7397      libcerror_error_t **error )
7398 {
7399 	libewf_internal_handle_t *internal_handle = NULL;
7400 	static char *function                     = "libewf_handle_get_segment_filename";
7401 	int result                                = 0;
7402 
7403 	if( handle == NULL )
7404 	{
7405 		libcerror_error_set(
7406 		 error,
7407 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7408 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7409 		 "%s: invalid handle.",
7410 		 function );
7411 
7412 		return( -1 );
7413 	}
7414 	internal_handle = (libewf_internal_handle_t *) handle;
7415 
7416 	if( internal_handle->segment_table == NULL )
7417 	{
7418 		libcerror_error_set(
7419 		 error,
7420 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7421 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7422 		 "%s: invalid handle - missing segment table.",
7423 		 function );
7424 
7425 		return( -1 );
7426 	}
7427 	result = libewf_segment_table_get_basename(
7428 	          internal_handle->segment_table,
7429 	          filename,
7430 	          filename_size,
7431 	          error );
7432 
7433 	if( result == -1 )
7434 	{
7435 		libcerror_error_set(
7436 		 error,
7437 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7438 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7439 		 "%s: unable to retrieve segment table basename.",
7440 		 function );
7441 
7442 		return( -1 );
7443 	}
7444 	return( result );
7445 }
7446 
7447 /* Sets the segment file
7448  * Returns 1 if successful or -1 on error
7449  */
libewf_handle_set_segment_filename(libewf_handle_t * handle,const char * filename,size_t filename_length,libcerror_error_t ** error)7450 int libewf_handle_set_segment_filename(
7451      libewf_handle_t *handle,
7452      const char *filename,
7453      size_t filename_length,
7454      libcerror_error_t **error )
7455 {
7456 	libewf_internal_handle_t *internal_handle = NULL;
7457 	static char *function                     = "libewf_handle_set_segment_filename";
7458 
7459 	if( handle == NULL )
7460 	{
7461 		libcerror_error_set(
7462 		 error,
7463 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7464 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7465 		 "%s: invalid handle.",
7466 		 function );
7467 
7468 		return( -1 );
7469 	}
7470 	internal_handle = (libewf_internal_handle_t *) handle;
7471 
7472 	if( internal_handle->write_io_handle == NULL )
7473 	{
7474 		libcerror_error_set(
7475 		 error,
7476 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7477 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7478 		 "%s: segment filename cannot be changed.",
7479 		 function );
7480 
7481 		return( -1 );
7482 	}
7483 	if( internal_handle->segment_table == NULL )
7484 	{
7485 		libcerror_error_set(
7486 		 error,
7487 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7488 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7489 		 "%s: invalid handle - missing segment table.",
7490 		 function );
7491 
7492 		return( -1 );
7493 	}
7494 	if( libewf_segment_table_set_basename(
7495 	     internal_handle->segment_table,
7496 	     filename,
7497 	     filename_length,
7498 	     error ) != 1 )
7499 	{
7500 		libcerror_error_set(
7501 		 error,
7502 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7503 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7504 		 "%s: unable to set segment table basename.",
7505 		 function );
7506 
7507 		return( -1 );
7508 	}
7509 	return( 1 );
7510 }
7511 
7512 #if defined( HAVE_WIDE_CHARACTER_TYPE )
7513 
7514 /* Retrieves the segment filename size
7515  * The filename size includes the end of string character
7516  * Returns 1 if successful, 0 if value not present or -1 on error
7517  */
libewf_handle_get_segment_filename_size_wide(libewf_handle_t * handle,size_t * filename_size,libcerror_error_t ** error)7518 int libewf_handle_get_segment_filename_size_wide(
7519      libewf_handle_t *handle,
7520      size_t *filename_size,
7521      libcerror_error_t **error )
7522 {
7523 	libewf_internal_handle_t *internal_handle = NULL;
7524 	static char *function                     = "libewf_handle_get_segment_filename_size_wide";
7525 	int result                                = 0;
7526 
7527 	if( handle == NULL )
7528 	{
7529 		libcerror_error_set(
7530 		 error,
7531 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7532 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7533 		 "%s: invalid handle.",
7534 		 function );
7535 
7536 		return( -1 );
7537 	}
7538 	internal_handle = (libewf_internal_handle_t *) handle;
7539 
7540 	if( internal_handle->segment_table == NULL )
7541 	{
7542 		libcerror_error_set(
7543 		 error,
7544 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7545 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7546 		 "%s: invalid handle - missing segment table.",
7547 		 function );
7548 
7549 		return( -1 );
7550 	}
7551 	result = libewf_segment_table_get_basename_size_wide(
7552 	          internal_handle->segment_table,
7553 	          filename_size,
7554 	          error );
7555 
7556 	if( result == -1 )
7557 	{
7558 		libcerror_error_set(
7559 		 error,
7560 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7561 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7562 		 "%s: unable to retrieve segment table basename size.",
7563 		 function );
7564 
7565 		return( -1 );
7566 	}
7567 	return( result );
7568 }
7569 
7570 /* Retrieves the segment filename
7571  * The filename size should include the end of string character
7572  * Returns 1 if successful, 0 if value not present or -1 on error
7573  */
libewf_handle_get_segment_filename_wide(libewf_handle_t * handle,wchar_t * filename,size_t filename_size,libcerror_error_t ** error)7574 int libewf_handle_get_segment_filename_wide(
7575      libewf_handle_t *handle,
7576      wchar_t *filename,
7577      size_t filename_size,
7578      libcerror_error_t **error )
7579 {
7580 	libewf_internal_handle_t *internal_handle = NULL;
7581 	static char *function                     = "libewf_handle_get_segment_filename_wide";
7582 	int result                                = 0;
7583 
7584 	if( handle == NULL )
7585 	{
7586 		libcerror_error_set(
7587 		 error,
7588 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7589 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7590 		 "%s: invalid handle.",
7591 		 function );
7592 
7593 		return( -1 );
7594 	}
7595 	internal_handle = (libewf_internal_handle_t *) handle;
7596 
7597 	if( internal_handle->segment_table == NULL )
7598 	{
7599 		libcerror_error_set(
7600 		 error,
7601 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7602 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7603 		 "%s: invalid handle - missing segment table.",
7604 		 function );
7605 
7606 		return( -1 );
7607 	}
7608 	result = libewf_segment_table_get_basename_wide(
7609 	          internal_handle->segment_table,
7610 	          filename,
7611 	          filename_size,
7612 	          error );
7613 
7614 	if( result == -1 )
7615 	{
7616 		libcerror_error_set(
7617 		 error,
7618 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7619 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7620 		 "%s: unable to retrieve segment table basename.",
7621 		 function );
7622 
7623 		return( -1 );
7624 	}
7625 	return( result );
7626 }
7627 
7628 /* Sets the segment file
7629  * Returns 1 if successful or -1 on error
7630  */
libewf_handle_set_segment_filename_wide(libewf_handle_t * handle,const wchar_t * filename,size_t filename_length,libcerror_error_t ** error)7631 int libewf_handle_set_segment_filename_wide(
7632      libewf_handle_t *handle,
7633      const wchar_t *filename,
7634      size_t filename_length,
7635      libcerror_error_t **error )
7636 {
7637 	libewf_internal_handle_t *internal_handle = NULL;
7638 	static char *function                     = "libewf_handle_set_segment_filename_wide";
7639 
7640 	if( handle == NULL )
7641 	{
7642 		libcerror_error_set(
7643 		 error,
7644 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7645 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7646 		 "%s: invalid handle.",
7647 		 function );
7648 
7649 		return( -1 );
7650 	}
7651 	internal_handle = (libewf_internal_handle_t *) handle;
7652 
7653 	if( internal_handle->write_io_handle == NULL )
7654 	{
7655 		libcerror_error_set(
7656 		 error,
7657 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7658 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7659 		 "%s: segment filename cannot be changed.",
7660 		 function );
7661 
7662 		return( -1 );
7663 	}
7664 	if( internal_handle->segment_table == NULL )
7665 	{
7666 		libcerror_error_set(
7667 		 error,
7668 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7669 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7670 		 "%s: invalid handle - missing segment table.",
7671 		 function );
7672 
7673 		return( -1 );
7674 	}
7675 	if( libewf_segment_table_set_basename_wide(
7676 	     internal_handle->segment_table,
7677 	     filename,
7678 	     filename_length,
7679 	     error ) != 1 )
7680 	{
7681 		libcerror_error_set(
7682 		 error,
7683 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7684 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7685 		 "%s: unable to set segment table basename.",
7686 		 function );
7687 
7688 		return( -1 );
7689 	}
7690 	return( 1 );
7691 }
7692 
7693 #endif
7694 
7695 /* Retrieves the maximum segment file size
7696  * Returns 1 if successful or -1 on error
7697  */
libewf_handle_get_maximum_segment_size(libewf_handle_t * handle,size64_t * maximum_segment_size,libcerror_error_t ** error)7698 int libewf_handle_get_maximum_segment_size(
7699      libewf_handle_t *handle,
7700      size64_t *maximum_segment_size,
7701      libcerror_error_t **error )
7702 {
7703 	libewf_internal_handle_t *internal_handle = NULL;
7704 	static char *function                     = "libewf_handle_get_maximum_segment_size";
7705 
7706 	if( handle == NULL )
7707 	{
7708 		libcerror_error_set(
7709 		 error,
7710 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7711 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7712 		 "%s: invalid handle.",
7713 		 function );
7714 
7715 		return( -1 );
7716 	}
7717 	internal_handle = (libewf_internal_handle_t *) handle;
7718 
7719 	if( internal_handle->segment_table == NULL )
7720 	{
7721 		libcerror_error_set(
7722 		 error,
7723 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7724 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7725 		 "%s: invalid handle - missing segment table.",
7726 		 function );
7727 
7728 		return( -1 );
7729 	}
7730 	if( maximum_segment_size == NULL )
7731 	{
7732 		libcerror_error_set(
7733 		 error,
7734 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7735 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7736 		 "%s: invalid maximum segment size.",
7737 		 function );
7738 
7739 		return( -1 );
7740 	}
7741 	*maximum_segment_size = internal_handle->segment_table->maximum_segment_size;
7742 
7743 	return( 1 );
7744 }
7745 
7746 /* Sets the maximum segment file size
7747  * A maximum segment file size of 0 represents the maximum possible size for the format
7748  * If the maximum segment file size is smaller than the size needed to store a single chunk
7749  * the size off the latter is enforced and not the maximum segment file size
7750  * Returns 1 if successful or -1 on error
7751  */
libewf_handle_set_maximum_segment_size(libewf_handle_t * handle,size64_t maximum_segment_size,libcerror_error_t ** error)7752 int libewf_handle_set_maximum_segment_size(
7753      libewf_handle_t *handle,
7754      size64_t maximum_segment_size,
7755      libcerror_error_t **error )
7756 {
7757 	libewf_internal_handle_t *internal_handle = NULL;
7758 	static char *function                     = "libewf_handle_set_maximum_segment_size";
7759 
7760 	if( handle == NULL )
7761 	{
7762 		libcerror_error_set(
7763 		 error,
7764 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7765 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7766 		 "%s: invalid handle.",
7767 		 function );
7768 
7769 		return( -1 );
7770 	}
7771 	internal_handle = (libewf_internal_handle_t *) handle;
7772 
7773 	if( internal_handle->media_values == NULL )
7774 	{
7775 		libcerror_error_set(
7776 		 error,
7777 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7778 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7779 		 "%s: invalid handle - missing media values.",
7780 		 function );
7781 
7782 		return( -1 );
7783 	}
7784 	if( internal_handle->segment_table == NULL )
7785 	{
7786 		libcerror_error_set(
7787 		 error,
7788 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7789 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7790 		 "%s: invalid handle - missing segment table.",
7791 		 function );
7792 
7793 		return( -1 );
7794 	}
7795 	if( ( internal_handle->read_io_handle != NULL )
7796 	 || ( internal_handle->write_io_handle == NULL )
7797 	 || ( internal_handle->write_io_handle->values_initialized != 0 ) )
7798 	{
7799 		libcerror_error_set(
7800 		 error,
7801 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7802 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7803 		 "%s: maximum segment size cannot be changed.",
7804 		 function );
7805 
7806 		return( -1 );
7807 	}
7808 	if( maximum_segment_size > (size64_t) INT64_MAX )
7809 	{
7810 		libcerror_error_set(
7811 		 error,
7812 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7813 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
7814 		 "%s: invalid maximum segment size value exceeds maximum.",
7815 		 function );
7816 
7817 		return( -1 );
7818 	}
7819 	if( maximum_segment_size > internal_handle->write_io_handle->maximum_segment_file_size )
7820 	{
7821 		libcerror_error_set(
7822 		 error,
7823 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7824 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
7825 		 "%s: invalid segment file size value out of bounds.",
7826 		 function );
7827 
7828 		return( -1 );
7829 	}
7830 	internal_handle->segment_table->maximum_segment_size = maximum_segment_size;
7831 
7832 	return( 1 );
7833 }
7834 
7835 /* Retrieves the delta segment filename size
7836  * The filename size includes the end of string character
7837  * Returns 1 if successful, 0 if value not present or -1 on error
7838  */
libewf_handle_get_delta_segment_filename_size(libewf_handle_t * handle,size_t * filename_size,libcerror_error_t ** error)7839 int libewf_handle_get_delta_segment_filename_size(
7840      libewf_handle_t *handle,
7841      size_t *filename_size,
7842      libcerror_error_t **error )
7843 {
7844 	libewf_internal_handle_t *internal_handle = NULL;
7845 	static char *function                     = "libewf_handle_get_delta_segment_filename_size";
7846 	int result                                = 0;
7847 
7848 	if( handle == NULL )
7849 	{
7850 		libcerror_error_set(
7851 		 error,
7852 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7853 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7854 		 "%s: invalid handle.",
7855 		 function );
7856 
7857 		return( -1 );
7858 	}
7859 	internal_handle = (libewf_internal_handle_t *) handle;
7860 
7861 	if( internal_handle->delta_segment_table == NULL )
7862 	{
7863 		libcerror_error_set(
7864 		 error,
7865 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7866 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7867 		 "%s: invalid handle - missing delta segment table.",
7868 		 function );
7869 
7870 		return( -1 );
7871 	}
7872 	result = libewf_segment_table_get_basename_size(
7873 	          internal_handle->delta_segment_table,
7874 	          filename_size,
7875 	          error );
7876 
7877 	if( result == -1 )
7878 	{
7879 		libcerror_error_set(
7880 		 error,
7881 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7882 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7883 		 "%s: unable to retrieve segment table basename size.",
7884 		 function );
7885 
7886 		return( -1 );
7887 	}
7888 	return( result );
7889 }
7890 
7891 /* Retrieves the delta segment filename
7892  * The filename size should include the end of string character
7893  * Returns 1 if successful, 0 if value not present or -1 on error
7894  */
libewf_handle_get_delta_segment_filename(libewf_handle_t * handle,char * filename,size_t filename_size,libcerror_error_t ** error)7895 int libewf_handle_get_delta_segment_filename(
7896      libewf_handle_t *handle,
7897      char *filename,
7898      size_t filename_size,
7899      libcerror_error_t **error )
7900 {
7901 	libewf_internal_handle_t *internal_handle = NULL;
7902 	static char *function                     = "libewf_handle_get_delta_segment_filename";
7903 	int result                                = 0;
7904 
7905 	if( handle == NULL )
7906 	{
7907 		libcerror_error_set(
7908 		 error,
7909 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7910 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7911 		 "%s: invalid handle.",
7912 		 function );
7913 
7914 		return( -1 );
7915 	}
7916 	internal_handle = (libewf_internal_handle_t *) handle;
7917 
7918 	if( internal_handle->delta_segment_table == NULL )
7919 	{
7920 		libcerror_error_set(
7921 		 error,
7922 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7923 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7924 		 "%s: invalid handle - missing delta segment table.",
7925 		 function );
7926 
7927 		return( -1 );
7928 	}
7929 	result = libewf_segment_table_get_basename(
7930 	          internal_handle->delta_segment_table,
7931 	          filename,
7932 	          filename_size,
7933 	          error );
7934 
7935 	if( result == -1 )
7936 	{
7937 		libcerror_error_set(
7938 		 error,
7939 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7940 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7941 		 "%s: unable to retrieve segment table basename.",
7942 		 function );
7943 
7944 		return( -1 );
7945 	}
7946 	return( result );
7947 }
7948 
7949 /* Sets the delta segment file
7950  * Returns 1 if successful or -1 on error
7951  */
libewf_handle_set_delta_segment_filename(libewf_handle_t * handle,const char * filename,size_t filename_length,libcerror_error_t ** error)7952 int libewf_handle_set_delta_segment_filename(
7953      libewf_handle_t *handle,
7954      const char *filename,
7955      size_t filename_length,
7956      libcerror_error_t **error )
7957 {
7958 	libewf_internal_handle_t *internal_handle = NULL;
7959 	static char *function                     = "libewf_handle_set_delta_segment_filename";
7960 
7961 	if( handle == NULL )
7962 	{
7963 		libcerror_error_set(
7964 		 error,
7965 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7966 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7967 		 "%s: invalid handle.",
7968 		 function );
7969 
7970 		return( -1 );
7971 	}
7972 	internal_handle = (libewf_internal_handle_t *) handle;
7973 
7974 	if( internal_handle->write_io_handle == NULL )
7975 	{
7976 		libcerror_error_set(
7977 		 error,
7978 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7979 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7980 		 "%s: delta segment filename cannot be changed.",
7981 		 function );
7982 
7983 		return( -1 );
7984 	}
7985 	if( internal_handle->delta_segment_table == NULL )
7986 	{
7987 		libcerror_error_set(
7988 		 error,
7989 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
7990 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
7991 		 "%s: invalid handle - missing delta segment table.",
7992 		 function );
7993 
7994 		return( -1 );
7995 	}
7996 	if( libewf_segment_table_set_basename(
7997 	     internal_handle->delta_segment_table,
7998 	     filename,
7999 	     filename_length,
8000 	     error ) != 1 )
8001 	{
8002 		libcerror_error_set(
8003 		 error,
8004 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8005 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
8006 		 "%s: unable to set segment table basename.",
8007 		 function );
8008 
8009 		return( -1 );
8010 	}
8011 	return( 1 );
8012 }
8013 
8014 #if defined( HAVE_WIDE_CHARACTER_TYPE )
8015 
8016 /* Retrieves the delta segment filename size
8017  * The filename size includes the end of string character
8018  * Returns 1 if successful, 0 if value not present or -1 on error
8019  */
libewf_handle_get_delta_segment_filename_size_wide(libewf_handle_t * handle,size_t * filename_size,libcerror_error_t ** error)8020 int libewf_handle_get_delta_segment_filename_size_wide(
8021      libewf_handle_t *handle,
8022      size_t *filename_size,
8023      libcerror_error_t **error )
8024 {
8025 	libewf_internal_handle_t *internal_handle = NULL;
8026 	static char *function                     = "libewf_handle_get_delta_segment_filename_size_wide";
8027 	int result                                = 0;
8028 
8029 	if( handle == NULL )
8030 	{
8031 		libcerror_error_set(
8032 		 error,
8033 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8034 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8035 		 "%s: invalid handle.",
8036 		 function );
8037 
8038 		return( -1 );
8039 	}
8040 	internal_handle = (libewf_internal_handle_t *) handle;
8041 
8042 	if( internal_handle->delta_segment_table == NULL )
8043 	{
8044 		libcerror_error_set(
8045 		 error,
8046 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8047 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8048 		 "%s: invalid handle - missing delta segment table.",
8049 		 function );
8050 
8051 		return( -1 );
8052 	}
8053 	result = libewf_segment_table_get_basename_size_wide(
8054 	          internal_handle->delta_segment_table,
8055 	          filename_size,
8056 	          error );
8057 
8058 	if( result == -1 )
8059 	{
8060 		libcerror_error_set(
8061 		 error,
8062 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8063 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8064 		 "%s: unable to retrieve segment table basename size.",
8065 		 function );
8066 
8067 		return( -1 );
8068 	}
8069 	return( result );
8070 }
8071 
8072 /* Retrieves the delta segment filename
8073  * The filename size should include the end of string character
8074  * Returns 1 if successful, 0 if value not present or -1 on error
8075  */
libewf_handle_get_delta_segment_filename_wide(libewf_handle_t * handle,wchar_t * filename,size_t filename_size,libcerror_error_t ** error)8076 int libewf_handle_get_delta_segment_filename_wide(
8077      libewf_handle_t *handle,
8078      wchar_t *filename,
8079      size_t filename_size,
8080      libcerror_error_t **error )
8081 {
8082 	libewf_internal_handle_t *internal_handle = NULL;
8083 	static char *function                     = "libewf_handle_get_delta_segment_filename_wide";
8084 	int result                                = 0;
8085 
8086 	if( handle == NULL )
8087 	{
8088 		libcerror_error_set(
8089 		 error,
8090 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8091 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8092 		 "%s: invalid handle.",
8093 		 function );
8094 
8095 		return( -1 );
8096 	}
8097 	internal_handle = (libewf_internal_handle_t *) handle;
8098 
8099 	if( internal_handle->delta_segment_table == NULL )
8100 	{
8101 		libcerror_error_set(
8102 		 error,
8103 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8104 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8105 		 "%s: invalid handle - missing delta segment table.",
8106 		 function );
8107 
8108 		return( -1 );
8109 	}
8110 	result = libewf_segment_table_get_basename_wide(
8111 	          internal_handle->delta_segment_table,
8112 	          filename,
8113 	          filename_size,
8114 	          error );
8115 
8116 	if( result == -1 )
8117 	{
8118 		libcerror_error_set(
8119 		 error,
8120 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8121 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8122 		 "%s: unable to retrieve segment table basename.",
8123 		 function );
8124 
8125 		return( -1 );
8126 	}
8127 	return( result );
8128 }
8129 
8130 /* Sets the delta segment file
8131  * Returns 1 if successful or -1 on error
8132  */
libewf_handle_set_delta_segment_filename_wide(libewf_handle_t * handle,const wchar_t * filename,size_t filename_length,libcerror_error_t ** error)8133 int libewf_handle_set_delta_segment_filename_wide(
8134      libewf_handle_t *handle,
8135      const wchar_t *filename,
8136      size_t filename_length,
8137      libcerror_error_t **error )
8138 {
8139 	libewf_internal_handle_t *internal_handle = NULL;
8140 	static char *function                     = "libewf_handle_set_delta_segment_filename_wide";
8141 
8142 	if( handle == NULL )
8143 	{
8144 		libcerror_error_set(
8145 		 error,
8146 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8147 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8148 		 "%s: invalid handle.",
8149 		 function );
8150 
8151 		return( -1 );
8152 	}
8153 	internal_handle = (libewf_internal_handle_t *) handle;
8154 
8155 	if( internal_handle->write_io_handle == NULL )
8156 	{
8157 		libcerror_error_set(
8158 		 error,
8159 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8160 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
8161 		 "%s: delta segment filename cannot be changed.",
8162 		 function );
8163 
8164 		return( -1 );
8165 	}
8166 	if( internal_handle->delta_segment_table == NULL )
8167 	{
8168 		libcerror_error_set(
8169 		 error,
8170 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8171 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8172 		 "%s: invalid handle - missing delta segment table.",
8173 		 function );
8174 
8175 		return( -1 );
8176 	}
8177 	if( libewf_segment_table_set_basename_wide(
8178 	     internal_handle->delta_segment_table,
8179 	     filename,
8180 	     filename_length,
8181 	     error ) != 1 )
8182 	{
8183 		libcerror_error_set(
8184 		 error,
8185 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8186 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
8187 		 "%s: unable to set segment table basename.",
8188 		 function );
8189 
8190 		return( -1 );
8191 	}
8192 	return( 1 );
8193 }
8194 
8195 #endif
8196 
8197 /* Retrieves the maximum delta segment file size
8198  * Returns 1 if successful or -1 on error
8199  */
libewf_handle_get_maximum_delta_segment_size(libewf_handle_t * handle,size64_t * maximum_delta_segment_size,libcerror_error_t ** error)8200 int libewf_handle_get_maximum_delta_segment_size(
8201      libewf_handle_t *handle,
8202      size64_t *maximum_delta_segment_size,
8203      libcerror_error_t **error )
8204 {
8205 	libewf_internal_handle_t *internal_handle = NULL;
8206 	static char *function                     = "libewf_handle_get_maximum_delta_segment_size";
8207 
8208 	if( handle == NULL )
8209 	{
8210 		libcerror_error_set(
8211 		 error,
8212 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8213 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8214 		 "%s: invalid handle.",
8215 		 function );
8216 
8217 		return( -1 );
8218 	}
8219 	internal_handle = (libewf_internal_handle_t *) handle;
8220 
8221 	if( internal_handle->delta_segment_table == NULL )
8222 	{
8223 		libcerror_error_set(
8224 		 error,
8225 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8226 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8227 		 "%s: invalid handle - missing delta segment table.",
8228 		 function );
8229 
8230 		return( -1 );
8231 	}
8232 	if( maximum_delta_segment_size == NULL )
8233 	{
8234 		libcerror_error_set(
8235 		 error,
8236 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8237 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8238 		 "%s: invalid maximum delta segment size.",
8239 		 function );
8240 
8241 		return( -1 );
8242 	}
8243 	*maximum_delta_segment_size = internal_handle->delta_segment_table->maximum_segment_size;
8244 
8245 	return( 1 );
8246 }
8247 
8248 /* Sets the maximum delta segment file size
8249  * Returns 1 if successful or -1 on error
8250  */
libewf_handle_set_maximum_delta_segment_size(libewf_handle_t * handle,size64_t maximum_delta_segment_size,libcerror_error_t ** error)8251 int libewf_handle_set_maximum_delta_segment_size(
8252      libewf_handle_t *handle,
8253      size64_t maximum_delta_segment_size,
8254      libcerror_error_t **error )
8255 {
8256 	libewf_internal_handle_t *internal_handle = NULL;
8257 	static char *function                     = "libewf_handle_set_maximum_delta_segment_size";
8258 
8259 	if( handle == NULL )
8260 	{
8261 		libcerror_error_set(
8262 		 error,
8263 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8264 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8265 		 "%s: invalid handle.",
8266 		 function );
8267 
8268 		return( -1 );
8269 	}
8270 	internal_handle = (libewf_internal_handle_t *) handle;
8271 
8272 	if( internal_handle->delta_segment_table == NULL )
8273 	{
8274 		libcerror_error_set(
8275 		 error,
8276 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8277 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8278 		 "%s: invalid handle - missing delta segment table.",
8279 		 function );
8280 
8281 		return( -1 );
8282 	}
8283 	if( ( internal_handle->write_io_handle == NULL )
8284 	 || ( internal_handle->write_io_handle->values_initialized != 0 ) )
8285 	{
8286 		libcerror_error_set(
8287 		 error,
8288 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8289 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
8290 		 "%s: maximum delta segment size cannot be changed.",
8291 		 function );
8292 
8293 		return( -1 );
8294 	}
8295 	if( maximum_delta_segment_size > (size64_t) INT64_MAX )
8296 	{
8297 		libcerror_error_set(
8298 		 error,
8299 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8300 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
8301 		 "%s: invalid maximum delta segment size value exceeds maximum.",
8302 		 function );
8303 
8304 		return( -1 );
8305 	}
8306 	if( maximum_delta_segment_size == 0 )
8307 	{
8308 		libcerror_error_set(
8309 		 error,
8310 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8311 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
8312 		 "%s: invalid maximum delta segment size value out of bounds.",
8313 		 function );
8314 
8315 		return( -1 );
8316 	}
8317 	internal_handle->delta_segment_table->maximum_segment_size = maximum_delta_segment_size;
8318 
8319 	return( 1 );
8320 }
8321 
8322 /* Retrieves the filename size of the (delta) segment file of the current chunk
8323  * The filename size should include the end of string character
8324  * Returns 1 if successful, 0 if no such filename or -1 on error
8325  */
libewf_handle_get_filename_size(libewf_handle_t * handle,size_t * filename_size,libcerror_error_t ** error)8326 int libewf_handle_get_filename_size(
8327      libewf_handle_t *handle,
8328      size_t *filename_size,
8329      libcerror_error_t **error )
8330 {
8331 	libbfio_handle_t *file_io_handle = NULL;
8332 	static char *function            = "libewf_handle_get_filename_size";
8333 	int result                       = 0;
8334 
8335 	if( handle == NULL )
8336 	{
8337 		libcerror_error_set(
8338 		 error,
8339 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8340 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8341 		 "%s: invalid handle.",
8342 		 function );
8343 
8344 		return( -1 );
8345 	}
8346 	result = libewf_handle_get_file_io_handle(
8347 	          handle,
8348 	          &file_io_handle,
8349 	          error );
8350 
8351 	if( result == -1 )
8352 	{
8353 		libcerror_error_set(
8354 		 error,
8355 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8356 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8357 		 "%s: unable to retrieve file IO handle for current chunk.",
8358 		 function );
8359 
8360 		return( -1 );
8361 	}
8362 	else if( result != 0 )
8363 	{
8364 		if( libbfio_file_get_name_size(
8365 		     file_io_handle,
8366 		     filename_size,
8367 		     error ) != 1 )
8368 		{
8369 			libcerror_error_set(
8370 			 error,
8371 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8372 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8373 			 "%s: unable to retrieve filename size.",
8374 			 function );
8375 
8376 			return( -1 );
8377 		}
8378 	}
8379 	return( result );
8380 }
8381 
8382 /* Retrieves the filename of the (delta) segment file of the current chunk
8383  * The filename size should include the end of string character
8384  * Returns 1 if successful, 0 if no such filename or -1 on error
8385  */
libewf_handle_get_filename(libewf_handle_t * handle,char * filename,size_t filename_size,libcerror_error_t ** error)8386 int libewf_handle_get_filename(
8387      libewf_handle_t *handle,
8388      char *filename,
8389      size_t filename_size,
8390      libcerror_error_t **error )
8391 {
8392 	libbfio_handle_t *file_io_handle = NULL;
8393 	static char *function            = "libewf_handle_get_filename";
8394 	int result                       = 0;
8395 
8396 	if( handle == NULL )
8397 	{
8398 		libcerror_error_set(
8399 		 error,
8400 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8401 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8402 		 "%s: invalid handle.",
8403 		 function );
8404 
8405 		return( -1 );
8406 	}
8407 	result = libewf_handle_get_file_io_handle(
8408 	          handle,
8409 	          &file_io_handle,
8410 	          error );
8411 
8412 	if( result == -1 )
8413 	{
8414 		libcerror_error_set(
8415 		 error,
8416 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8417 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8418 		 "%s: unable to retrieve file IO handle for current chunk.",
8419 		 function );
8420 
8421 		return( -1 );
8422 	}
8423 	else if( result != 0 )
8424 	{
8425 		if( libbfio_file_get_name(
8426 		     file_io_handle,
8427 		     filename,
8428 		     filename_size,
8429 		     error ) != 1 )
8430 		{
8431 			libcerror_error_set(
8432 			 error,
8433 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8434 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8435 			 "%s: unable to retrieve filename.",
8436 			 function );
8437 
8438 			return( -1 );
8439 		}
8440 	}
8441 	return( result );
8442 }
8443 
8444 #if defined( HAVE_WIDE_CHARACTER_TYPE )
8445 
8446 /* Retrieves the filename size of the (delta) segment file of the current chunk
8447  * The filename size includes the end of string character
8448  * Returns 1 if successful, 0 if no such filename or -1 on error
8449  */
libewf_handle_get_filename_size_wide(libewf_handle_t * handle,size_t * filename_size,libcerror_error_t ** error)8450 int libewf_handle_get_filename_size_wide(
8451      libewf_handle_t *handle,
8452      size_t *filename_size,
8453      libcerror_error_t **error )
8454 {
8455 	libbfio_handle_t *file_io_handle = NULL;
8456 	static char *function            = "libewf_handle_get_filename_size_wide";
8457 	int result                       = 0;
8458 
8459 	if( handle == NULL )
8460 	{
8461 		libcerror_error_set(
8462 		 error,
8463 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8464 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8465 		 "%s: invalid handle.",
8466 		 function );
8467 
8468 		return( -1 );
8469 	}
8470 	result = libewf_handle_get_file_io_handle(
8471 	          handle,
8472 	          &file_io_handle,
8473 	          error );
8474 
8475 	if( result == -1 )
8476 	{
8477 		libcerror_error_set(
8478 		 error,
8479 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8480 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8481 		 "%s: unable to retrieve file IO handle for current chunk.",
8482 		 function );
8483 
8484 		return( -1 );
8485 	}
8486 	else if( result != 0 )
8487 	{
8488 		if( libbfio_file_get_name_size_wide(
8489 		     file_io_handle,
8490 		     filename_size,
8491 		     error ) != 1 )
8492 		{
8493 			libcerror_error_set(
8494 			 error,
8495 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8496 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8497 			 "%s: unable to retrieve filename size.",
8498 			 function );
8499 
8500 			return( -1 );
8501 		}
8502 	}
8503 	return( result );
8504 }
8505 
8506 /* Retrieves the filename of the (delta) segment file of the current chunk
8507  * The filename size should include the end of string character
8508  * Returns 1 if successful, 0 if no such filename or -1 on error
8509  */
libewf_handle_get_filename_wide(libewf_handle_t * handle,wchar_t * filename,size_t filename_size,libcerror_error_t ** error)8510 int libewf_handle_get_filename_wide(
8511      libewf_handle_t *handle,
8512      wchar_t *filename,
8513      size_t filename_size,
8514      libcerror_error_t **error )
8515 {
8516 	libbfio_handle_t *file_io_handle = NULL;
8517 	static char *function            = "libewf_handle_get_filename_wide";
8518 	int result                       = 0;
8519 
8520 	if( handle == NULL )
8521 	{
8522 		libcerror_error_set(
8523 		 error,
8524 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8525 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8526 		 "%s: invalid handle.",
8527 		 function );
8528 
8529 		return( -1 );
8530 	}
8531 	result = libewf_handle_get_file_io_handle(
8532 	          handle,
8533 	          &file_io_handle,
8534 	          error );
8535 
8536 	if( result == -1 )
8537 	{
8538 		libcerror_error_set(
8539 		 error,
8540 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8541 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8542 		 "%s: unable to retrieve file IO handle for current chunk.",
8543 		 function );
8544 
8545 		return( -1 );
8546 	}
8547 	else if( result != 0 )
8548 	{
8549 		if( libbfio_file_get_name_wide(
8550 		     file_io_handle,
8551 		     filename,
8552 		     filename_size,
8553 		     error ) != 1 )
8554 		{
8555 			libcerror_error_set(
8556 			 error,
8557 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8558 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8559 			 "%s: unable to retrieve filename.",
8560 			 function );
8561 
8562 			return( -1 );
8563 		}
8564 	}
8565 	return( result );
8566 }
8567 
8568 #endif
8569 
8570 /* Retrieves the file IO handle of the (delta) segment file of the current chunk
8571  * Returns 1 if successful, 0 if no such file IO handle or -1 on error
8572  */
libewf_handle_get_file_io_handle(libewf_handle_t * handle,libbfio_handle_t ** file_io_handle,libcerror_error_t ** error)8573 int libewf_handle_get_file_io_handle(
8574      libewf_handle_t *handle,
8575      libbfio_handle_t **file_io_handle,
8576      libcerror_error_t **error )
8577 {
8578 	libewf_internal_handle_t *internal_handle = NULL;
8579 	static char *function                     = "libewf_handle_get_file_io_handle";
8580 	off64_t chunk_offset                      = 0;
8581 	size64_t chunk_size                       = 0;
8582 	uint64_t chunk_index                      = 0;
8583 	uint32_t chunk_flags                      = 0;
8584 	int file_io_pool_entry                    = 0;
8585 
8586 	if( handle == NULL )
8587 	{
8588 		libcerror_error_set(
8589 		 error,
8590 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8591 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8592 		 "%s: invalid handle.",
8593 		 function );
8594 
8595 		return( -1 );
8596 	}
8597 	internal_handle = (libewf_internal_handle_t *) handle;
8598 
8599 	if( internal_handle->io_handle == NULL )
8600 	{
8601 		libcerror_error_set(
8602 		 error,
8603 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8604 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8605 		 "%s: invalid handle - missing IO handle.",
8606 		 function );
8607 
8608 		return( -1 );
8609 	}
8610 	if( internal_handle->io_handle->current_offset < 0 )
8611 	{
8612 		libcerror_error_set(
8613 		 error,
8614 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8615 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
8616 		 "%s: invalid handle - invalid IO handle - current offset value out of bounds.",
8617 		 function );
8618 
8619 		return( -1 );
8620 	}
8621 	if( internal_handle->media_values == NULL )
8622 	{
8623 		libcerror_error_set(
8624 		 error,
8625 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8626 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8627 		 "%s: invalid handle - missing media values.",
8628 		 function );
8629 
8630 		return( -1 );
8631 	}
8632 	if( internal_handle->media_values->chunk_size == 0 )
8633 	{
8634 		libcerror_error_set(
8635 		 error,
8636 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8637 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8638 		 "%s: invalid handle - invalid media values - missing chunk size.",
8639 		 function );
8640 
8641 		return( -1 );
8642 	}
8643 	chunk_index = internal_handle->io_handle->current_offset / internal_handle->media_values->chunk_size;
8644 
8645 	if( chunk_index >= (uint64_t) INT32_MAX )
8646 	{
8647 		libcerror_error_set(
8648 		 error,
8649 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8650 		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
8651 		 "%s: invalid chunk index value exceeds maximum.",
8652 		 function );
8653 
8654 		return( -1 );
8655 	}
8656 	if( libmfdata_list_get_data_range_by_index(
8657 	     internal_handle->chunk_table_list,
8658 	     (int) chunk_index,
8659 	     &file_io_pool_entry,
8660 	     &chunk_offset,
8661 	     &chunk_size,
8662 	     &chunk_flags,
8663 	     error ) != 1 )
8664 	{
8665 		libcerror_error_set(
8666 		 error,
8667 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8668 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8669 		 "%s: unable to retrieve data range of chunk: %" PRIu64 ".",
8670 		 function,
8671 		 chunk_index );
8672 
8673 		return( -1 );
8674 	}
8675 	if( file_io_pool_entry == -1 )
8676 	{
8677 		return( 0 );
8678 	}
8679 	if( libbfio_pool_get_handle(
8680 	     internal_handle->file_io_pool,
8681 	     file_io_pool_entry,
8682 	     file_io_handle,
8683 	     error ) != 1 )
8684 	{
8685 		libcerror_error_set(
8686 		 error,
8687 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8688 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8689 		 "%s: unable to retrieve file IO handle: %d from pool (chunk: %" PRIu64 ").",
8690 		 function,
8691 		 file_io_pool_entry,
8692 		 chunk_index );
8693 
8694 		return( -1 );
8695 	}
8696 	return( 1 );
8697 }
8698 
8699 /* Retrieves the maximum number of supported segment files to write
8700  * Returns 1 if successful or -1 on error
8701  */
libewf_internal_handle_get_write_maximum_number_of_segments(uint8_t ewf_format,uint16_t * maximum_number_of_segments,libcerror_error_t ** error)8702 int libewf_internal_handle_get_write_maximum_number_of_segments(
8703      uint8_t ewf_format,
8704      uint16_t *maximum_number_of_segments,
8705      libcerror_error_t **error )
8706 {
8707 	static char *function = "libewf_internal_handle_get_write_maximum_number_of_segments";
8708 
8709 	if( maximum_number_of_segments == NULL )
8710 	{
8711 		libcerror_error_set(
8712 		 error,
8713 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8714 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8715 		 "%s: invalid maximum number of segments.",
8716 		 function );
8717 
8718 		return( -1 );
8719 	}
8720 	if( ewf_format == EWF_FORMAT_S01 )
8721 	{
8722 		/* 'z' - 's' + 1 = 8
8723 		 * ( ( 8 * 26 * 26 ) + 99 ) = 5507
8724 		 */
8725 		*maximum_number_of_segments = (uint16_t) 5507;
8726 	}
8727 	else if( ewf_format == EWF_FORMAT_E01 )
8728 	{
8729 		/* 'Z' - 'E' + 1 = 22
8730 		 * ( ( 22 * 26 * 26 ) + 99 ) = 14971
8731 		 */
8732 		*maximum_number_of_segments = (uint16_t) 14971;
8733 	}
8734 	else
8735 	{
8736 		libcerror_error_set(
8737 		 error,
8738 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8739 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
8740 		 "%s: unsupported EWF format.",
8741 		 function );
8742 
8743 		return( -1 );
8744 	}
8745 	return( 1 );
8746 }
8747 
8748 /* Retrieves the media values
8749  * Returns 1 if successful or -1 on error
8750  */
libewf_internal_handle_get_media_values(libewf_internal_handle_t * internal_handle,size64_t * media_size,libcerror_error_t ** error)8751 int libewf_internal_handle_get_media_values(
8752      libewf_internal_handle_t *internal_handle,
8753      size64_t *media_size,
8754      libcerror_error_t **error )
8755 {
8756 	libewf_chunk_data_t *chunk_data = NULL;
8757 	static char *function           = "libewf_internal_handle_get_media_values";
8758 	size64_t chunks_data_size       = 0;
8759 	size64_t sector_data_size       = 0;
8760 	int chunk_index                 = 0;
8761 	int number_of_chunks            = 0;
8762 
8763 	if( internal_handle == NULL )
8764 	{
8765 		libcerror_error_set(
8766 		 error,
8767 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8768 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8769 		 "%s: invalid handle.",
8770 		 function );
8771 
8772 		return( -1 );
8773 	}
8774 	if( internal_handle->media_values == NULL )
8775 	{
8776 		libcerror_error_set(
8777 		 error,
8778 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8779 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8780 		 "%s: invalid handle - missing media values.",
8781 		 function );
8782 
8783 		return( -1 );
8784 	}
8785 	if( media_size == NULL )
8786 	{
8787 		libcerror_error_set(
8788 		 error,
8789 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8790 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8791 		 "%s: invalid media size.",
8792 		 function );
8793 
8794 		return( -1 );
8795 	}
8796 	sector_data_size  = internal_handle->media_values->number_of_sectors;
8797 	sector_data_size *= internal_handle->media_values->bytes_per_sector;
8798 
8799 	if( ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_READ ) != 0 )
8800 	 && ( ( internal_handle->io_handle->access_flags & LIBEWF_ACCESS_FLAG_RESUME ) == 0 ) )
8801 	{
8802 		if( libmfdata_list_get_number_of_elements(
8803 		     internal_handle->chunk_table_list,
8804 		     &number_of_chunks,
8805 		     error ) != 1 )
8806 		{
8807 			libcerror_error_set(
8808 			 error,
8809 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8810 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8811 			 "%s: unable to retrieve number of chunks in chunk table list.",
8812 			 function );
8813 
8814 			return( -1 );
8815 		}
8816 #if defined( HAVE_VERBOSE_OUTPUT )
8817 		if( libcnotify_verbose != 0 )
8818 		{
8819 			if( ( internal_handle->media_values->number_of_chunks != 0 )
8820 			 && ( internal_handle->media_values->number_of_chunks != (uint32_t) number_of_chunks ) )
8821 			{
8822 				libcnotify_printf(
8823 				 "%s: mismatch of number of chunks in volume: %" PRIu32 " and chunk table: %d\n",
8824 				 function,
8825 				 internal_handle->media_values->number_of_chunks,
8826 				 number_of_chunks );
8827 			}
8828 		}
8829 #endif
8830 		if( number_of_chunks > 0 )
8831 		{
8832 			chunk_index = number_of_chunks - 1;
8833 
8834 			/* This function will expand element groups
8835 			 */
8836 			if( libmfdata_list_get_element_value_by_index(
8837 			     internal_handle->chunk_table_list,
8838 			     internal_handle->file_io_pool,
8839 			     internal_handle->chunk_table_cache,
8840 			     chunk_index,
8841 			     (intptr_t **) &chunk_data,
8842 			     0,
8843 			     error ) != 1 )
8844 			{
8845 				libcerror_error_set(
8846 				 error,
8847 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8848 				 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
8849 				 "%s: unable to retrieve chunk data: %d.",
8850 				 function,
8851 				 chunk_index );
8852 
8853 				return( -1 );
8854 			}
8855 			if( chunk_data == NULL )
8856 			{
8857 				libcerror_error_set(
8858 				 error,
8859 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8860 				 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8861 				 "%s: missing chunk data: %d.",
8862 				 function,
8863 				 chunk_index );
8864 
8865 				return( -1 );
8866 			}
8867 			chunks_data_size = chunk_index
8868 			                 * internal_handle->media_values->sectors_per_chunk
8869 			                 * internal_handle->media_values->bytes_per_sector;
8870 
8871 			/* The only way to determine the size of the last compressed chunk
8872 			 * is to decompress it
8873 			 */
8874 			if( libewf_chunk_data_unpack(
8875 			     chunk_data,
8876 			     internal_handle->media_values->chunk_size,
8877 			     error ) != 1 )
8878 			{
8879 				libcerror_error_set(
8880 				 error,
8881 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8882 				 LIBCERROR_RUNTIME_ERROR_GENERIC,
8883 				 "%s: unable to unpack chunk data: %d.",
8884 				 function,
8885 				 chunk_index );
8886 
8887 				return( -1 );
8888 			}
8889 			if( chunk_data->is_corrupt == 0 )
8890 			{
8891 				chunks_data_size += chunk_data->data_size;
8892 			}
8893 			if( sector_data_size != chunks_data_size )
8894 			{
8895 #if defined( HAVE_VERBOSE_OUTPUT )
8896 				if( libcnotify_verbose != 0 )
8897 				{
8898 					libcnotify_printf(
8899 					 "%s: mismatch of media data size in volume: %" PRIu64 " and chunk table: %" PRIu64 "\n",
8900 					 function,
8901 					 sector_data_size,
8902 					 chunks_data_size );
8903 				}
8904 #endif
8905 				if( sector_data_size < chunks_data_size )
8906 				{
8907 					sector_data_size = chunks_data_size;
8908 				}
8909 			}
8910 		}
8911 	}
8912 	*media_size = sector_data_size;
8913 
8914 	return( 1 );
8915 }
8916 
8917 /* Sets the media values
8918  * Returns 1 if successful or -1 on error
8919  */
libewf_internal_handle_set_media_values(libewf_internal_handle_t * internal_handle,uint32_t sectors_per_chunk,uint32_t bytes_per_sector,size64_t media_size,libcerror_error_t ** error)8920 int libewf_internal_handle_set_media_values(
8921      libewf_internal_handle_t *internal_handle,
8922      uint32_t sectors_per_chunk,
8923      uint32_t bytes_per_sector,
8924      size64_t media_size,
8925      libcerror_error_t **error )
8926 {
8927 	static char *function            = "libewf_internal_handle_set_media_values";
8928 	size32_t chunk_size              = 0;
8929 	size64_t maximum_input_file_size = 0;
8930 	uint64_t number_of_chunks        = 0;
8931 	uint64_t number_of_sectors       = 0;
8932 
8933 	if( internal_handle == NULL )
8934 	{
8935 		libcerror_error_set(
8936 		 error,
8937 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8938 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
8939 		 "%s: invalid handle.",
8940 		 function );
8941 
8942 		return( -1 );
8943 	}
8944 	if( internal_handle->media_values == NULL )
8945 	{
8946 		libcerror_error_set(
8947 		 error,
8948 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
8949 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
8950 		 "%s: invalid handle - missing media values.",
8951 		 function );
8952 
8953 		return( -1 );
8954 	}
8955 	if( ( sectors_per_chunk == 0 )
8956 	 || ( sectors_per_chunk > (uint32_t) INT32_MAX ) )
8957 	{
8958 		libcerror_error_set(
8959 		 error,
8960 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8961 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
8962 		 "%s: invalid sectors per chunk.",
8963 		 function );
8964 
8965 		return( -1 );
8966 	}
8967 	if( ( bytes_per_sector == 0 )
8968 	 || ( bytes_per_sector > (uint32_t) INT32_MAX ) )
8969 	{
8970 		libcerror_error_set(
8971 		 error,
8972 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8973 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
8974 		 "%s: invalid bytes per sector.",
8975 		 function );
8976 
8977 		return( -1 );
8978 	}
8979 	if( media_size > (size64_t) INT64_MAX )
8980 	{
8981 		libcerror_error_set(
8982 		 error,
8983 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
8984 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
8985 		 "%s: invalid media size value exceeds maximum.",
8986 		 function );
8987 
8988 		return( -1 );
8989 	}
8990 	/* Determine the chunk size
8991 	 */
8992 	chunk_size = sectors_per_chunk * bytes_per_sector;
8993 
8994 	if( ( chunk_size == 0 )
8995 	 || ( chunk_size > (size32_t) INT32_MAX ) )
8996 	{
8997 		libcerror_error_set(
8998 		 error,
8999 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9000 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
9001 		 "%s: invalid chunk size.",
9002 		 function );
9003 
9004 		return( -1 );
9005 	}
9006 	/* Check if the input file size does not exceed the maximum possible input file size
9007 	 * for the chunk size
9008 	 */
9009 	maximum_input_file_size = (size64_t) chunk_size * (size64_t) UINT32_MAX;
9010 
9011 	if( media_size > maximum_input_file_size )
9012 	{
9013 		libcerror_error_set(
9014 		 error,
9015 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9016 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
9017 		 "%s: media size cannot be larger than size: %" PRIu64 " with a chunk size of: %" PRIu32 ".",
9018 		 function,
9019 		 maximum_input_file_size,
9020 		 chunk_size );
9021 
9022 		return( -1 );
9023 	}
9024 	internal_handle->media_values->sectors_per_chunk = sectors_per_chunk;
9025 	internal_handle->media_values->bytes_per_sector  = bytes_per_sector;
9026 	internal_handle->media_values->chunk_size        = chunk_size;
9027 	internal_handle->media_values->media_size        = media_size;
9028 
9029 	/* If a media size was provided
9030 	 */
9031 	if( media_size > 0 )
9032 	{
9033 		/* Determine the number of chunks to write
9034 		 */
9035 		number_of_chunks = (uint64_t) media_size / (uint64_t) chunk_size;
9036 
9037 		if( ( (uint64_t) media_size % (uint64_t) chunk_size ) != 0 )
9038 		{
9039 			number_of_chunks += 1;
9040 		}
9041 		if( number_of_chunks > (uint64_t) UINT32_MAX )
9042 		{
9043 			libcerror_error_set(
9044 			 error,
9045 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9046 			 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
9047 			 "%s: invalid number of chunks value exceeds maximum.",
9048 			 function );
9049 
9050 			return( -1 );
9051 		}
9052 		internal_handle->media_values->number_of_chunks = (uint32_t) number_of_chunks;
9053 
9054 		/* Determine the number of sectors to write
9055 		 */
9056 		number_of_sectors = (uint64_t) media_size / (uint64_t) bytes_per_sector;
9057 
9058 		if( number_of_sectors > (uint64_t) INT64_MAX )
9059 		{
9060 			libcerror_error_set(
9061 			 error,
9062 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9063 			 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
9064 			 "%s: invalid number of sectors value exceeds maximum.",
9065 			 function );
9066 
9067 			return( -1 );
9068 		}
9069 		internal_handle->media_values->number_of_sectors = number_of_sectors;
9070 	}
9071 	if( internal_handle->write_io_handle != NULL )
9072 	{
9073 		if( libewf_write_io_handle_set_compressed_zero_byte_empty_block(
9074 		     internal_handle->write_io_handle,
9075 		     internal_handle->io_handle,
9076 		     internal_handle->media_values,
9077 		     error ) != 1 )
9078 		{
9079 			libcerror_error_set(
9080 			 error,
9081 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9082 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
9083 			 "%s: unable to set compressed zero byte empty block in write IO handle.",
9084 			 function );
9085 
9086 			return( -1 );
9087 		}
9088 	}
9089 	return( 1 );
9090 }
9091 
9092 /* Sets internal values based on the EWF file format
9093  * Returns 1 if successful or -1 on error
9094  */
libewf_internal_handle_set_format(libewf_internal_handle_t * internal_handle,uint8_t format,libcerror_error_t ** error)9095 int libewf_internal_handle_set_format(
9096      libewf_internal_handle_t *internal_handle,
9097      uint8_t format,
9098      libcerror_error_t **error )
9099 {
9100 	static char *function = "libewf_internal_handle_set_format";
9101 
9102 	if( internal_handle == NULL )
9103 	{
9104 		libcerror_error_set(
9105 		 error,
9106 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9107 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9108 		 "%s: invalid handle.",
9109 		 function );
9110 
9111 		return( -1 );
9112 	}
9113 	if( internal_handle->io_handle == NULL )
9114 	{
9115 		libcerror_error_set(
9116 		 error,
9117 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9118 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9119 		 "%s: invalid handle - missing IO handle.",
9120 		 function );
9121 
9122 		return( -1 );
9123 	}
9124 	if( ( format != LIBEWF_FORMAT_ENCASE1 )
9125 	 && ( format != LIBEWF_FORMAT_ENCASE2 )
9126 	 && ( format != LIBEWF_FORMAT_ENCASE3 )
9127 	 && ( format != LIBEWF_FORMAT_ENCASE4 )
9128 	 && ( format != LIBEWF_FORMAT_ENCASE5 )
9129 	 && ( format != LIBEWF_FORMAT_ENCASE6 )
9130 	 && ( format != LIBEWF_FORMAT_ENCASE7 )
9131 	 && ( format != LIBEWF_FORMAT_LINEN5 )
9132 	 && ( format != LIBEWF_FORMAT_LINEN6 )
9133 	 && ( format != LIBEWF_FORMAT_LINEN7 )
9134 	 && ( format != LIBEWF_FORMAT_SMART )
9135 	 && ( format != LIBEWF_FORMAT_FTK )
9136 	 && ( format != LIBEWF_FORMAT_LOGICAL_ENCASE5 )
9137 	 && ( format != LIBEWF_FORMAT_LOGICAL_ENCASE6 )
9138 	 && ( format != LIBEWF_FORMAT_LOGICAL_ENCASE7 )
9139 	 && ( format != LIBEWF_FORMAT_EWF )
9140 	 && ( format != LIBEWF_FORMAT_EWFX ) )
9141 	{
9142 		libcerror_error_set(
9143 		 error,
9144 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9145 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
9146 		 "%s: unsupported format: %d.",
9147 		 function,
9148 	         format );
9149 
9150 		return( -1 );
9151 	}
9152 	internal_handle->io_handle->format = format;
9153 
9154 	if( ( format == LIBEWF_FORMAT_EWF )
9155 	 || ( format == LIBEWF_FORMAT_SMART ) )
9156 	{
9157 		internal_handle->io_handle->ewf_format = EWF_FORMAT_S01;
9158 	}
9159 	else if( format == LIBEWF_FORMAT_LVF )
9160 	{
9161 		internal_handle->io_handle->ewf_format = EWF_FORMAT_L01;
9162 	}
9163 	else
9164 	{
9165 		internal_handle->io_handle->ewf_format = EWF_FORMAT_E01;
9166 	}
9167 	if( internal_handle->write_io_handle != NULL )
9168 	{
9169 		if( format == LIBEWF_FORMAT_ENCASE6 )
9170 		{
9171 			internal_handle->write_io_handle->maximum_segment_file_size  = INT64_MAX;
9172 			internal_handle->write_io_handle->maximum_chunks_per_section = EWF_MAXIMUM_OFFSETS_IN_TABLE_ENCASE6;
9173 		}
9174 		else if( format == LIBEWF_FORMAT_EWFX )
9175 		{
9176 			internal_handle->write_io_handle->unrestrict_offset_table    = 1;
9177 			internal_handle->write_io_handle->maximum_segment_file_size  = INT32_MAX;
9178 			internal_handle->write_io_handle->maximum_chunks_per_section = INT32_MAX;
9179 		}
9180 		else
9181 		{
9182 			internal_handle->write_io_handle->maximum_segment_file_size  = INT32_MAX;
9183 			internal_handle->write_io_handle->maximum_chunks_per_section = EWF_MAXIMUM_OFFSETS_IN_TABLE;
9184 		}
9185 		/* Determine the maximum number of segments allowed to write
9186 		 */
9187 		if( libewf_internal_handle_get_write_maximum_number_of_segments(
9188 		     internal_handle->io_handle->ewf_format,
9189 		     &( internal_handle->write_io_handle->maximum_number_of_segments ),
9190 		     error ) != 1 )
9191 		{
9192 			libcerror_error_set(
9193 			 error,
9194 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9195 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
9196 			 "%s: unable to determine the maximum number of allowed segment files.",
9197 			 function );
9198 
9199 			return( -1 );
9200 		}
9201 	}
9202 	return( 1 );
9203 }
9204 
9205 /* Retrieves the root (single) file entry
9206  * Returns 1 if successful, 0 if no file entries are present or -1 on error
9207  */
libewf_handle_get_root_file_entry(libewf_handle_t * handle,libewf_file_entry_t ** root_file_entry,libcerror_error_t ** error)9208 int libewf_handle_get_root_file_entry(
9209      libewf_handle_t *handle,
9210      libewf_file_entry_t **root_file_entry,
9211      libcerror_error_t **error )
9212 {
9213 	libewf_internal_handle_t *internal_handle = NULL;
9214 	static char *function                     = "libewf_handle_get_root_file_entry";
9215 
9216 	if( handle == NULL )
9217 	{
9218 		libcerror_error_set(
9219 		 error,
9220 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9221 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9222 		 "%s: invalid handle.",
9223 		 function );
9224 
9225 		return( -1 );
9226 	}
9227 	internal_handle = (libewf_internal_handle_t *) handle;
9228 
9229 	if( internal_handle->single_files == NULL )
9230 	{
9231 		libcerror_error_set(
9232 		 error,
9233 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9234 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9235 		 "%s: invalid handle - missing single files.",
9236 		 function );
9237 
9238 		return( -1 );
9239 	}
9240 	if( root_file_entry == NULL )
9241 	{
9242 		libcerror_error_set(
9243 		 error,
9244 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9245 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9246 		 "%s: invalid root file entry.",
9247 		 function );
9248 
9249 		return( -1 );
9250 	}
9251 	if( *root_file_entry != NULL )
9252 	{
9253 		libcerror_error_set(
9254 		 error,
9255 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9256 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
9257 		 "%s: root file entry already set.",
9258 		 function );
9259 
9260 		return( -1 );
9261 	}
9262 	if( internal_handle->single_files->root_file_entry_node == NULL )
9263 	{
9264 		return( 0 );
9265 	}
9266 	if( libewf_file_entry_initialize(
9267 	     root_file_entry,
9268 	     internal_handle,
9269 	     internal_handle->single_files->root_file_entry_node,
9270 	     LIBEWF_ITEM_FLAGS_DEFAULT,
9271 	     error ) != 1 )
9272 	{
9273 		libcerror_error_set(
9274 		 error,
9275 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9276 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
9277 		 "%s: unable to create root file entry.",
9278 		 function );
9279 
9280 		return( -1 );
9281 	}
9282 	return( 1 );
9283 }
9284 
9285 /* Retrieves the (single) file entry for the specific UTF-8 encoded path
9286  * The path separator is the \ character
9287  * Returns 1 if successful, 0 if no such file entry or -1 on error
9288  */
libewf_file_get_file_entry_by_utf8_path(libewf_handle_t * handle,const uint8_t * utf8_string,size_t utf8_string_length,libewf_file_entry_t ** file_entry,libcerror_error_t ** error)9289 int libewf_file_get_file_entry_by_utf8_path(
9290      libewf_handle_t *handle,
9291      const uint8_t *utf8_string,
9292      size_t utf8_string_length,
9293      libewf_file_entry_t **file_entry,
9294      libcerror_error_t **error )
9295 {
9296 	libewf_internal_handle_t *internal_handle         = NULL;
9297 	libewf_single_file_entry_t *single_file_entry     = NULL;
9298 	libewf_single_file_entry_t *sub_single_file_entry = NULL;
9299 	libcdata_tree_node_t *node                        = NULL;
9300 	libcdata_tree_node_t *sub_node                    = NULL;
9301 	uint8_t *utf8_string_segment                      = NULL;
9302 	static char *function                             = "libewf_file_get_file_entry_by_utf8_path";
9303 	size_t utf8_string_index                          = 0;
9304 	size_t utf8_string_segment_length                 = 0;
9305 	int result                                        = 0;
9306 
9307 	if( handle == NULL )
9308 	{
9309 		libcerror_error_set(
9310 		 error,
9311 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9312 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9313 		 "%s: invalid handle.",
9314 		 function );
9315 
9316 		return( -1 );
9317 	}
9318 	internal_handle = (libewf_internal_handle_t *) handle;
9319 
9320 	if( internal_handle->single_files == NULL )
9321 	{
9322 		libcerror_error_set(
9323 		 error,
9324 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9325 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9326 		 "%s: invalid handle - missing single files.",
9327 		 function );
9328 
9329 		return( -1 );
9330 	}
9331 	if( utf8_string == NULL )
9332 	{
9333 		libcerror_error_set(
9334 		 error,
9335 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9336 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9337 		 "%s: invalid UTF-8 string.",
9338 		 function );
9339 
9340 		return( -1 );
9341 	}
9342 	if( utf8_string_length > (size_t) SSIZE_MAX )
9343 	{
9344 		libcerror_error_set(
9345 		 error,
9346 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9347 		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
9348 		 "%s: invalid UTF-8 string length value exceeds maximum.",
9349 		 function );
9350 
9351 		return( -1 );
9352 	}
9353 	if( file_entry == NULL )
9354 	{
9355 		libcerror_error_set(
9356 		 error,
9357 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9358 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9359 		 "%s: invalid file entry.",
9360 		 function );
9361 
9362 		return( -1 );
9363 	}
9364 	if( *file_entry != NULL )
9365 	{
9366 		libcerror_error_set(
9367 		 error,
9368 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9369 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
9370 		 "%s: file entry already set.",
9371 		 function );
9372 
9373 		return( -1 );
9374 	}
9375 	if( internal_handle->single_files->root_file_entry_node == NULL )
9376 	{
9377 		return( 0 );
9378 	}
9379 	if( libcdata_tree_node_get_value(
9380 	     internal_handle->single_files->root_file_entry_node,
9381 	     (intptr_t **) &single_file_entry,
9382 	     error ) != 1 )
9383 	{
9384 		libcerror_error_set(
9385 		 error,
9386 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9387 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
9388 		 "%s: unable to retrieve value from root file entry node.",
9389 		 function );
9390 
9391 		return( -1 );
9392 	}
9393 	if( single_file_entry == NULL )
9394 	{
9395 		libcerror_error_set(
9396 		 error,
9397 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9398 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9399 		 "%s: missing root file entry values.",
9400 		 function );
9401 
9402 		return( -1 );
9403 	}
9404 	if( utf8_string_length > 0 )
9405 	{
9406 		/* Ignore a leading separator
9407 		 */
9408 		if( utf8_string[ utf8_string_index ] == (uint8_t) LIBEWF_SEPARATOR )
9409 		{
9410 			utf8_string_index++;
9411 		}
9412 	}
9413 	node = internal_handle->single_files->root_file_entry_node;
9414 
9415 	if( ( utf8_string_length == 0 )
9416 	 || ( utf8_string_length == 1 ) )
9417 	{
9418 		result = 1;
9419 	}
9420 	else while( utf8_string_index < utf8_string_length )
9421 	{
9422 		utf8_string_segment        = (uint8_t *) &( utf8_string[ utf8_string_index ] );
9423 		utf8_string_segment_length = 0;
9424 
9425 		while( utf8_string_index < utf8_string_length )
9426 		{
9427 			if( ( utf8_string[ utf8_string_index ] == (uint8_t) LIBEWF_SEPARATOR )
9428 			 || ( utf8_string[ utf8_string_index ] == (uint8_t) 0 ) )
9429 			{
9430 				utf8_string_index++;
9431 
9432 				break;
9433 			}
9434 			utf8_string_index++;
9435 
9436 			utf8_string_segment_length++;
9437 		}
9438 		if( utf8_string_segment_length == 0 )
9439 		{
9440 			libcerror_error_set(
9441 			 error,
9442 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9443 			 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9444 			 "%s: missing sub file entry name.",
9445 			 function );
9446 
9447 			return( -1 );
9448 		}
9449 		result = libewf_single_file_tree_get_sub_node_by_utf8_name(
9450 			  node,
9451 			  utf8_string_segment,
9452 			  utf8_string_segment_length,
9453 			  &sub_node,
9454 			  &sub_single_file_entry,
9455 			  error );
9456 
9457 		if( result == -1 )
9458 		{
9459 			libcerror_error_set(
9460 			 error,
9461 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9462 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
9463 			 "%s: unable to retrieve single file entry sub node by name.",
9464 			 function );
9465 
9466 			return( -1 );
9467 		}
9468 		else if( result == 0 )
9469 		{
9470 			break;
9471 		}
9472 		node = sub_node;
9473 	}
9474 	if( result != 0 )
9475 	{
9476 		if( libewf_file_entry_initialize(
9477 		     file_entry,
9478 		     internal_handle,
9479 		     node,
9480 		     LIBEWF_ITEM_FLAGS_DEFAULT,
9481 		     error ) != 1 )
9482 		{
9483 			libcerror_error_set(
9484 			 error,
9485 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9486 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
9487 			 "%s: unable to create file entry.",
9488 			 function );
9489 
9490 			return( -1 );
9491 		}
9492 	}
9493 	return( result );
9494 }
9495 
9496 /* Retrieves the (single) file entry for the specific UTF-16 encoded path
9497  * The path separator is the \ character
9498  * Returns 1 if successful, 0 if no such file entry or -1 on error
9499  */
libewf_file_get_file_entry_by_utf16_path(libewf_handle_t * handle,const uint16_t * utf16_string,size_t utf16_string_length,libewf_file_entry_t ** file_entry,libcerror_error_t ** error)9500 int libewf_file_get_file_entry_by_utf16_path(
9501      libewf_handle_t *handle,
9502      const uint16_t *utf16_string,
9503      size_t utf16_string_length,
9504      libewf_file_entry_t **file_entry,
9505      libcerror_error_t **error )
9506 {
9507 	libewf_internal_handle_t *internal_handle         = NULL;
9508 	libewf_single_file_entry_t *single_file_entry     = NULL;
9509 	libewf_single_file_entry_t *sub_single_file_entry = NULL;
9510 	libcdata_tree_node_t *node                        = NULL;
9511 	libcdata_tree_node_t *sub_node                    = NULL;
9512 	uint16_t *utf16_string_segment                    = NULL;
9513 	static char *function                             = "libewf_file_get_file_entry_by_utf16_path";
9514 	size_t utf16_string_index                         = 0;
9515 	size_t utf16_string_segment_length                = 0;
9516 	int result                                        = 0;
9517 
9518 	if( handle == NULL )
9519 	{
9520 		libcerror_error_set(
9521 		 error,
9522 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9523 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9524 		 "%s: invalid handle.",
9525 		 function );
9526 
9527 		return( -1 );
9528 	}
9529 	internal_handle = (libewf_internal_handle_t *) handle;
9530 
9531 	if( internal_handle->single_files == NULL )
9532 	{
9533 		libcerror_error_set(
9534 		 error,
9535 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9536 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9537 		 "%s: invalid handle - missing single files.",
9538 		 function );
9539 
9540 		return( -1 );
9541 	}
9542 	if( utf16_string == NULL )
9543 	{
9544 		libcerror_error_set(
9545 		 error,
9546 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9547 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9548 		 "%s: invalid UTF-16 string.",
9549 		 function );
9550 
9551 		return( -1 );
9552 	}
9553 	if( utf16_string_length > (size_t) SSIZE_MAX )
9554 	{
9555 		libcerror_error_set(
9556 		 error,
9557 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9558 		 LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
9559 		 "%s: invalid UTF-16 string length value exceeds maximum.",
9560 		 function );
9561 
9562 		return( -1 );
9563 	}
9564 	if( file_entry == NULL )
9565 	{
9566 		libcerror_error_set(
9567 		 error,
9568 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
9569 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
9570 		 "%s: invalid file entry.",
9571 		 function );
9572 
9573 		return( -1 );
9574 	}
9575 	if( *file_entry != NULL )
9576 	{
9577 		libcerror_error_set(
9578 		 error,
9579 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9580 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
9581 		 "%s: file entry already set.",
9582 		 function );
9583 
9584 		return( -1 );
9585 	}
9586 	if( internal_handle->single_files->root_file_entry_node == NULL )
9587 	{
9588 		return( 0 );
9589 	}
9590 	if( libcdata_tree_node_get_value(
9591 	     internal_handle->single_files->root_file_entry_node,
9592 	     (intptr_t **) &single_file_entry,
9593 	     error ) != 1 )
9594 	{
9595 		libcerror_error_set(
9596 		 error,
9597 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9598 		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
9599 		 "%s: unable to retrieve value from root file entry node.",
9600 		 function );
9601 
9602 		return( -1 );
9603 	}
9604 	if( single_file_entry == NULL )
9605 	{
9606 		libcerror_error_set(
9607 		 error,
9608 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9609 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9610 		 "%s: missing root file entry values.",
9611 		 function );
9612 
9613 		return( -1 );
9614 	}
9615 	if( utf16_string_length > 0 )
9616 	{
9617 		/* Ignore a leading separator
9618 		 */
9619 		if( utf16_string[ utf16_string_index ] == (uint16_t) LIBEWF_SEPARATOR )
9620 		{
9621 			utf16_string_index++;
9622 		}
9623 	}
9624 	node = internal_handle->single_files->root_file_entry_node;
9625 
9626 	if( ( utf16_string_length == 0 )
9627 	 || ( utf16_string_length == 1 ) )
9628 	{
9629 		result = 1;
9630 	}
9631 	else while( utf16_string_index < utf16_string_length )
9632 	{
9633 		utf16_string_segment        = (uint16_t *) &( utf16_string[ utf16_string_index ] );
9634 		utf16_string_segment_length = 0;
9635 
9636 		while( utf16_string_index < utf16_string_length )
9637 		{
9638 			if( ( utf16_string[ utf16_string_index ] == (uint16_t) LIBEWF_SEPARATOR )
9639 			 || ( utf16_string[ utf16_string_index ] == (uint16_t) 0 ) )
9640 			{
9641 				utf16_string_index++;
9642 
9643 				break;
9644 			}
9645 			utf16_string_index++;
9646 
9647 			utf16_string_segment_length++;
9648 		}
9649 		if( utf16_string_segment_length == 0 )
9650 		{
9651 			libcerror_error_set(
9652 			 error,
9653 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9654 			 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
9655 			 "%s: missing sub file entry name.",
9656 			 function );
9657 
9658 			return( -1 );
9659 		}
9660 		result = libewf_single_file_tree_get_sub_node_by_utf16_name(
9661 			  node,
9662 			  utf16_string_segment,
9663 			  utf16_string_segment_length,
9664 			  &sub_node,
9665 			  &sub_single_file_entry,
9666 			  error );
9667 
9668 		if( result == -1 )
9669 		{
9670 			libcerror_error_set(
9671 			 error,
9672 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9673 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
9674 			 "%s: unable to retrieve single file entry sub node by name.",
9675 			 function );
9676 
9677 			return( -1 );
9678 		}
9679 		else if( result == 0 )
9680 		{
9681 			break;
9682 		}
9683 		node = sub_node;
9684 	}
9685 	if( result != 0 )
9686 	{
9687 		if( libewf_file_entry_initialize(
9688 		     file_entry,
9689 		     internal_handle,
9690 		     node,
9691 		     LIBEWF_ITEM_FLAGS_DEFAULT,
9692 		     error ) != 1 )
9693 		{
9694 			libcerror_error_set(
9695 			 error,
9696 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
9697 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
9698 			 "%s: unable to create file entry.",
9699 			 function );
9700 
9701 			return( -1 );
9702 		}
9703 	}
9704 	return( result );
9705 }
9706 
9707