1 /*
2 * Support 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 <narrow_string.h>
24 #include <types.h>
25 #include <wide_string.h>
26
27 #include <stdio.h>
28
29 #include "libewf_codepage.h"
30 #include "libewf_definitions.h"
31 #include "libewf_error.h"
32 #include "libewf_filename.h"
33 #include "libewf_libbfio.h"
34 #include "libewf_libcerror.h"
35 #include "libewf_libclocale.h"
36 #include "libewf_libcnotify.h"
37 #include "libewf_segment_file.h"
38 #include "libewf_support.h"
39
40 #include "ewf_definitions.h"
41
42 #if !defined( HAVE_LOCAL_LIBEWF )
43
44 /* Returns the library version as a string
45 */
libewf_get_version(void)46 const char *libewf_get_version(
47 void )
48 {
49 return( (const char *) LIBEWF_VERSION_STRING );
50 }
51
52 /* Returns the access flags for reading
53 */
libewf_get_access_flags_read(void)54 int libewf_get_access_flags_read(
55 void )
56 {
57 return( (int) LIBEWF_ACCESS_FLAG_READ );
58 }
59
60 /* Returns the access flags for reading and writing
61 */
libewf_get_access_flags_read_write(void)62 int libewf_get_access_flags_read_write(
63 void )
64 {
65 return( (int) ( LIBEWF_ACCESS_FLAG_READ | LIBEWF_ACCESS_FLAG_WRITE ) );
66 }
67
68 /* Returns the access flags for writing
69 */
libewf_get_access_flags_write(void)70 int libewf_get_access_flags_write(
71 void )
72 {
73 return( (int) LIBEWF_ACCESS_FLAG_WRITE );
74 }
75
76 /* Returns the access flags for resume writing
77 */
libewf_get_access_flags_write_resume(void)78 int libewf_get_access_flags_write_resume(
79 void )
80 {
81 return( (int) LIBEWF_ACCESS_FLAG_WRITE | LIBEWF_ACCESS_FLAG_RESUME );
82 }
83
84 /* Retrieves the narrow system string codepage
85 * A value of 0 represents no codepage, UTF-8 encoding is used instead
86 * Returns 1 if successful or -1 on error
87 */
libewf_get_codepage(int * codepage,libcerror_error_t ** error)88 int libewf_get_codepage(
89 int *codepage,
90 libcerror_error_t **error )
91 {
92 static char *function = "libewf_get_codepage";
93
94 if( codepage == NULL )
95 {
96 libcerror_error_set(
97 error,
98 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
99 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
100 "%s: invalid codepage.",
101 function );
102
103 return( -1 );
104 }
105 *codepage = libclocale_codepage;
106
107 return( 1 );
108 }
109
110 /* Sets the narrow system string codepage
111 * A value of 0 represents no codepage, UTF-8 encoding is used instead
112 * Returns 1 if successful or -1 on error
113 */
libewf_set_codepage(int codepage,libcerror_error_t ** error)114 int libewf_set_codepage(
115 int codepage,
116 libcerror_error_t **error )
117 {
118 static char *function = "libewf_set_codepage";
119
120 if( ( codepage != LIBEWF_CODEPAGE_ASCII )
121 && ( codepage != LIBEWF_CODEPAGE_ISO_8859_1 )
122 && ( codepage != LIBEWF_CODEPAGE_ISO_8859_2 )
123 && ( codepage != LIBEWF_CODEPAGE_ISO_8859_3 )
124 && ( codepage != LIBEWF_CODEPAGE_ISO_8859_4 )
125 && ( codepage != LIBEWF_CODEPAGE_ISO_8859_5 )
126 && ( codepage != LIBEWF_CODEPAGE_ISO_8859_6 )
127 && ( codepage != LIBEWF_CODEPAGE_ISO_8859_7 )
128 && ( codepage != LIBEWF_CODEPAGE_ISO_8859_8 )
129 && ( codepage != LIBEWF_CODEPAGE_ISO_8859_9 )
130 && ( codepage != LIBEWF_CODEPAGE_ISO_8859_10 )
131 && ( codepage != LIBEWF_CODEPAGE_ISO_8859_11 )
132 && ( codepage != LIBEWF_CODEPAGE_ISO_8859_13 )
133 && ( codepage != LIBEWF_CODEPAGE_ISO_8859_14 )
134 && ( codepage != LIBEWF_CODEPAGE_ISO_8859_15 )
135 && ( codepage != LIBEWF_CODEPAGE_ISO_8859_16 )
136 && ( codepage != LIBEWF_CODEPAGE_KOI8_R )
137 && ( codepage != LIBEWF_CODEPAGE_KOI8_U )
138 && ( codepage != LIBEWF_CODEPAGE_WINDOWS_874 )
139 && ( codepage != LIBEWF_CODEPAGE_WINDOWS_932 )
140 && ( codepage != LIBEWF_CODEPAGE_WINDOWS_936 )
141 && ( codepage != LIBEWF_CODEPAGE_WINDOWS_1250 )
142 && ( codepage != LIBEWF_CODEPAGE_WINDOWS_1251 )
143 && ( codepage != LIBEWF_CODEPAGE_WINDOWS_1252 )
144 && ( codepage != LIBEWF_CODEPAGE_WINDOWS_1253 )
145 && ( codepage != LIBEWF_CODEPAGE_WINDOWS_1254 )
146 && ( codepage != LIBEWF_CODEPAGE_WINDOWS_1256 )
147 && ( codepage != LIBEWF_CODEPAGE_WINDOWS_1257 )
148 && ( codepage != LIBEWF_CODEPAGE_WINDOWS_1258 )
149 && ( codepage != 0 ) )
150 {
151 libcerror_error_set(
152 error,
153 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
154 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
155 "%s: unsupported codepage.",
156 function );
157
158 return( -1 );
159 }
160 libclocale_codepage = codepage;
161
162 return( 1 );
163 }
164
165 #endif /* !defined( HAVE_LOCAL_LIBEWF ) */
166
167 /* Determines if a file is an EWF file (check for the EWF file signature)
168 * Returns 1 if true, 0 if not or -1 on error
169 */
libewf_check_file_signature(const char * filename,libcerror_error_t ** error)170 int libewf_check_file_signature(
171 const char *filename,
172 libcerror_error_t **error )
173 {
174 libbfio_handle_t *file_io_handle = NULL;
175 static char *function = "libewf_check_file_signature";
176 size_t filename_length = 0;
177 int result = 0;
178
179 if( filename == NULL )
180 {
181 libcerror_error_set(
182 error,
183 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
184 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
185 "%s: invalid filename.",
186 function );
187
188 return( -1 );
189 }
190 filename_length = narrow_string_length(
191 filename );
192
193 if( filename_length == 0 )
194 {
195 libcerror_error_set(
196 error,
197 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
198 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
199 "%s: invalid filename.",
200 function );
201
202 goto on_error;
203 }
204 if( libbfio_file_initialize(
205 &file_io_handle,
206 error ) != 1 )
207 {
208 libcerror_error_set(
209 error,
210 LIBCERROR_ERROR_DOMAIN_RUNTIME,
211 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
212 "%s: unable to create file IO handle.",
213 function );
214
215 goto on_error;
216 }
217 if( libbfio_file_set_name(
218 file_io_handle,
219 filename,
220 filename_length,
221 error ) != 1 )
222 {
223 libcerror_error_set(
224 error,
225 LIBCERROR_ERROR_DOMAIN_RUNTIME,
226 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
227 "%s: unable to set filename in file IO handle.",
228 function );
229
230 goto on_error;
231 }
232 result = libewf_check_file_signature_file_io_handle(
233 file_io_handle,
234 error );
235
236 if( result == -1 )
237 {
238 libcerror_error_set(
239 error,
240 LIBCERROR_ERROR_DOMAIN_RUNTIME,
241 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
242 "%s: unable to check file signature using a file handle.",
243 function );
244
245 goto on_error;
246 }
247 if( libbfio_handle_free(
248 &file_io_handle,
249 error ) != 1 )
250 {
251 libcerror_error_set(
252 error,
253 LIBCERROR_ERROR_DOMAIN_RUNTIME,
254 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
255 "%s: unable to free file IO handle.",
256 function );
257
258 goto on_error;
259 }
260 return( result );
261
262 on_error:
263 if( file_io_handle != NULL )
264 {
265 libbfio_handle_free(
266 &file_io_handle,
267 NULL );
268 }
269 return( -1 );
270 }
271
272 /* Determines if a file is an EWF file (check for the EWF file signature)
273 * Returns 1 if true, 0 if not or -1 on error
274 */
275 #if defined( HAVE_WIDE_CHARACTER_TYPE )
libewf_check_file_signature_wide(const wchar_t * filename,libcerror_error_t ** error)276 int libewf_check_file_signature_wide(
277 const wchar_t *filename,
278 libcerror_error_t **error )
279 {
280 libbfio_handle_t *file_io_handle = NULL;
281 static char *function = "libewf_check_file_signature_wide";
282 size_t filename_length = 0;
283 int result = 0;
284
285 if( filename == NULL )
286 {
287 libcerror_error_set(
288 error,
289 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
290 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
291 "%s: invalid filename.",
292 function );
293
294 return( -1 );
295 }
296 filename_length = wide_string_length(
297 filename );
298
299 if( filename_length == 0 )
300 {
301 libcerror_error_set(
302 error,
303 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
304 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
305 "%s: invalid filename.",
306 function );
307
308 goto on_error;
309 }
310 if( libbfio_file_initialize(
311 &file_io_handle,
312 error ) != 1 )
313 {
314 libcerror_error_set(
315 error,
316 LIBCERROR_ERROR_DOMAIN_RUNTIME,
317 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
318 "%s: unable to create file IO handle.",
319 function );
320
321 goto on_error;
322 }
323 if( libbfio_file_set_name_wide(
324 file_io_handle,
325 filename,
326 filename_length,
327 error ) != 1 )
328 {
329 libcerror_error_set(
330 error,
331 LIBCERROR_ERROR_DOMAIN_RUNTIME,
332 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
333 "%s: unable to set filename in file IO handle.",
334 function );
335
336 goto on_error;
337 }
338 result = libewf_check_file_signature_file_io_handle(
339 file_io_handle,
340 error );
341
342 if( result == -1 )
343 {
344 libcerror_error_set(
345 error,
346 LIBCERROR_ERROR_DOMAIN_RUNTIME,
347 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
348 "%s: unable to check file signature using a file handle.",
349 function );
350
351 goto on_error;
352 }
353 if( libbfio_handle_free(
354 &file_io_handle,
355 error ) != 1 )
356 {
357 libcerror_error_set(
358 error,
359 LIBCERROR_ERROR_DOMAIN_RUNTIME,
360 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
361 "%s: unable to free file IO handle.",
362 function );
363
364 goto on_error;
365 }
366 return( result );
367
368 on_error:
369 if( file_io_handle != NULL )
370 {
371 libbfio_handle_free(
372 &file_io_handle,
373 NULL );
374 }
375 return( -1 );
376 }
377 #endif
378
379 /* Determines if a file is an EWF file (check for the EWF file signature) using a Basic File IO (bfio) handle
380 * Returns 1 if true, 0 if not or -1 on error
381 */
libewf_check_file_signature_file_io_handle(libbfio_handle_t * file_io_handle,libcerror_error_t ** error)382 int libewf_check_file_signature_file_io_handle(
383 libbfio_handle_t *file_io_handle,
384 libcerror_error_t **error )
385 {
386 uint8_t signature[ 8 ];
387
388 static char *function = "libewf_check_file_signature_file_io_handle";
389 ssize_t read_count = 0;
390 int file_io_handle_is_open = 0;
391
392 if( file_io_handle == NULL )
393 {
394 libcerror_error_set(
395 error,
396 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
397 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
398 "%s: invalid file IO handle.",
399 function );
400
401 return( -1 );
402 }
403 file_io_handle_is_open = libbfio_handle_is_open(
404 file_io_handle,
405 error );
406
407 if( file_io_handle_is_open == -1 )
408 {
409 libcerror_error_set(
410 error,
411 LIBCERROR_ERROR_DOMAIN_IO,
412 LIBCERROR_IO_ERROR_OPEN_FAILED,
413 "%s: unable to open file.",
414 function );
415
416 return( -1 );
417 }
418 else if( file_io_handle_is_open == 0 )
419 {
420 if( libbfio_handle_open(
421 file_io_handle,
422 LIBBFIO_OPEN_READ,
423 error ) != 1 )
424 {
425 libcerror_error_set(
426 error,
427 LIBCERROR_ERROR_DOMAIN_IO,
428 LIBCERROR_IO_ERROR_OPEN_FAILED,
429 "%s: unable to open file.",
430 function );
431
432 return( -1 );
433 }
434 }
435 read_count = libbfio_handle_read_buffer_at_offset(
436 file_io_handle,
437 signature,
438 8,
439 0,
440 error );
441
442 if( read_count != 8 )
443 {
444 libcerror_error_set(
445 error,
446 LIBCERROR_ERROR_DOMAIN_IO,
447 LIBCERROR_IO_ERROR_READ_FAILED,
448 "%s: unable to read signature at offset: 0 (0x00000000).",
449 function );
450
451 goto on_error;
452 }
453 if( file_io_handle_is_open == 0 )
454 {
455 if( libbfio_handle_close(
456 file_io_handle,
457 error ) != 0 )
458 {
459 libcerror_error_set(
460 error,
461 LIBCERROR_ERROR_DOMAIN_IO,
462 LIBCERROR_IO_ERROR_CLOSE_FAILED,
463 "%s: unable to close file.",
464 function );
465
466 goto on_error;
467 }
468 }
469 /* The number of EWF segment files will be the largest
470 */
471 if( memory_compare(
472 evf_file_signature,
473 signature,
474 8 ) == 0 )
475 {
476 return( 1 );
477 }
478 else if( memory_compare(
479 lvf_file_signature,
480 signature,
481 8 ) == 0 )
482 {
483 return( 1 );
484 }
485 else if( memory_compare(
486 dvf_file_signature,
487 signature,
488 8 ) == 0 )
489 {
490 return( 1 );
491 }
492 return( 0 );
493
494 on_error:
495 if( file_io_handle_is_open == 0 )
496 {
497 libbfio_handle_close(
498 file_io_handle,
499 NULL );
500 }
501 return( -1 );
502 }
503
504 /* Globs the segment files according to the EWF naming schema
505 * if format is known the filename should contain the base of the filename
506 * otherwise the function will try to determine the format based on the extension
507 * Returns 1 if successful or -1 on error
508 */
libewf_glob(const char * filename,size_t filename_length,uint8_t format,char ** filenames[],int * number_of_filenames,libcerror_error_t ** error)509 int libewf_glob(
510 const char *filename,
511 size_t filename_length,
512 uint8_t format,
513 char **filenames[],
514 int *number_of_filenames,
515 libcerror_error_t **error )
516 {
517 libbfio_handle_t *file_io_handle = NULL;
518 char *segment_filename = NULL;
519 void *reallocation = NULL;
520 static char *function = "libewf_glob";
521 size_t additional_length = 4;
522 size_t segment_filename_length = 0;
523 int result = 0;
524 uint8_t segment_file_type = 0;
525 uint8_t ewf_format = 0;
526
527 if( filename == NULL )
528 {
529 libcerror_error_set(
530 error,
531 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
532 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
533 "%s: invalid filename.",
534 function );
535
536 return( -1 );
537 }
538 if( ( filename_length == 0 )
539 || ( filename_length > (size_t) SSIZE_MAX ) )
540 {
541 libcerror_error_set(
542 error,
543 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
544 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
545 "%s: invalid filename length.",
546 function );
547
548 return( -1 );
549 }
550 if( ( format != LIBEWF_FORMAT_UNKNOWN )
551 && ( format != LIBEWF_FORMAT_ENCASE1 )
552 && ( format != LIBEWF_FORMAT_ENCASE2 )
553 && ( format != LIBEWF_FORMAT_ENCASE3 )
554 && ( format != LIBEWF_FORMAT_ENCASE4 )
555 && ( format != LIBEWF_FORMAT_ENCASE5 )
556 && ( format != LIBEWF_FORMAT_ENCASE6 )
557 && ( format != LIBEWF_FORMAT_LINEN5 )
558 && ( format != LIBEWF_FORMAT_LINEN6 )
559 && ( format != LIBEWF_FORMAT_SMART )
560 && ( format != LIBEWF_FORMAT_FTK )
561 && ( format != LIBEWF_FORMAT_LVF )
562 && ( format != LIBEWF_FORMAT_EWF )
563 && ( format != LIBEWF_FORMAT_EWFX ) )
564 {
565 libcerror_error_set(
566 error,
567 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
568 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
569 "%s: unsupported format.",
570 function );
571
572 return( -1 );
573 }
574 if( filenames == NULL )
575 {
576 libcerror_error_set(
577 error,
578 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
579 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
580 "%s: invalid filenames.",
581 function );
582
583 return( -1 );
584 }
585 if( number_of_filenames == NULL )
586 {
587 libcerror_error_set(
588 error,
589 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
590 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
591 "%s: invalid number of filenames.",
592 function );
593
594 return( -1 );
595 }
596 if( format == LIBEWF_FORMAT_UNKNOWN )
597 {
598 if( filename[ filename_length - 4 ] != (char) '.' )
599 {
600 libcerror_error_set(
601 error,
602 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
603 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
604 "%s: invalid filename - missing extension.",
605 function );
606
607 return( -1 );
608 }
609 additional_length = 0;
610
611 if( filename[ filename_length - 3 ] == (char) 'E' )
612 {
613 format = LIBEWF_FORMAT_ENCASE5;
614 }
615 else if( filename[ filename_length - 3 ] == (char) 'e' )
616 {
617 format = LIBEWF_FORMAT_EWF;
618 }
619 else if( filename[ filename_length - 3 ] == (char) 'L' )
620 {
621 format = LIBEWF_FORMAT_LVF;
622 }
623 else if( filename[ filename_length - 3 ] == (char) 's' )
624 {
625 format = LIBEWF_FORMAT_SMART;
626 }
627 else
628 {
629 libcerror_error_set(
630 error,
631 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
632 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
633 "%s: invalid filename - unsupported extension: %s.",
634 function,
635 &( filename[ filename_length - 4 ] ) );
636
637 return( -1 );
638 }
639 }
640 if( format == LIBEWF_FORMAT_LVF )
641 {
642 segment_file_type = LIBEWF_SEGMENT_FILE_TYPE_LWF;
643 ewf_format = EWF_FORMAT_L01;
644 }
645 else if( format == LIBEWF_FORMAT_SMART )
646 {
647 segment_file_type = LIBEWF_SEGMENT_FILE_TYPE_EWF;
648 ewf_format = EWF_FORMAT_S01;
649 }
650 else
651 {
652 segment_file_type = LIBEWF_SEGMENT_FILE_TYPE_EWF;
653 ewf_format = EWF_FORMAT_E01;
654 }
655 if( libbfio_file_initialize(
656 &file_io_handle,
657 error ) != 1 )
658 {
659 libcerror_error_set(
660 error,
661 LIBCERROR_ERROR_DOMAIN_RUNTIME,
662 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
663 "%s: unable to create file IO handle.",
664 function );
665
666 goto on_error;
667 }
668 *number_of_filenames = 0;
669
670 while( *number_of_filenames < (int) UINT16_MAX )
671 {
672 segment_filename_length = filename_length + additional_length;
673
674 segment_filename = (char * ) memory_allocate(
675 sizeof( char ) * ( segment_filename_length + 1 ) );
676
677 if( segment_filename == NULL )
678 {
679 libcerror_error_set(
680 error,
681 LIBCERROR_ERROR_DOMAIN_MEMORY,
682 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
683 "%s: unable to create segment filename.",
684 function );
685
686 goto on_error;
687 }
688 if( narrow_string_copy(
689 segment_filename,
690 filename,
691 filename_length ) == NULL )
692 {
693 libcerror_error_set(
694 error,
695 LIBCERROR_ERROR_DOMAIN_MEMORY,
696 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
697 "%s: unable to copy filename.",
698 function );
699
700 goto on_error;
701 }
702 if( additional_length > 0 )
703 {
704 segment_filename[ filename_length ] = (char) '.';
705 }
706 if( libewf_filename_set_extension(
707 &( segment_filename[ segment_filename_length - 3 ] ),
708 (uint16_t) ( *number_of_filenames + 1 ),
709 UINT16_MAX,
710 segment_file_type,
711 format,
712 ewf_format,
713 error ) != 1 )
714 {
715 libcerror_error_set(
716 error,
717 LIBCERROR_ERROR_DOMAIN_RUNTIME,
718 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
719 "%s: unable to set extension.",
720 function );
721
722 goto on_error;
723 }
724 segment_filename[ segment_filename_length ] = 0;
725
726 if( libbfio_file_set_name(
727 file_io_handle,
728 segment_filename,
729 segment_filename_length,
730 error ) != 1 )
731 {
732 libcerror_error_set(
733 error,
734 LIBCERROR_ERROR_DOMAIN_RUNTIME,
735 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
736 "%s: unable to set name in file IO handle.",
737 function );
738
739 goto on_error;
740 }
741 result = libbfio_handle_exists(
742 file_io_handle,
743 error );
744
745 if( result == -1 )
746 {
747 libcerror_error_set(
748 error,
749 LIBCERROR_ERROR_DOMAIN_IO,
750 LIBCERROR_IO_ERROR_GENERIC,
751 "%s: unable to test if file exists.",
752 function );
753
754 goto on_error;
755 }
756 else if( result == 0 )
757 {
758 memory_free(
759 segment_filename );
760
761 break;
762 }
763 *number_of_filenames += 1;
764
765 reallocation = memory_reallocate(
766 *filenames,
767 sizeof( char * ) * *number_of_filenames );
768
769 if( reallocation == NULL )
770 {
771 libcerror_error_set(
772 error,
773 LIBCERROR_ERROR_DOMAIN_MEMORY,
774 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
775 "%s: unable to resize filenames.",
776 function );
777
778 goto on_error;
779 }
780 *filenames = (char **) reallocation;
781
782 ( *filenames )[ *number_of_filenames - 1 ] = segment_filename;
783 }
784 if( libbfio_handle_free(
785 &file_io_handle,
786 error ) != 1 )
787 {
788 libcerror_error_set(
789 error,
790 LIBCERROR_ERROR_DOMAIN_RUNTIME,
791 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
792 "%s: unable to free file IO handle.",
793 function );
794
795 goto on_error;
796 }
797 return( 1 );
798
799 on_error:
800 if( segment_filename != NULL )
801 {
802 memory_free(
803 segment_filename );
804 }
805 if( file_io_handle != NULL )
806 {
807 libbfio_handle_free(
808 &file_io_handle,
809 NULL );
810 }
811 return( -1 );
812 }
813
814 /* Frees the globbed filenames
815 * Returns 1 if successful or -1 on error
816 */
libewf_glob_free(char * filenames[],int number_of_filenames,libcerror_error_t ** error)817 int libewf_glob_free(
818 char *filenames[],
819 int number_of_filenames,
820 libcerror_error_t **error )
821 {
822 static char *function = "libewf_glob_free";
823 int filename_iterator = 0;
824
825 if( filenames == NULL )
826 {
827 libcerror_error_set(
828 error,
829 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
830 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
831 "%s: invalid filenames.",
832 function );
833
834 return( -1 );
835 }
836 if( number_of_filenames < 0 )
837 {
838 libcerror_error_set(
839 error,
840 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
841 LIBCERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO,
842 "%s: invalid number of filenames value less than zero.",
843 function );
844
845 return( -1 );
846 }
847 for( filename_iterator = 0;
848 filename_iterator < number_of_filenames;
849 filename_iterator++ )
850 {
851 memory_free(
852 filenames[ filename_iterator ] );
853 }
854 memory_free(
855 filenames );
856
857 return( 1 );
858 }
859
860 #if defined( HAVE_WIDE_CHARACTER_TYPE )
861
862 /* Globs the segment files according to the EWF naming schema
863 * if format is known the filename should contain the base of the filename
864 * otherwise the function will try to determine the format based on the extension
865 * Returns 1 if successful or -1 on error
866 */
libewf_glob_wide(const wchar_t * filename,size_t filename_length,uint8_t format,wchar_t ** filenames[],int * number_of_filenames,libcerror_error_t ** error)867 int libewf_glob_wide(
868 const wchar_t *filename,
869 size_t filename_length,
870 uint8_t format,
871 wchar_t **filenames[],
872 int *number_of_filenames,
873 libcerror_error_t **error )
874 {
875 libbfio_handle_t *file_io_handle = NULL;
876 wchar_t *segment_filename = NULL;
877 void *reallocation = NULL;
878 static char *function = "libewf_glob_wide";
879 size_t additional_length = 4;
880 size_t segment_filename_length = 0;
881 int result = 0;
882 uint8_t segment_file_type = 0;
883 uint8_t ewf_format = 0;
884
885 if( filename == NULL )
886 {
887 libcerror_error_set(
888 error,
889 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
890 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
891 "%s: invalid filename.",
892 function );
893
894 return( -1 );
895 }
896 if( ( filename_length == 0 )
897 || ( filename_length > (size_t) SSIZE_MAX ) )
898 {
899 libcerror_error_set(
900 error,
901 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
902 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
903 "%s: invalid filename length.",
904 function );
905
906 return( -1 );
907 }
908 if( ( format != LIBEWF_FORMAT_UNKNOWN )
909 && ( format != LIBEWF_FORMAT_ENCASE1 )
910 && ( format != LIBEWF_FORMAT_ENCASE2 )
911 && ( format != LIBEWF_FORMAT_ENCASE3 )
912 && ( format != LIBEWF_FORMAT_ENCASE4 )
913 && ( format != LIBEWF_FORMAT_ENCASE5 )
914 && ( format != LIBEWF_FORMAT_ENCASE6 )
915 && ( format != LIBEWF_FORMAT_LINEN5 )
916 && ( format != LIBEWF_FORMAT_LINEN6 )
917 && ( format != LIBEWF_FORMAT_SMART )
918 && ( format != LIBEWF_FORMAT_FTK )
919 && ( format != LIBEWF_FORMAT_LVF )
920 && ( format != LIBEWF_FORMAT_EWF )
921 && ( format != LIBEWF_FORMAT_EWFX ) )
922 {
923 libcerror_error_set(
924 error,
925 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
926 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
927 "%s: unsupported format.",
928 function );
929
930 return( -1 );
931 }
932 if( filenames == NULL )
933 {
934 libcerror_error_set(
935 error,
936 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
937 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
938 "%s: invalid filenames.",
939 function );
940
941 return( -1 );
942 }
943 if( number_of_filenames == NULL )
944 {
945 libcerror_error_set(
946 error,
947 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
948 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
949 "%s: invalid number of filenames.",
950 function );
951
952 return( -1 );
953 }
954 if( format == LIBEWF_FORMAT_UNKNOWN )
955 {
956 if( filename[ filename_length - 4 ] != (wchar_t) '.' )
957 {
958 libcerror_error_set(
959 error,
960 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
961 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
962 "%s: invalid filename - missing extension.",
963 function );
964
965 return( -1 );
966 }
967 additional_length = 0;
968
969 if( filename[ filename_length - 3 ] == (wchar_t) 'E' )
970 {
971 format = LIBEWF_FORMAT_ENCASE5;
972 }
973 else if( filename[ filename_length - 3 ] == (wchar_t) 'e' )
974 {
975 format = LIBEWF_FORMAT_EWF;
976 }
977 else if( filename[ filename_length - 3 ] == (wchar_t) 'L' )
978 {
979 format = LIBEWF_FORMAT_LVF;
980 }
981 else if( filename[ filename_length - 3 ] == (wchar_t) 's' )
982 {
983 format = LIBEWF_FORMAT_SMART;
984 }
985 else
986 {
987 libcerror_error_set(
988 error,
989 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
990 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
991 "%s: invalid filename - unsupported extension: %s.",
992 function,
993 &( filename[ filename_length - 4 ] ) );
994
995 return( -1 );
996 }
997 }
998 if( format == LIBEWF_FORMAT_LVF )
999 {
1000 segment_file_type = LIBEWF_SEGMENT_FILE_TYPE_LWF;
1001 ewf_format = EWF_FORMAT_L01;
1002 }
1003 else if( format == LIBEWF_FORMAT_SMART )
1004 {
1005 segment_file_type = LIBEWF_SEGMENT_FILE_TYPE_EWF;
1006 ewf_format = EWF_FORMAT_S01;
1007 }
1008 else
1009 {
1010 segment_file_type = LIBEWF_SEGMENT_FILE_TYPE_EWF;
1011 ewf_format = EWF_FORMAT_E01;
1012 }
1013 if( libbfio_file_initialize(
1014 &file_io_handle,
1015 error ) != 1 )
1016 {
1017 libcerror_error_set(
1018 error,
1019 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1020 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1021 "%s: unable to create file IO handle.",
1022 function );
1023
1024 goto on_error;
1025 }
1026 *number_of_filenames = 0;
1027
1028 while( *number_of_filenames < (int) UINT16_MAX )
1029 {
1030 segment_filename_length = filename_length + additional_length;
1031
1032 segment_filename = (wchar_t *) memory_allocate(
1033 sizeof( wchar_t ) * ( segment_filename_length + 1 ) );
1034
1035 if( segment_filename == NULL )
1036 {
1037 libcerror_error_set(
1038 error,
1039 LIBCERROR_ERROR_DOMAIN_MEMORY,
1040 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1041 "%s: unable to create segment filename.",
1042 function );
1043
1044 goto on_error;
1045 }
1046 if( wide_string_copy(
1047 segment_filename,
1048 filename,
1049 filename_length ) == NULL )
1050 {
1051 libcerror_error_set(
1052 error,
1053 LIBCERROR_ERROR_DOMAIN_MEMORY,
1054 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1055 "%s: unable to copy filename.",
1056 function );
1057
1058 goto on_error;
1059 }
1060 if( additional_length > 0 )
1061 {
1062 segment_filename[ filename_length ] = (wchar_t) '.';
1063 }
1064 if( libewf_filename_set_extension_wide(
1065 &( segment_filename[ segment_filename_length - 3 ] ),
1066 (uint16_t) ( *number_of_filenames + 1 ),
1067 UINT16_MAX,
1068 segment_file_type,
1069 format,
1070 ewf_format,
1071 error ) != 1 )
1072 {
1073 libcerror_error_set(
1074 error,
1075 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1076 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1077 "%s: unable to set extension.",
1078 function );
1079
1080 goto on_error;
1081 }
1082 segment_filename[ segment_filename_length ] = 0;
1083
1084 if( libbfio_file_set_name_wide(
1085 file_io_handle,
1086 segment_filename,
1087 segment_filename_length,
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 name in file IO handle.",
1095 function );
1096
1097 goto on_error;
1098 }
1099 result = libbfio_handle_exists(
1100 file_io_handle,
1101 error );
1102
1103 if( result == -1 )
1104 {
1105 libcerror_error_set(
1106 error,
1107 LIBCERROR_ERROR_DOMAIN_IO,
1108 LIBCERROR_IO_ERROR_GENERIC,
1109 "%s: unable to test if file exists.",
1110 function );
1111
1112 goto on_error;
1113 }
1114 else if( result == 0 )
1115 {
1116 memory_free(
1117 segment_filename );
1118
1119 break;
1120 }
1121 *number_of_filenames += 1;
1122
1123 reallocation = memory_reallocate(
1124 *filenames,
1125 sizeof( wchar_t * ) * *number_of_filenames );
1126
1127 if( reallocation == NULL )
1128 {
1129 libcerror_error_set(
1130 error,
1131 LIBCERROR_ERROR_DOMAIN_MEMORY,
1132 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1133 "%s: unable to resize filenames.",
1134 function );
1135
1136 goto on_error;
1137 }
1138 *filenames = (wchar_t **) reallocation;
1139
1140 ( *filenames )[ *number_of_filenames - 1 ] = segment_filename;
1141 }
1142 if( libbfio_handle_free(
1143 &file_io_handle,
1144 error ) != 1 )
1145 {
1146 libcerror_error_set(
1147 error,
1148 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1149 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1150 "%s: unable to free file IO handle.",
1151 function );
1152
1153 goto on_error;
1154 }
1155 return( 1 );
1156
1157 on_error:
1158 if( segment_filename != NULL )
1159 {
1160 memory_free(
1161 segment_filename );
1162 }
1163 if( file_io_handle != NULL )
1164 {
1165 libbfio_handle_free(
1166 &file_io_handle,
1167 NULL );
1168 }
1169 return( -1 );
1170 }
1171
1172 /* Frees the globbed wide filenames
1173 * Returns 1 if successful or -1 on error
1174 */
libewf_glob_wide_free(wchar_t * filenames[],int number_of_filenames,libcerror_error_t ** error)1175 int libewf_glob_wide_free(
1176 wchar_t *filenames[],
1177 int number_of_filenames,
1178 libcerror_error_t **error )
1179 {
1180 static char *function = "libewf_glob_wide_free";
1181 int filename_iterator = 0;
1182
1183 if( filenames == NULL )
1184 {
1185 libcerror_error_set(
1186 error,
1187 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1188 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1189 "%s: invalid filenames.",
1190 function );
1191
1192 return( -1 );
1193 }
1194 if( number_of_filenames < 0 )
1195 {
1196 libcerror_error_set(
1197 error,
1198 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1199 LIBCERROR_ARGUMENT_ERROR_VALUE_LESS_THAN_ZERO,
1200 "%s: invalid number of filenames value less than zero.",
1201 function );
1202
1203 return( -1 );
1204 }
1205 for( filename_iterator = 0;
1206 filename_iterator < number_of_filenames;
1207 filename_iterator++ )
1208 {
1209 memory_free(
1210 filenames[ filename_iterator ] );
1211 }
1212 memory_free(
1213 filenames );
1214
1215 return( 1 );
1216 }
1217
1218 #endif
1219
1220