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