1 /*
2  * System string 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 #include "libcfile_libcerror.h"
30 #include "libcfile_libclocale.h"
31 #include "libcfile_libuna.h"
32 #include "libcfile_system_string.h"
33 
34 #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) && SIZEOF_WCHAR_T != 2 && SIZEOF_WCHAR_T != 4
35 #error Unsupported size of wchar_t
36 #endif
37 
38 /* Determines the size of a narrow string from a system string
39  * Returns 1 if successful or -1 on error
40  */
libcfile_system_string_size_to_narrow_string(const system_character_t * system_string,size_t system_string_size,size_t * narrow_string_size,libcerror_error_t ** error)41 int libcfile_system_string_size_to_narrow_string(
42      const system_character_t *system_string,
43      size_t system_string_size,
44      size_t *narrow_string_size,
45      libcerror_error_t **error )
46 {
47 	static char *function = "libcfile_system_string_size_to_narrow_string";
48 
49 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
50 	int result            = 0;
51 #endif
52 
53 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
54 	if( libclocale_codepage == 0 )
55 	{
56 #if SIZEOF_WCHAR_T == 4
57 		result = libuna_utf8_string_size_from_utf32(
58 		          (libuna_utf32_character_t *) system_string,
59 		          system_string_size,
60 		          narrow_string_size,
61 		          error );
62 #elif SIZEOF_WCHAR_T == 2
63 		result = libuna_utf8_string_size_from_utf16(
64 		          (libuna_utf16_character_t *) system_string,
65 		          system_string_size,
66 		          narrow_string_size,
67 		          error );
68 #endif /* SIZEOF_WCHAR_T */
69 	}
70 	else
71 	{
72 #if SIZEOF_WCHAR_T == 4
73 		result = libuna_byte_stream_size_from_utf32(
74 		          (libuna_utf32_character_t *) system_string,
75 		          system_string_size,
76 		          libclocale_codepage,
77 		          narrow_string_size,
78 		          error );
79 #elif SIZEOF_WCHAR_T == 2
80 		result = libuna_byte_stream_size_from_utf16(
81 		          (libuna_utf16_character_t *) system_string,
82 		          system_string_size,
83 		          libclocale_codepage,
84 		          narrow_string_size,
85 		          error );
86 #endif /* SIZEOF_WCHAR_T */
87 	}
88 	if( result != 1 )
89 	{
90 		libcerror_error_set(
91 		 error,
92 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
93 		 LIBCERROR_CONVERSION_ERROR_GENERIC,
94 		 "%s: unable to determine narrow string size.",
95 		 function );
96 
97 		return( -1 );
98 	}
99 #else
100 	if( system_string == NULL )
101 	{
102 		libcerror_error_set(
103 		 error,
104 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
105 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
106 		 "%s: invalid system string.",
107 		 function );
108 
109 		return( -1 );
110 	}
111 	if( system_string_size > (size_t) SSIZE_MAX )
112 	{
113 		libcerror_error_set(
114 		 error,
115 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
116 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
117 		 "%s: invalid system string size value exceeds maximum.",
118 		 function );
119 
120 		return( -1 );
121 	}
122 	if( narrow_string_size == NULL )
123 	{
124 		libcerror_error_set(
125 		 error,
126 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
127 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
128 		 "%s: invalid narrow string size.",
129 		 function );
130 
131 		return( -1 );
132 	}
133 	*narrow_string_size = system_string_size;
134 
135 #endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
136 
137 	return( 1 );
138 }
139 
140 /* Copies a system string to a narrow string
141  * Returns 1 if successful or -1 on error
142  */
libcfile_system_string_copy_to_narrow_string(const system_character_t * system_string,size_t system_string_size,char * narrow_string,size_t narrow_string_size,libcerror_error_t ** error)143 int libcfile_system_string_copy_to_narrow_string(
144      const system_character_t *system_string,
145      size_t system_string_size,
146      char *narrow_string,
147      size_t narrow_string_size,
148      libcerror_error_t **error )
149 {
150 	static char *function = "libcfile_system_string_copy_to_narrow_string";
151 
152 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
153 	int result            = 0;
154 #endif
155 
156 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
157 	if( libclocale_codepage == 0 )
158 	{
159 #if SIZEOF_WCHAR_T == 4
160 		result = libuna_utf8_string_copy_from_utf32(
161 		          (libuna_utf8_character_t *) narrow_string,
162 		          narrow_string_size,
163 		          (libuna_utf32_character_t *) system_string,
164 		          system_string_size,
165 		          error );
166 #elif SIZEOF_WCHAR_T == 2
167 		result = libuna_utf8_string_copy_from_utf16(
168 		          (libuna_utf8_character_t *) narrow_string,
169 		          narrow_string_size,
170 		          (libuna_utf16_character_t *) system_string,
171 		          system_string_size,
172 		          error );
173 #endif /* SIZEOF_WCHAR_T */
174 	}
175 	else
176 	{
177 #if SIZEOF_WCHAR_T == 4
178 		result = libuna_byte_stream_copy_from_utf32(
179 		          (uint8_t *) narrow_string,
180 		          narrow_string_size,
181 		          libclocale_codepage,
182 		          (libuna_utf32_character_t *) system_string,
183 		          system_string_size,
184 		          error );
185 #elif SIZEOF_WCHAR_T == 2
186 		result = libuna_byte_stream_copy_from_utf16(
187 		          (uint8_t *) narrow_string,
188 		          narrow_string_size,
189 		          libclocale_codepage,
190 		          (libuna_utf16_character_t *) system_string,
191 		          system_string_size,
192 		          error );
193 #endif /* SIZEOF_WCHAR_T */
194 	}
195 	if( result != 1 )
196 	{
197 		libcerror_error_set(
198 		 error,
199 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
200 		 LIBCERROR_CONVERSION_ERROR_GENERIC,
201 		 "%s: unable to set narrow string.",
202 		 function );
203 
204 		return( -1 );
205 	}
206 #else
207 	if( system_string == NULL )
208 	{
209 		libcerror_error_set(
210 		 error,
211 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
212 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
213 		 "%s: invalid system string.",
214 		 function );
215 
216 		return( -1 );
217 	}
218 	if( system_string_size > (size_t) SSIZE_MAX )
219 	{
220 		libcerror_error_set(
221 		 error,
222 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
223 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
224 		 "%s: invalid system string size value exceeds maximum.",
225 		 function );
226 
227 		return( -1 );
228 	}
229 	if( narrow_string == NULL )
230 	{
231 		libcerror_error_set(
232 		 error,
233 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
234 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
235 		 "%s: invalid narrow string.",
236 		 function );
237 
238 		return( -1 );
239 	}
240 	if( narrow_string_size > (size_t) SSIZE_MAX )
241 	{
242 		libcerror_error_set(
243 		 error,
244 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
245 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
246 		 "%s: invalid narrow string size value exceeds maximum.",
247 		 function );
248 
249 		return( -1 );
250 	}
251 	if( narrow_string_size < system_string_size )
252 	{
253 		libcerror_error_set(
254 		 error,
255 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
256 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
257 		 "%s: invalid narrow string size value too small.",
258 		 function );
259 
260 		return( -1 );
261 	}
262 	if( system_string_copy(
263 	     narrow_string,
264 	     system_string,
265 	     system_string_size ) == NULL )
266 	{
267 		libcerror_error_set(
268 		 error,
269 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
270 		 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
271 		 "%s: unable to set narrow string.",
272 		 function );
273 
274 		return( -1 );
275 	}
276 	narrow_string[ system_string_size - 1 ] = 0;
277 
278 #endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
279 
280 	return( 1 );
281 }
282 
283 /* Determines the size of a system string from a narrow string
284  * Returns 1 if successful or -1 on error
285  */
libcfile_system_string_size_from_narrow_string(const char * narrow_string,size_t narrow_string_size,size_t * system_string_size,libcerror_error_t ** error)286 int libcfile_system_string_size_from_narrow_string(
287      const char *narrow_string,
288      size_t narrow_string_size,
289      size_t *system_string_size,
290      libcerror_error_t **error )
291 {
292 	static char *function = "libcfile_system_string_size_from_narrow_string";
293 
294 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
295 	int result            = 0;
296 #endif
297 
298 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
299 	if( libclocale_codepage == 0 )
300 	{
301 #if SIZEOF_WCHAR_T == 4
302 		result = libuna_utf32_string_size_from_utf8(
303 		          (libuna_utf8_character_t *) narrow_string,
304 		          narrow_string_size,
305 		          system_string_size,
306 		          error );
307 #elif SIZEOF_WCHAR_T == 2
308 		result = libuna_utf16_string_size_from_utf8(
309 		          (libuna_utf8_character_t *) narrow_string,
310 		          narrow_string_size,
311 		          system_string_size,
312 		          error );
313 #endif /* SIZEOF_WCHAR_T */
314 	}
315 	else
316 	{
317 #if SIZEOF_WCHAR_T == 4
318 		result = libuna_utf32_string_size_from_byte_stream(
319 		          (uint8_t *) narrow_string,
320 		          narrow_string_size,
321 		          libclocale_codepage,
322 		          system_string_size,
323 		          error );
324 #elif SIZEOF_WCHAR_T == 2
325 		result = libuna_utf16_string_size_from_byte_stream(
326 		          (uint8_t *) narrow_string,
327 		          narrow_string_size,
328 		          libclocale_codepage,
329 		          system_string_size,
330 		          error );
331 #endif /* SIZEOF_WCHAR_T */
332 	}
333 	if( result != 1 )
334 	{
335 		libcerror_error_set(
336 		 error,
337 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
338 		 LIBCERROR_CONVERSION_ERROR_GENERIC,
339 		 "%s: unable to determine system string size.",
340 		 function );
341 
342 		return( -1 );
343 	}
344 #else
345 	if( narrow_string == NULL )
346 	{
347 		libcerror_error_set(
348 		 error,
349 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
350 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
351 		 "%s: invalid narrow string.",
352 		 function );
353 
354 		return( -1 );
355 	}
356 	if( narrow_string_size > (size_t) SSIZE_MAX )
357 	{
358 		libcerror_error_set(
359 		 error,
360 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
361 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
362 		 "%s: invalid narrow string size value exceeds maximum.",
363 		 function );
364 
365 		return( -1 );
366 	}
367 	if( system_string_size == NULL )
368 	{
369 		libcerror_error_set(
370 		 error,
371 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
372 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
373 		 "%s: invalid system string size.",
374 		 function );
375 
376 		return( -1 );
377 	}
378 	*system_string_size = narrow_string_size;
379 
380 #endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
381 
382 	return( 1 );
383 }
384 
385 /* Copies a system string from a narrow string
386  * Returns 1 if successful or -1 on error
387  */
libcfile_system_string_copy_from_narrow_string(system_character_t * system_string,size_t system_string_size,const char * narrow_string,size_t narrow_string_size,libcerror_error_t ** error)388 int libcfile_system_string_copy_from_narrow_string(
389      system_character_t *system_string,
390      size_t system_string_size,
391      const char *narrow_string,
392      size_t narrow_string_size,
393      libcerror_error_t **error )
394 {
395 	static char *function = "libcfile_system_string_copy_from_narrow_string";
396 
397 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
398 	int result            = 0;
399 #endif
400 
401 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
402 	if( libclocale_codepage == 0 )
403 	{
404 #if SIZEOF_WCHAR_T == 4
405 		result = libuna_utf32_string_copy_from_utf8(
406 		          (libuna_utf32_character_t *) system_string,
407 		          system_string_size,
408 		          (libuna_utf8_character_t *) narrow_string,
409 		          narrow_string_size,
410 		          error );
411 #elif SIZEOF_WCHAR_T == 2
412 		result = libuna_utf16_string_copy_from_utf8(
413 		          (libuna_utf16_character_t *) system_string,
414 		          system_string_size,
415 		          (libuna_utf8_character_t *) narrow_string,
416 		          narrow_string_size,
417 		          error );
418 #endif /* SIZEOF_WCHAR_T */
419 	}
420 	else
421 	{
422 #if SIZEOF_WCHAR_T == 4
423 		result = libuna_utf32_string_copy_from_byte_stream(
424 		          (libuna_utf32_character_t *) system_string,
425 		          system_string_size,
426 		          (uint8_t *) narrow_string,
427 		          narrow_string_size,
428 		          libclocale_codepage,
429 		          error );
430 #elif SIZEOF_WCHAR_T == 2
431 		result = libuna_utf16_string_copy_from_byte_stream(
432 		          (libuna_utf16_character_t *) system_string,
433 		          system_string_size,
434 		          (uint8_t *) narrow_string,
435 		          narrow_string_size,
436 		          libclocale_codepage,
437 		          error );
438 #endif /* SIZEOF_WCHAR_T */
439 	}
440 	if( result != 1 )
441 	{
442 		libcerror_error_set(
443 		 error,
444 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
445 		 LIBCERROR_CONVERSION_ERROR_GENERIC,
446 		 "%s: unable to set system string.",
447 		 function );
448 
449 		return( -1 );
450 	}
451 #else
452 	if( system_string == NULL )
453 	{
454 		libcerror_error_set(
455 		 error,
456 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
457 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
458 		 "%s: invalid system string.",
459 		 function );
460 
461 		return( -1 );
462 	}
463 	if( system_string_size > (size_t) SSIZE_MAX )
464 	{
465 		libcerror_error_set(
466 		 error,
467 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
468 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
469 		 "%s: invalid system string size value exceeds maximum.",
470 		 function );
471 
472 		return( -1 );
473 	}
474 	if( narrow_string == NULL )
475 	{
476 		libcerror_error_set(
477 		 error,
478 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
479 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
480 		 "%s: invalid narrow string.",
481 		 function );
482 
483 		return( -1 );
484 	}
485 	if( narrow_string_size > (size_t) SSIZE_MAX )
486 	{
487 		libcerror_error_set(
488 		 error,
489 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
490 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
491 		 "%s: invalid narrow string size value exceeds maximum.",
492 		 function );
493 
494 		return( -1 );
495 	}
496 	if( system_string_size < narrow_string_size )
497 	{
498 		libcerror_error_set(
499 		 error,
500 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
501 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
502 		 "%s: invalid system string size value too small.",
503 		 function );
504 
505 		return( -1 );
506 	}
507 	if( system_string_copy(
508 	     system_string,
509 	     narrow_string,
510 	     narrow_string_size ) == NULL )
511 	{
512 		libcerror_error_set(
513 		 error,
514 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
515 		 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
516 		 "%s: unable to set narrow string.",
517 		 function );
518 
519 		return( -1 );
520 	}
521 	system_string[ narrow_string_size - 1 ] = 0;
522 
523 #endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
524 
525 	return( 1 );
526 }
527 
528 #if defined( HAVE_WIDE_CHARACTER_TYPE )
529 
530 /* Determines the size of a wide string from a system string
531  * Returns 1 if successful or -1 on error
532  */
libcfile_system_string_size_to_wide_string(const system_character_t * system_string,size_t system_string_size,size_t * wide_string_size,libcerror_error_t ** error)533 int libcfile_system_string_size_to_wide_string(
534      const system_character_t *system_string,
535      size_t system_string_size,
536      size_t *wide_string_size,
537      libcerror_error_t **error )
538 {
539 	static char *function = "libcfile_system_string_size_to_wide_string";
540 
541 #if !defined( HAVE_WIDE_SYSTEM_CHARACTER )
542 	int result            = 0;
543 #endif
544 
545 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
546 	if( system_string == NULL )
547 	{
548 		libcerror_error_set(
549 		 error,
550 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
551 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
552 		 "%s: invalid system string.",
553 		 function );
554 
555 		return( -1 );
556 	}
557 	if( system_string_size > (size_t) SSIZE_MAX )
558 	{
559 		libcerror_error_set(
560 		 error,
561 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
562 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
563 		 "%s: invalid system string size value exceeds maximum.",
564 		 function );
565 
566 		return( -1 );
567 	}
568 	if( wide_string_size == NULL )
569 	{
570 		libcerror_error_set(
571 		 error,
572 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
573 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
574 		 "%s: invalid wide string size.",
575 		 function );
576 
577 		return( -1 );
578 	}
579 	*wide_string_size = system_string_size;
580 #else
581 	if( libclocale_codepage == 0 )
582 	{
583 #if SIZEOF_WCHAR_T == 4
584 		result = libuna_utf32_string_size_from_utf8(
585 		          (libuna_utf8_character_t *) system_string,
586 		          system_string_size,
587 		          wide_string_size,
588 		          error );
589 #elif SIZEOF_WCHAR_T == 2
590 		result = libuna_utf16_string_size_from_utf8(
591 		          (libuna_utf8_character_t *) system_string,
592 		          system_string_size,
593 		          wide_string_size,
594 		          error );
595 #endif /* SIZEOF_WCHAR_T */
596 	}
597 	else
598 	{
599 #if SIZEOF_WCHAR_T == 4
600 		result = libuna_utf32_string_size_from_byte_stream(
601 		          (uint8_t *) system_string,
602 		          system_string_size,
603 		          libclocale_codepage,
604 		          wide_string_size,
605 		          error );
606 #elif SIZEOF_WCHAR_T == 2
607 		result = libuna_utf16_string_size_from_byte_stream(
608 		          (uint8_t *) system_string,
609 		          system_string_size,
610 		          libclocale_codepage,
611 		          wide_string_size,
612 		          error );
613 #endif /* SIZEOF_WCHAR_T */
614 	}
615 	if( result != 1 )
616 	{
617 		libcerror_error_set(
618 		 error,
619 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
620 		 LIBCERROR_CONVERSION_ERROR_GENERIC,
621 		 "%s: unable to determine wide string size.",
622 		 function );
623 
624 		return( -1 );
625 	}
626 #endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
627 
628 	return( 1 );
629 }
630 
631 /* Copies a system string to a wide string
632  * Returns 1 if successful or -1 on error
633  */
libcfile_system_string_copy_to_wide_string(const system_character_t * system_string,size_t system_string_size,wchar_t * wide_string,size_t wide_string_size,libcerror_error_t ** error)634 int libcfile_system_string_copy_to_wide_string(
635      const system_character_t *system_string,
636      size_t system_string_size,
637      wchar_t *wide_string,
638      size_t wide_string_size,
639      libcerror_error_t **error )
640 {
641 	static char *function = "libcfile_system_string_copy_to_wide_string";
642 
643 #if !defined( HAVE_WIDE_SYSTEM_CHARACTER )
644 	int result            = 0;
645 #endif
646 
647 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
648 	if( system_string == NULL )
649 	{
650 		libcerror_error_set(
651 		 error,
652 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
653 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
654 		 "%s: invalid system string.",
655 		 function );
656 
657 		return( -1 );
658 	}
659 	if( system_string_size > (size_t) SSIZE_MAX )
660 	{
661 		libcerror_error_set(
662 		 error,
663 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
664 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
665 		 "%s: invalid system string size value exceeds maximum.",
666 		 function );
667 
668 		return( -1 );
669 	}
670 	if( wide_string == NULL )
671 	{
672 		libcerror_error_set(
673 		 error,
674 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
675 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
676 		 "%s: invalid wide string.",
677 		 function );
678 
679 		return( -1 );
680 	}
681 	if( wide_string_size > (size_t) SSIZE_MAX )
682 	{
683 		libcerror_error_set(
684 		 error,
685 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
686 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
687 		 "%s: invalid wide string size value exceeds maximum.",
688 		 function );
689 
690 		return( -1 );
691 	}
692 	if( wide_string_size < system_string_size )
693 	{
694 		libcerror_error_set(
695 		 error,
696 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
697 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
698 		 "%s: invalid wide string size value too small.",
699 		 function );
700 
701 		return( -1 );
702 	}
703 	if( system_string_copy(
704 	     wide_string,
705 	     system_string,
706 	     system_string_size ) == NULL )
707 	{
708 		libcerror_error_set(
709 		 error,
710 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
711 		 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
712 		 "%s: unable to set wide string.",
713 		 function );
714 
715 		return( -1 );
716 	}
717 	wide_string[ system_string_size - 1 ] = 0;
718 #else
719 	if( libclocale_codepage == 0 )
720 	{
721 #if SIZEOF_WCHAR_T == 4
722 		result = libuna_utf32_string_copy_from_utf8(
723 		          (libuna_utf32_character_t *) wide_string,
724 		          wide_string_size,
725 		          (libuna_utf8_character_t *) system_string,
726 		          system_string_size,
727 		          error );
728 #elif SIZEOF_WCHAR_T == 2
729 		result = libuna_utf16_string_copy_from_utf8(
730 		          (libuna_utf16_character_t *) wide_string,
731 		          wide_string_size,
732 		          (libuna_utf8_character_t *) system_string,
733 		          system_string_size,
734 		          error );
735 #endif /* SIZEOF_WCHAR_T */
736 	}
737 	else
738 	{
739 #if SIZEOF_WCHAR_T == 4
740 		result = libuna_utf32_string_copy_from_byte_stream(
741 		          (libuna_utf32_character_t *) wide_string,
742 		          wide_string_size,
743 		          (uint8_t *) system_string,
744 		          system_string_size,
745 		          libclocale_codepage,
746 		          error );
747 #elif SIZEOF_WCHAR_T == 2
748 		result = libuna_utf16_string_copy_from_byte_stream(
749 		          (libuna_utf16_character_t *) wide_string,
750 		          wide_string_size,
751 		          (uint8_t *) system_string,
752 		          system_string_size,
753 		          libclocale_codepage,
754 		          error );
755 #endif /* SIZEOF_WCHAR_T */
756 	}
757 	if( result != 1 )
758 	{
759 		libcerror_error_set(
760 		 error,
761 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
762 		 LIBCERROR_CONVERSION_ERROR_GENERIC,
763 		 "%s: unable to set wide string.",
764 		 function );
765 
766 		return( -1 );
767 	}
768 #endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
769 
770 	return( 1 );
771 }
772 
773 /* Determines the size of a system string from a wide string
774  * Returns 1 if successful or -1 on error
775  */
libcfile_system_string_size_from_wide_string(const wchar_t * wide_string,size_t wide_string_size,size_t * system_string_size,libcerror_error_t ** error)776 int libcfile_system_string_size_from_wide_string(
777      const wchar_t *wide_string,
778      size_t wide_string_size,
779      size_t *system_string_size,
780      libcerror_error_t **error )
781 {
782 	static char *function = "libcfile_system_string_size_from_wide_string";
783 
784 #if !defined( HAVE_WIDE_SYSTEM_CHARACTER )
785 	int result            = 0;
786 #endif
787 
788 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
789 	if( wide_string == NULL )
790 	{
791 		libcerror_error_set(
792 		 error,
793 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
794 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
795 		 "%s: invalid wide string.",
796 		 function );
797 
798 		return( -1 );
799 	}
800 	if( wide_string_size > (size_t) SSIZE_MAX )
801 	{
802 		libcerror_error_set(
803 		 error,
804 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
805 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
806 		 "%s: invalid wide string size value exceeds maximum.",
807 		 function );
808 
809 		return( -1 );
810 	}
811 	if( system_string_size == NULL )
812 	{
813 		libcerror_error_set(
814 		 error,
815 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
816 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
817 		 "%s: invalid system string size.",
818 		 function );
819 
820 		return( -1 );
821 	}
822 	*system_string_size = wide_string_size;
823 #else
824 	if( libclocale_codepage == 0 )
825 	{
826 #if SIZEOF_WCHAR_T == 4
827 		result = libuna_utf8_string_size_from_utf32(
828 		          (libuna_utf32_character_t *) wide_string,
829 		          wide_string_size,
830 		          system_string_size,
831 		          error );
832 #elif SIZEOF_WCHAR_T == 2
833 		result = libuna_utf8_string_size_from_utf16(
834 		          (libuna_utf16_character_t *) wide_string,
835 		          wide_string_size,
836 		          system_string_size,
837 		          error );
838 #endif /* SIZEOF_WCHAR_T */
839 	}
840 	else
841 	{
842 #if SIZEOF_WCHAR_T == 4
843 		result = libuna_byte_stream_size_from_utf32(
844 		          (libuna_utf32_character_t *) wide_string,
845 		          wide_string_size,
846 		          libclocale_codepage,
847 		          system_string_size,
848 		          error );
849 #elif SIZEOF_WCHAR_T == 2
850 		result = libuna_byte_stream_size_from_utf16(
851 		          (libuna_utf16_character_t *) wide_string,
852 		          wide_string_size,
853 		          libclocale_codepage,
854 		          system_string_size,
855 		          error );
856 #endif /* SIZEOF_WCHAR_T */
857 	}
858 	if( result != 1 )
859 	{
860 		libcerror_error_set(
861 		 error,
862 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
863 		 LIBCERROR_CONVERSION_ERROR_GENERIC,
864 		 "%s: unable to determine wide string size.",
865 		 function );
866 
867 		return( -1 );
868 	}
869 #endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
870 
871 	return( 1 );
872 }
873 
874 /* Copies a system string from a wide string
875  * Returns 1 if successful or -1 on error
876  */
libcfile_system_string_copy_from_wide_string(system_character_t * system_string,size_t system_string_size,const wchar_t * wide_string,size_t wide_string_size,libcerror_error_t ** error)877 int libcfile_system_string_copy_from_wide_string(
878      system_character_t *system_string,
879      size_t system_string_size,
880      const wchar_t *wide_string,
881      size_t wide_string_size,
882      libcerror_error_t **error )
883 {
884 	static char *function = "libcfile_system_string_copy_from_wide_string";
885 
886 #if !defined( HAVE_WIDE_SYSTEM_CHARACTER )
887 	int result            = 0;
888 #endif
889 
890 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
891 	if( system_string == NULL )
892 	{
893 		libcerror_error_set(
894 		 error,
895 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
896 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
897 		 "%s: invalid system string.",
898 		 function );
899 
900 		return( -1 );
901 	}
902 	if( system_string_size > (size_t) SSIZE_MAX )
903 	{
904 		libcerror_error_set(
905 		 error,
906 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
907 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
908 		 "%s: invalid system string size value exceeds maximum.",
909 		 function );
910 
911 		return( -1 );
912 	}
913 	if( wide_string == NULL )
914 	{
915 		libcerror_error_set(
916 		 error,
917 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
918 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
919 		 "%s: invalid wide string.",
920 		 function );
921 
922 		return( -1 );
923 	}
924 	if( wide_string_size > (size_t) SSIZE_MAX )
925 	{
926 		libcerror_error_set(
927 		 error,
928 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
929 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
930 		 "%s: invalid wide string size value exceeds maximum.",
931 		 function );
932 
933 		return( -1 );
934 	}
935 	if( system_string_size < wide_string_size )
936 	{
937 		libcerror_error_set(
938 		 error,
939 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
940 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
941 		 "%s: invalid system string size value too small.",
942 		 function );
943 
944 		return( -1 );
945 	}
946 	if( system_string_copy(
947 	     system_string,
948 	     wide_string,
949 	     wide_string_size ) == NULL )
950 	{
951 		libcerror_error_set(
952 		 error,
953 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
954 		 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
955 		 "%s: unable to set wide string.",
956 		 function );
957 
958 		return( -1 );
959 	}
960 	system_string[ wide_string_size - 1 ] = 0;
961 #else
962 	if( libclocale_codepage == 0 )
963 	{
964 #if SIZEOF_WCHAR_T == 4
965 		result = libuna_utf8_string_copy_from_utf32(
966 		          (libuna_utf8_character_t *) system_string,
967 		          system_string_size,
968 		          (libuna_utf32_character_t *) wide_string,
969 		          wide_string_size,
970 		          error );
971 #elif SIZEOF_WCHAR_T == 2
972 		result = libuna_utf8_string_copy_from_utf16(
973 		          (libuna_utf8_character_t *) system_string,
974 		          system_string_size,
975 		          (libuna_utf16_character_t *) wide_string,
976 		          wide_string_size,
977 		          error );
978 #endif /* SIZEOF_WCHAR_T */
979 	}
980 	else
981 	{
982 #if SIZEOF_WCHAR_T == 4
983 		result = libuna_byte_stream_copy_from_utf32(
984 		          (uint8_t *) system_string,
985 		          system_string_size,
986 		          libclocale_codepage,
987 		          (libuna_utf32_character_t *) wide_string,
988 		          wide_string_size,
989 		          error );
990 #elif SIZEOF_WCHAR_T == 2
991 		result = libuna_byte_stream_copy_from_utf16(
992 		          (uint8_t *) system_string,
993 		          system_string_size,
994 		          libclocale_codepage,
995 		          (libuna_utf16_character_t *) wide_string,
996 		          wide_string_size,
997 		          error );
998 #endif /* SIZEOF_WCHAR_T */
999 	}
1000 	if( result != 1 )
1001 	{
1002 		libcerror_error_set(
1003 		 error,
1004 		 LIBCERROR_ERROR_DOMAIN_CONVERSION,
1005 		 LIBCERROR_CONVERSION_ERROR_GENERIC,
1006 		 "%s: unable to set wide string.",
1007 		 function );
1008 
1009 		return( -1 );
1010 	}
1011 #endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */
1012 
1013 	return( 1 );
1014 }
1015 
1016 #endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */
1017 
1018