1 /*
2 * Support functions
3 *
4 * Copyright (C) 2008-2020, Joachim Metz <joachim.metz@gmail.com>
5 *
6 * Refer to AUTHORS for acknowledgements.
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #include <common.h>
23 #include <memory.h>
24 #include <narrow_string.h>
25 #include <system_string.h>
26 #include <types.h>
27 #include <wide_string.h>
28
29 #if defined( HAVE_SYS_STAT_H )
30 #include <sys/stat.h>
31 #endif
32
33 #if defined( HAVE_ERRNO_H )
34 #include <errno.h>
35 #endif
36
37 #if defined( HAVE_UNISTD_H )
38 #include <unistd.h>
39 #endif
40
41 #include "libcfile_definitions.h"
42 #include "libcfile_libcerror.h"
43 #include "libcfile_libclocale.h"
44 #include "libcfile_libuna.h"
45 #include "libcfile_support.h"
46
47 #if !defined( HAVE_LOCAL_LIBCFILE )
48
49 /* Returns the library version as a string
50 */
libcfile_get_version(void)51 const char *libcfile_get_version(
52 void )
53 {
54 return( (const char *) LIBCFILE_VERSION_STRING );
55 }
56
57 /* Retrieves the narrow system string codepage
58 * A value of 0 represents no codepage, UTF-8 encoding is used instead
59 * Returns 1 if successful or -1 on error
60 */
libcfile_get_codepage(int * codepage,libcerror_error_t ** error)61 int libcfile_get_codepage(
62 int *codepage,
63 libcerror_error_t **error )
64 {
65 static char *function = "libcfile_get_codepage";
66
67 if( libclocale_codepage_get(
68 codepage,
69 error ) != 1 )
70 {
71 libcerror_error_set(
72 error,
73 LIBCERROR_ERROR_DOMAIN_RUNTIME,
74 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
75 "%s: unable to retrieve codepage.",
76 function );
77
78 return( -1 );
79 }
80 return( 1 );
81 }
82
83 /* Sets the narrow system string codepage
84 * A value of 0 represents no codepage, UTF-8 encoding is used instead
85 * Returns 1 if successful or -1 on error
86 */
libcfile_set_codepage(int codepage,libcerror_error_t ** error)87 int libcfile_set_codepage(
88 int codepage,
89 libcerror_error_t **error )
90 {
91 static char *function = "libcfile_set_codepage";
92
93 if( libclocale_codepage_set(
94 codepage,
95 error ) != 1 )
96 {
97 libcerror_error_set(
98 error,
99 LIBCERROR_ERROR_DOMAIN_RUNTIME,
100 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
101 "%s: unable to set codepage.",
102 function );
103
104 return( -1 );
105 }
106 return( 1 );
107 }
108
109 #endif /* !defined( HAVE_LOCAL_LIBCFILE ) */
110
111 #if defined( WINAPI ) && ( WINVER <= 0x0500 )
112
113 /* Cross Windows safe version of GetFileAttributesA
114 * Returns the file attributs if successful or INVALID_FILE_ATTRIBUTES on error
115 */
libcfile_GetFileAttributesA(LPCSTR filename)116 DWORD libcfile_GetFileAttributesA(
117 LPCSTR filename )
118 {
119 FARPROC function = NULL;
120 HMODULE library_handle = NULL;
121 DWORD result = 0;
122
123 if( filename == NULL )
124 {
125 return( INVALID_FILE_ATTRIBUTES );
126 }
127 library_handle = LoadLibrary(
128 _SYSTEM_STRING( "kernel32.dll" ) );
129
130 if( library_handle == NULL )
131 {
132 return( INVALID_FILE_ATTRIBUTES );
133 }
134 function = GetProcAddress(
135 library_handle,
136 (LPCSTR) "GetFileAttributesA" );
137
138 if( function != NULL )
139 {
140 result = function(
141 filename );
142 }
143 /* This call should be after using the function
144 * in most cases kernel32.dll will still be available after free
145 */
146 if( FreeLibrary(
147 library_handle ) != TRUE )
148 {
149 result = INVALID_FILE_ATTRIBUTES;
150 }
151 return( result );
152 }
153
154 #endif /* defined( WINAPI ) && ( WINVER <= 0x0500 ) */
155
156 #if defined( WINAPI )
157
158 /* Determines if a file exists
159 * This function uses the WINAPI function for Windows XP (0x0501) or later,
160 * or tries to dynamically call the function for Windows 2000 (0x0500) or earlier
161 * Returns 1 if the file exists, 0 if not or -1 on error
162 */
libcfile_file_exists(const char * filename,libcerror_error_t ** error)163 int libcfile_file_exists(
164 const char *filename,
165 libcerror_error_t **error )
166 {
167 static char *function = "libcfile_file_exists";
168 int result = 1;
169 DWORD error_code = 0;
170 DWORD file_attributes = 0;
171
172 if( filename == NULL )
173 {
174 libcerror_error_set(
175 error,
176 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
177 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
178 "%s: invalid filename.",
179 function );
180
181 return( -1 );
182 }
183 #if ( WINVER <= 0x0500 )
184 file_attributes = libcfile_GetFileAttributesA(
185 (LPCSTR) filename );
186 #else
187 file_attributes = GetFileAttributesA(
188 (LPCSTR) filename );
189 #endif
190 if( file_attributes == INVALID_FILE_ATTRIBUTES )
191 {
192 error_code = GetLastError();
193
194 switch( error_code )
195 {
196 case ERROR_ACCESS_DENIED:
197 result = 1;
198
199 break;
200
201 case ERROR_FILE_NOT_FOUND:
202 case ERROR_PATH_NOT_FOUND:
203 result = 0;
204
205 break;
206
207 default:
208 libcerror_system_set_error(
209 error,
210 LIBCERROR_ERROR_DOMAIN_IO,
211 LIBCERROR_IO_ERROR_GENERIC,
212 error_code,
213 "%s: unable to determine attributes of file: %s.",
214 function,
215 filename );
216
217 return( -1 );
218 }
219 }
220 return( result );
221 }
222
223 #elif defined( HAVE_STAT )
224
225 /* Determines if a file exists
226 * This function uses the POSIX stat function or equivalent
227 * Returns 1 if the file exists, 0 if not or -1 on error
228 */
libcfile_file_exists(const char * filename,libcerror_error_t ** error)229 int libcfile_file_exists(
230 const char *filename,
231 libcerror_error_t **error )
232 {
233 struct stat file_statistics;
234
235 static char *function = "libcfile_file_exists";
236 int result = 0;
237
238 if( filename == NULL )
239 {
240 libcerror_error_set(
241 error,
242 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
243 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
244 "%s: invalid filename.",
245 function );
246
247 return( -1 );
248 }
249 if( memory_set(
250 &file_statistics,
251 0,
252 sizeof( struct stat ) ) == NULL )
253 {
254 libcerror_error_set(
255 error,
256 LIBCERROR_ERROR_DOMAIN_MEMORY,
257 LIBCERROR_MEMORY_ERROR_SET_FAILED,
258 "%s: unable to clear file statistics.",
259 function );
260
261 return( -1 );
262 }
263 result = stat(
264 filename,
265 &file_statistics );
266
267 if( result != 0 )
268 {
269 switch( errno )
270 {
271 case EACCES:
272 result = 1;
273
274 break;
275
276 case ENOENT:
277 result = 0;
278
279 break;
280
281 default:
282 libcerror_system_set_error(
283 error,
284 LIBCERROR_ERROR_DOMAIN_IO,
285 LIBCERROR_IO_ERROR_GENERIC,
286 errno,
287 "%s: unable to stat file: %" PRIs_SYSTEM ".",
288 function,
289 filename );
290
291 return( -1 );
292 }
293 }
294 else
295 {
296 result = 1;
297 }
298 return( result );
299 }
300
301 #else
302 #error Missing file exists function
303 #endif
304
305 #if defined( HAVE_WIDE_CHARACTER_TYPE )
306
307 #if defined( WINAPI ) && ( WINVER <= 0x0500 )
308
309 /* Cross Windows safe version of GetFileAttributesW
310 * Returns the file attributs if successful or INVALID_FILE_ATTRIBUTES on error
311 */
libcfile_GetFileAttributesW(LPCWSTR filename)312 DWORD libcfile_GetFileAttributesW(
313 LPCWSTR filename )
314 {
315 FARPROC function = NULL;
316 HMODULE library_handle = NULL;
317 DWORD result = 0;
318
319 if( filename == NULL )
320 {
321 return( INVALID_FILE_ATTRIBUTES );
322 }
323 library_handle = LoadLibrary(
324 _SYSTEM_STRING( "kernel32.dll" ) );
325
326 if( library_handle == NULL )
327 {
328 return( INVALID_FILE_ATTRIBUTES );
329 }
330 function = GetProcAddress(
331 library_handle,
332 (LPCSTR) "GetFileAttributesW" );
333
334 if( function != NULL )
335 {
336 result = function(
337 filename );
338 }
339 /* This call should be after using the function
340 * in most cases kernel32.dll will still be available after free
341 */
342 if( FreeLibrary(
343 library_handle ) != TRUE )
344 {
345 result = INVALID_FILE_ATTRIBUTES;
346 }
347 return( result );
348 }
349
350 #endif /* defined( WINAPI ) && ( WINVER <= 0x0500 ) */
351
352 #if defined( WINAPI )
353
354 /* Determines if a file exists using get file attibutes
355 * This function uses the WINAPI function for Windows XP (0x0501) or later,
356 * or tries to dynamically call the function for Windows 2000 (0x0500) or earlier
357 * Returns 1 if the file exists, 0 if not or -1 on error
358 */
libcfile_file_exists_wide(const wchar_t * filename,libcerror_error_t ** error)359 int libcfile_file_exists_wide(
360 const wchar_t *filename,
361 libcerror_error_t **error )
362 {
363 static char *function = "libcfile_file_exists_wide";
364 int result = 1;
365 DWORD error_code = 0;
366 DWORD file_attributes = 0;
367
368 if( filename == NULL )
369 {
370 libcerror_error_set(
371 error,
372 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
373 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
374 "%s: invalid filename.",
375 function );
376
377 return( -1 );
378 }
379 #if ( WINVER <= 0x0500 )
380 file_attributes = libcfile_GetFileAttributesW(
381 (LPCWSTR) filename );
382 #else
383 file_attributes = GetFileAttributesW(
384 (LPCWSTR) filename );
385 #endif
386 if( file_attributes == INVALID_FILE_ATTRIBUTES )
387 {
388 error_code = GetLastError();
389
390 switch( error_code )
391 {
392 case ERROR_ACCESS_DENIED:
393 result = 1;
394
395 break;
396
397 case ERROR_FILE_NOT_FOUND:
398 case ERROR_PATH_NOT_FOUND:
399 result = 0;
400
401 break;
402
403 default:
404 libcerror_system_set_error(
405 error,
406 LIBCERROR_ERROR_DOMAIN_IO,
407 LIBCERROR_IO_ERROR_GENERIC,
408 error_code,
409 "%s: unable to determine attributes of file: %ls.",
410 function,
411 filename );
412
413 return( -1 );
414 }
415 }
416 return( result );
417 }
418
419 #elif defined( HAVE_STAT )
420
421 /* Determines if a file exists
422 * This function uses the POSIX stat function or equivalent
423 * Returns 1 if the file exists, 0 if not or -1 on error
424 */
libcfile_file_exists_wide(const wchar_t * filename,libcerror_error_t ** error)425 int libcfile_file_exists_wide(
426 const wchar_t *filename,
427 libcerror_error_t **error )
428 {
429 struct stat file_statistics;
430
431 char *narrow_filename = NULL;
432 static char *function = "libcfile_file_exists_wide";
433 size_t narrow_filename_size = 0;
434 size_t filename_size = 0;
435 int result = 0;
436
437 if( filename == NULL )
438 {
439 libcerror_error_set(
440 error,
441 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
442 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
443 "%s: invalid filename.",
444 function );
445
446 return( -1 );
447 }
448 filename_size = 1 + wide_string_length(
449 filename );
450
451 /* Convert the filename to a narrow string
452 * if the platform has no wide character open function
453 */
454 if( libclocale_codepage == 0 )
455 {
456 #if SIZEOF_WCHAR_T == 4
457 result = libuna_utf8_string_size_from_utf32(
458 (libuna_utf32_character_t *) filename,
459 filename_size,
460 &narrow_filename_size,
461 error );
462 #elif SIZEOF_WCHAR_T == 2
463 result = libuna_utf8_string_size_from_utf16(
464 (libuna_utf16_character_t *) filename,
465 filename_size,
466 &narrow_filename_size,
467 error );
468 #else
469 #error Unsupported size of wchar_t
470 #endif /* SIZEOF_WCHAR_T */
471 }
472 else
473 {
474 #if SIZEOF_WCHAR_T == 4
475 result = libuna_byte_stream_size_from_utf32(
476 (libuna_utf32_character_t *) filename,
477 filename_size,
478 libclocale_codepage,
479 &narrow_filename_size,
480 error );
481 #elif SIZEOF_WCHAR_T == 2
482 result = libuna_byte_stream_size_from_utf16(
483 (libuna_utf16_character_t *) filename,
484 filename_size,
485 libclocale_codepage,
486 &narrow_filename_size,
487 error );
488 #else
489 #error Unsupported size of wchar_t
490 #endif /* SIZEOF_WCHAR_T */
491 }
492 if( result != 1 )
493 {
494 libcerror_error_set(
495 error,
496 LIBCERROR_ERROR_DOMAIN_CONVERSION,
497 LIBCERROR_CONVERSION_ERROR_GENERIC,
498 "%s: unable to determine narrow character filename size.",
499 function );
500
501 return( -1 );
502 }
503 narrow_filename = narrow_string_allocate(
504 narrow_filename_size );
505
506 if( narrow_filename == NULL )
507 {
508 libcerror_error_set(
509 error,
510 LIBCERROR_ERROR_DOMAIN_MEMORY,
511 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
512 "%s: unable to create narrow character filename.",
513 function );
514
515 return( -1 );
516 }
517 if( libclocale_codepage == 0 )
518 {
519 #if SIZEOF_WCHAR_T == 4
520 result = libuna_utf8_string_copy_from_utf32(
521 (libuna_utf8_character_t *) narrow_filename,
522 narrow_filename_size,
523 (libuna_utf32_character_t *) filename,
524 filename_size,
525 error );
526 #elif SIZEOF_WCHAR_T == 2
527 result = libuna_utf8_string_copy_from_utf16(
528 (libuna_utf8_character_t *) narrow_filename,
529 narrow_filename_size,
530 (libuna_utf16_character_t *) filename,
531 filename_size,
532 error );
533 #else
534 #error Unsupported size of wchar_t
535 #endif /* SIZEOF_WCHAR_T */
536 }
537 else
538 {
539 #if SIZEOF_WCHAR_T == 4
540 result = libuna_byte_stream_copy_from_utf32(
541 (uint8_t *) narrow_filename,
542 narrow_filename_size,
543 libclocale_codepage,
544 (libuna_utf32_character_t *) filename,
545 filename_size,
546 error );
547 #elif SIZEOF_WCHAR_T == 2
548 result = libuna_byte_stream_copy_from_utf16(
549 (uint8_t *) narrow_filename,
550 narrow_filename_size,
551 libclocale_codepage,
552 (libuna_utf16_character_t *) filename,
553 filename_size,
554 error );
555 #else
556 #error Unsupported size of wchar_t
557 #endif /* SIZEOF_WCHAR_T */
558 }
559 if( result != 1 )
560 {
561 libcerror_error_set(
562 error,
563 LIBCERROR_ERROR_DOMAIN_CONVERSION,
564 LIBCERROR_CONVERSION_ERROR_GENERIC,
565 "%s: unable to set narrow character filename.",
566 function );
567
568 memory_free(
569 narrow_filename );
570
571 return( -1 );
572 }
573 result = stat(
574 narrow_filename,
575 &file_statistics );
576
577 memory_free(
578 narrow_filename );
579
580 if( result != 0 )
581 {
582 switch( errno )
583 {
584 case EACCES:
585 result = 1;
586
587 break;
588
589 case ENOENT:
590 result = 0;
591
592 break;
593
594 default:
595 libcerror_system_set_error(
596 error,
597 LIBCERROR_ERROR_DOMAIN_IO,
598 LIBCERROR_IO_ERROR_GENERIC,
599 errno,
600 "%s: unable to stat file: %" PRIs_SYSTEM ".",
601 function,
602 filename );
603
604 return( -1 );
605 }
606 }
607 else
608 {
609 result = 1;
610 }
611 return( result );
612 }
613
614 #else
615 #error Missing file exists wide function
616 #endif
617
618 #endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
619
620 #if defined( WINAPI ) && ( WINVER <= 0x0500 )
621
622 /* Cross Windows safe version of DeleteFileA
623 * Returns TRUE if successful or FALSE on error
624 */
libcfile_DeleteFileA(LPCSTR filename)625 BOOL libcfile_DeleteFileA(
626 LPCSTR filename )
627 {
628 FARPROC function = NULL;
629 HMODULE library_handle = NULL;
630 BOOL result = FALSE;
631
632 if( filename == NULL )
633 {
634 return( FALSE );
635 }
636 library_handle = LoadLibrary(
637 _SYSTEM_STRING( "kernel32.dll" ) );
638
639 if( library_handle == NULL )
640 {
641 return( FALSE );
642 }
643 function = GetProcAddress(
644 library_handle,
645 (LPCSTR) "DeleteFileA" );
646
647 if( function != NULL )
648 {
649 result = function(
650 filename );
651 }
652 /* This call should be after using the function
653 * in most cases kernel32.dll will still be available after free
654 */
655 if( FreeLibrary(
656 library_handle ) != TRUE )
657 {
658 result = FALSE;
659 }
660 return( result );
661 }
662
663 #endif /* defined( WINAPI ) && ( WINVER <= 0x0500 ) */
664
665 /* Removes a file
666 * Returns 1 if successful or -1 on error
667 */
libcfile_file_remove(const char * filename,libcerror_error_t ** error)668 int libcfile_file_remove(
669 const char *filename,
670 libcerror_error_t **error )
671 {
672 static char *function = "libcfile_file_remove";
673 uint32_t error_code = 0;
674
675 if( libcfile_file_remove_with_error_code(
676 filename,
677 &error_code,
678 error ) != 1 )
679 {
680 libcerror_error_set(
681 error,
682 LIBCERROR_ERROR_DOMAIN_IO,
683 LIBCERROR_IO_ERROR_UNLINK_FAILED,
684 "%s: unable to remove file.",
685 function );
686
687 return( -1 );
688 }
689 return( 1 );
690 }
691
692 #if defined( WINAPI )
693
694 /* Removes a file
695 * This function uses the WINAPI function for Windows XP (0x0501) or later,
696 * or tries to dynamically call the function for Windows 2000 (0x0500) or earlier
697 * Returns 1 if successful or -1 on error
698 */
libcfile_file_remove_with_error_code(const char * filename,uint32_t * error_code,libcerror_error_t ** error)699 int libcfile_file_remove_with_error_code(
700 const char *filename,
701 uint32_t *error_code,
702 libcerror_error_t **error )
703 {
704 static char *function = "libcfile_file_remove_with_error_code";
705 BOOL result = FALSE;
706
707 if( filename == NULL )
708 {
709 libcerror_error_set(
710 error,
711 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
712 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
713 "%s: invalid filename.",
714 function );
715
716 return( -1 );
717 }
718 if( error_code == NULL )
719 {
720 libcerror_error_set(
721 error,
722 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
723 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
724 "%s: invalid error code.",
725 function );
726
727 return( -1 );
728 }
729 #if ( WINVER <= 0x0500 )
730 result = libcfile_DeleteFileA(
731 filename );
732 #else
733 result = DeleteFileA(
734 filename );
735 #endif
736 if( result == 0 )
737 {
738 *error_code = GetLastError();
739
740 libcerror_system_set_error(
741 error,
742 LIBCERROR_ERROR_DOMAIN_IO,
743 LIBCERROR_IO_ERROR_UNLINK_FAILED,
744 *error_code,
745 "%s: unable to remove file.",
746 function );
747
748 return( -1 );
749 }
750 return( 1 );
751 }
752
753 #elif defined( HAVE_UNLINK )
754
755 /* Removes a file
756 * This function uses the POSIX unlink function or equivalent
757 * Returns 1 if successful or -1 on error
758 */
libcfile_file_remove_with_error_code(const char * filename,uint32_t * error_code,libcerror_error_t ** error)759 int libcfile_file_remove_with_error_code(
760 const char *filename,
761 uint32_t *error_code,
762 libcerror_error_t **error )
763 {
764 static char *function = "libcfile_file_remove_with_error_code";
765
766 if( filename == NULL )
767 {
768 libcerror_error_set(
769 error,
770 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
771 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
772 "%s: invalid filename.",
773 function );
774
775 return( -1 );
776 }
777 if( error_code == NULL )
778 {
779 libcerror_error_set(
780 error,
781 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
782 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
783 "%s: invalid error code.",
784 function );
785
786 return( -1 );
787 }
788 if( unlink(
789 filename ) != 0 )
790 {
791 *error_code = (uint32_t) errno;
792
793 libcerror_system_set_error(
794 error,
795 LIBCERROR_ERROR_DOMAIN_IO,
796 LIBCERROR_IO_ERROR_UNLINK_FAILED,
797 *error_code,
798 "%s: unable to unlink file.",
799 function );
800
801 return( -1 );
802 }
803 return( 1 );
804 }
805
806 #else
807 #error Missing file remove function
808 #endif
809
810 #if defined( HAVE_WIDE_CHARACTER_TYPE )
811
812 #if defined( WINAPI ) && ( WINVER <= 0x0500 )
813
814 /* Cross Windows safe version of DeleteFileW
815 * Returns TRUE if successful or FALSE on error
816 */
libcfile_DeleteFileW(LPCWSTR filename)817 BOOL libcfile_DeleteFileW(
818 LPCWSTR filename )
819 {
820 FARPROC function = NULL;
821 HMODULE library_handle = NULL;
822 BOOL result = FALSE;
823
824 if( filename == NULL )
825 {
826 return( FALSE );
827 }
828 library_handle = LoadLibrary(
829 _SYSTEM_STRING( "kernel32.dll" ) );
830
831 if( library_handle == NULL )
832 {
833 return( FALSE );
834 }
835 function = GetProcAddress(
836 library_handle,
837 (LPCSTR) "DeleteFileW" );
838
839 if( function != NULL )
840 {
841 result = function(
842 filename );
843 }
844 /* This call should be after using the function
845 * in most cases kernel32.dll will still be available after free
846 */
847 if( FreeLibrary(
848 library_handle ) != TRUE )
849 {
850 result = FALSE;
851 }
852 return( result );
853 }
854
855 #endif /* defined( WINAPI ) && ( WINVER <= 0x0500 ) */
856
857 /* Removes a file
858 * Returns 1 if successful or -1 on error
859 */
libcfile_file_remove_wide(const wchar_t * filename,libcerror_error_t ** error)860 int libcfile_file_remove_wide(
861 const wchar_t *filename,
862 libcerror_error_t **error )
863 {
864 static char *function = "libcfile_file_remove_wide";
865 uint32_t error_code = 0;
866
867 if( libcfile_file_remove_wide_with_error_code(
868 filename,
869 &error_code,
870 error ) != 1 )
871 {
872 libcerror_error_set(
873 error,
874 LIBCERROR_ERROR_DOMAIN_IO,
875 LIBCERROR_IO_ERROR_UNLINK_FAILED,
876 "%s: unable to remove file.",
877 function );
878
879 return( -1 );
880 }
881 return( 1 );
882 }
883
884 #if defined( WINAPI )
885
886 /* Removes a file
887 * This function uses the WINAPI function for Windows XP (0x0501) or later,
888 * or tries to dynamically call the function for Windows 2000 (0x0500) or earlier
889 * Returns 1 if successful or -1 on error
890 */
libcfile_file_remove_wide_with_error_code(const wchar_t * filename,uint32_t * error_code,libcerror_error_t ** error)891 int libcfile_file_remove_wide_with_error_code(
892 const wchar_t *filename,
893 uint32_t *error_code,
894 libcerror_error_t **error )
895 {
896 static char *function = "libcfile_file_remove_wide_with_error_code";
897 BOOL result = FALSE;
898
899 if( filename == NULL )
900 {
901 libcerror_error_set(
902 error,
903 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
904 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
905 "%s: invalid filename.",
906 function );
907
908 return( -1 );
909 }
910 if( error_code == NULL )
911 {
912 libcerror_error_set(
913 error,
914 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
915 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
916 "%s: invalid error code.",
917 function );
918
919 return( -1 );
920 }
921 #if ( WINVER <= 0x0500 )
922 result = libcfile_DeleteFileW(
923 filename );
924 #else
925 result = DeleteFileW(
926 filename );
927 #endif
928 if( result == 0 )
929 {
930 *error_code = GetLastError();
931
932 libcerror_system_set_error(
933 error,
934 LIBCERROR_ERROR_DOMAIN_IO,
935 LIBCERROR_IO_ERROR_UNLINK_FAILED,
936 *error_code,
937 "%s: unable to remove file.",
938 function );
939
940 return( -1 );
941 }
942 return( 1 );
943 }
944
945 #elif defined( HAVE_UNLINK )
946
947 /* Removes a file
948 * This function uses the POSIX unlink function or equivalent
949 * Returns 1 if successful or -1 on error
950 */
libcfile_file_remove_wide_with_error_code(const wchar_t * filename,uint32_t * error_code,libcerror_error_t ** error)951 int libcfile_file_remove_wide_with_error_code(
952 const wchar_t *filename,
953 uint32_t *error_code,
954 libcerror_error_t **error )
955 {
956 char *narrow_filename = NULL;
957 static char *function = "libcfile_file_remove_wide_with_error_code";
958 size_t narrow_filename_size = 0;
959 size_t filename_size = 0;
960 int result = 0;
961
962 if( filename == NULL )
963 {
964 libcerror_error_set(
965 error,
966 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
967 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
968 "%s: invalid filename.",
969 function );
970
971 return( -1 );
972 }
973 if( error_code == NULL )
974 {
975 libcerror_error_set(
976 error,
977 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
978 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
979 "%s: invalid error code.",
980 function );
981
982 return( -1 );
983 }
984 filename_size = 1 + wide_string_length(
985 filename );
986
987 /* Convert the filename to a narrow string
988 * if the platform has no wide character open function
989 */
990 if( libclocale_codepage == 0 )
991 {
992 #if SIZEOF_WCHAR_T == 4
993 result = libuna_utf8_string_size_from_utf32(
994 (libuna_utf32_character_t *) filename,
995 filename_size,
996 &narrow_filename_size,
997 error );
998 #elif SIZEOF_WCHAR_T == 2
999 result = libuna_utf8_string_size_from_utf16(
1000 (libuna_utf16_character_t *) filename,
1001 filename_size,
1002 &narrow_filename_size,
1003 error );
1004 #else
1005 #error Unsupported size of wchar_t
1006 #endif /* SIZEOF_WCHAR_T */
1007 }
1008 else
1009 {
1010 #if SIZEOF_WCHAR_T == 4
1011 result = libuna_byte_stream_size_from_utf32(
1012 (libuna_utf32_character_t *) filename,
1013 filename_size,
1014 libclocale_codepage,
1015 &narrow_filename_size,
1016 error );
1017 #elif SIZEOF_WCHAR_T == 2
1018 result = libuna_byte_stream_size_from_utf16(
1019 (libuna_utf16_character_t *) filename,
1020 filename_size,
1021 libclocale_codepage,
1022 &narrow_filename_size,
1023 error );
1024 #else
1025 #error Unsupported size of wchar_t
1026 #endif /* SIZEOF_WCHAR_T */
1027 }
1028 if( result != 1 )
1029 {
1030 libcerror_error_set(
1031 error,
1032 LIBCERROR_ERROR_DOMAIN_CONVERSION,
1033 LIBCERROR_CONVERSION_ERROR_GENERIC,
1034 "%s: unable to determine narrow character filename size.",
1035 function );
1036
1037 goto on_error;
1038 }
1039 narrow_filename = narrow_string_allocate(
1040 narrow_filename_size );
1041
1042 if( narrow_filename == NULL )
1043 {
1044 libcerror_error_set(
1045 error,
1046 LIBCERROR_ERROR_DOMAIN_MEMORY,
1047 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1048 "%s: unable to create narrow character filename.",
1049 function );
1050
1051 goto on_error;
1052 }
1053 if( libclocale_codepage == 0 )
1054 {
1055 #if SIZEOF_WCHAR_T == 4
1056 result = libuna_utf8_string_copy_from_utf32(
1057 (libuna_utf8_character_t *) narrow_filename,
1058 narrow_filename_size,
1059 (libuna_utf32_character_t *) filename,
1060 filename_size,
1061 error );
1062 #elif SIZEOF_WCHAR_T == 2
1063 result = libuna_utf8_string_copy_from_utf16(
1064 (libuna_utf8_character_t *) narrow_filename,
1065 narrow_filename_size,
1066 (libuna_utf16_character_t *) filename,
1067 filename_size,
1068 error );
1069 #else
1070 #error Unsupported size of wchar_t
1071 #endif /* SIZEOF_WCHAR_T */
1072 }
1073 else
1074 {
1075 #if SIZEOF_WCHAR_T == 4
1076 result = libuna_byte_stream_copy_from_utf32(
1077 (uint8_t *) narrow_filename,
1078 narrow_filename_size,
1079 libclocale_codepage,
1080 (libuna_utf32_character_t *) filename,
1081 filename_size,
1082 error );
1083 #elif SIZEOF_WCHAR_T == 2
1084 result = libuna_byte_stream_copy_from_utf16(
1085 (uint8_t *) narrow_filename,
1086 narrow_filename_size,
1087 libclocale_codepage,
1088 (libuna_utf16_character_t *) filename,
1089 filename_size,
1090 error );
1091 #else
1092 #error Unsupported size of wchar_t
1093 #endif /* SIZEOF_WCHAR_T */
1094 }
1095 if( result != 1 )
1096 {
1097 libcerror_error_set(
1098 error,
1099 LIBCERROR_ERROR_DOMAIN_CONVERSION,
1100 LIBCERROR_CONVERSION_ERROR_GENERIC,
1101 "%s: unable to set narrow character filename.",
1102 function );
1103
1104 goto on_error;
1105 }
1106 if( unlink(
1107 narrow_filename ) != 0 )
1108 {
1109 *error_code = (uint32_t) errno;
1110
1111 libcerror_system_set_error(
1112 error,
1113 LIBCERROR_ERROR_DOMAIN_IO,
1114 LIBCERROR_IO_ERROR_UNLINK_FAILED,
1115 *error_code,
1116 "%s: unable to unlink file.",
1117 function );
1118
1119 goto on_error;
1120 }
1121 memory_free(
1122 narrow_filename );
1123
1124 return( 1 );
1125
1126 on_error:
1127 if( narrow_filename != NULL )
1128 {
1129 memory_free(
1130 narrow_filename );
1131 }
1132 return( -1 );
1133 }
1134
1135 #else
1136 #error Missing file remove wide function
1137 #endif
1138
1139 #endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
1140
1141