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 §ion,
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 §ion,
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 §ion,
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 §ion,
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 §ion,
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