1 /*
2  * GUID functions
3  *
4  * Copyright (C) 2010-2018, Joachim Metz <joachim.metz@gmail.com>
5  *
6  * Refer to AUTHORS for acknowledgements.
7  *
8  * This software 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 software 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 software.  If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <common.h>
23 #include <byte_stream.h>
24 #include <memory.h>
25 #include <types.h>
26 
27 #include "libfguid_definitions.h"
28 #include "libfguid_identifier.h"
29 #include "libfguid_libcerror.h"
30 #include "libfguid_types.h"
31 
32 /* Creates an identifier
33  * Make sure the value identifier is referencing, is set to NULL
34  * Returns 1 if successful or -1 on error
35  */
libfguid_identifier_initialize(libfguid_identifier_t ** identifier,libcerror_error_t ** error)36 int libfguid_identifier_initialize(
37      libfguid_identifier_t **identifier,
38      libcerror_error_t **error )
39 {
40 	libfguid_internal_identifier_t *internal_identifier = NULL;
41 	static char *function                               = "libfguid_identifier_initialize";
42 
43 	if( identifier == NULL )
44 	{
45 		libcerror_error_set(
46 		 error,
47 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
48 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
49 		 "%s: invalid identifier.",
50 		 function );
51 
52 		return( -1 );
53 	}
54 	if( *identifier != NULL )
55 	{
56 		libcerror_error_set(
57 		 error,
58 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
59 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
60 		 "%s: invalid identifier value already set.",
61 		 function );
62 
63 		return( -1 );
64 	}
65 	internal_identifier = memory_allocate_structure(
66 	                       libfguid_internal_identifier_t );
67 
68 	if( internal_identifier == NULL )
69 	{
70 		libcerror_error_set(
71 		 error,
72 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
73 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
74 		 "%s: unable to create identifier.",
75 		 function );
76 
77 		goto on_error;
78 	}
79 	if( memory_set(
80 	     internal_identifier,
81 	     0,
82 	     sizeof( libfguid_internal_identifier_t ) ) == NULL )
83 	{
84 		libcerror_error_set(
85 		 error,
86 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
87 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
88 		 "%s: unable to clear identifier.",
89 		 function );
90 
91 		goto on_error;
92 	}
93 	*identifier = (libfguid_identifier_t *) internal_identifier;
94 
95 	return( 1 );
96 
97 on_error:
98 	if( internal_identifier != NULL )
99 	{
100 		memory_free(
101 		 internal_identifier );
102 	}
103 	return( -1 );
104 }
105 
106 /* Frees an identifier
107  * Returns 1 if successful or -1 on error
108  */
libfguid_identifier_free(libfguid_identifier_t ** identifier,libcerror_error_t ** error)109 int libfguid_identifier_free(
110      libfguid_identifier_t **identifier,
111      libcerror_error_t **error )
112 {
113 	libfguid_internal_identifier_t *internal_identifier = NULL;
114 	static char *function                               = "libfguid_identifier_free";
115 
116 	if( identifier == NULL )
117 	{
118 		libcerror_error_set(
119 		 error,
120 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
121 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
122 		 "%s: invalid identifier.",
123 		 function );
124 
125 		return( -1 );
126 	}
127 	if( *identifier != NULL )
128 	{
129 		internal_identifier = (libfguid_internal_identifier_t *) *identifier;
130 		*identifier         = NULL;
131 
132 		memory_free(
133 		 internal_identifier );
134 	}
135 	return( 1 );
136 }
137 
138 /* Copies the identifier from a byte stream
139  * Returns 1 if successful or -1 on error
140  */
libfguid_identifier_copy_from_byte_stream(libfguid_identifier_t * identifier,const uint8_t * byte_stream,size_t byte_stream_size,int byte_order,libcerror_error_t ** error)141 int libfguid_identifier_copy_from_byte_stream(
142      libfguid_identifier_t *identifier,
143      const uint8_t *byte_stream,
144      size_t byte_stream_size,
145      int byte_order,
146      libcerror_error_t **error )
147 {
148 	libfguid_internal_identifier_t *internal_identifier = NULL;
149 	static char *function                               = "libfguid_identifier_copy_from_byte_stream";
150 
151 	if( identifier == NULL )
152 	{
153 		libcerror_error_set(
154 		 error,
155 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
156 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
157 		 "%s: invalid identifier.",
158 		 function );
159 
160 		return( -1 );
161 	}
162 	internal_identifier = (libfguid_internal_identifier_t *) identifier;
163 
164 	if( byte_stream == NULL )
165 	{
166 		libcerror_error_set(
167 		 error,
168 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
169 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
170 		 "%s: invalid byte stream.",
171 		 function );
172 
173 		return( -1 );
174 	}
175 	if( byte_stream_size < 16 )
176 	{
177 		libcerror_error_set(
178 		 error,
179 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
180 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
181 		 "%s: byte stream too small.",
182 		 function );
183 
184 		return( -1 );
185 	}
186 	if( byte_stream_size > (size_t) SSIZE_MAX )
187 	{
188 		libcerror_error_set(
189 		 error,
190 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
191 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
192 		 "%s: byte stream size exceeds maximum.",
193 		 function );
194 
195 		return( -1 );
196 	}
197 	if( ( byte_order != LIBFGUID_ENDIAN_BIG )
198 	 && ( byte_order != LIBFGUID_ENDIAN_LITTLE ) )
199 	{
200 		libcerror_error_set(
201 		 error,
202 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
203 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
204 		 "%s: unsupported byte order.",
205 		 function );
206 
207 		return( -1 );
208 	}
209 	if( byte_order == LIBFGUID_ENDIAN_LITTLE )
210 	{
211 		byte_stream_copy_to_uint32_little_endian(
212 		 byte_stream,
213 		 internal_identifier->time.lower );
214 
215 		byte_stream += 4;
216 
217 		byte_stream_copy_to_uint16_little_endian(
218 		 byte_stream,
219 		 internal_identifier->time.middle );
220 
221 		byte_stream += 2;
222 
223 		byte_stream_copy_to_uint16_little_endian(
224 		 byte_stream,
225 		 internal_identifier->time.upper );
226 
227 		byte_stream += 2;
228 	}
229 	else if( byte_order == LIBFGUID_ENDIAN_BIG )
230 	{
231 		byte_stream_copy_to_uint32_big_endian(
232 		 byte_stream,
233 		 internal_identifier->time.lower );
234 
235 		byte_stream += 4;
236 
237 		byte_stream_copy_to_uint16_big_endian(
238 		 byte_stream,
239 		 internal_identifier->time.middle );
240 
241 		byte_stream += 2;
242 
243 		byte_stream_copy_to_uint16_big_endian(
244 		 byte_stream,
245 		 internal_identifier->time.upper );
246 
247 		byte_stream += 2;
248 	}
249 	internal_identifier->clock_sequence.upper = byte_stream[ 0 ];
250 	internal_identifier->clock_sequence.lower = byte_stream[ 1 ];
251 	internal_identifier->node[ 0 ]            = byte_stream[ 2 ];
252 	internal_identifier->node[ 1 ]            = byte_stream[ 3 ];
253 	internal_identifier->node[ 2 ]            = byte_stream[ 4 ];
254 	internal_identifier->node[ 3 ]            = byte_stream[ 5 ];
255 	internal_identifier->node[ 4 ]            = byte_stream[ 6 ];
256 	internal_identifier->node[ 5 ]            = byte_stream[ 7 ];
257 
258 	return( 1 );
259 }
260 
261 /* Copies the identifier to a byte stream
262  * Returns 1 if successful or -1 on error
263  */
libfguid_identifier_copy_to_byte_stream(libfguid_identifier_t * identifier,uint8_t * byte_stream,size_t byte_stream_size,int byte_order,libcerror_error_t ** error)264 int libfguid_identifier_copy_to_byte_stream(
265      libfguid_identifier_t *identifier,
266      uint8_t *byte_stream,
267      size_t byte_stream_size,
268      int byte_order,
269      libcerror_error_t **error )
270 {
271 	libfguid_internal_identifier_t *internal_identifier = NULL;
272 	static char *function                               = "libfguid_identifier_copy_to_byte_stream";
273 
274 	if( identifier == NULL )
275 	{
276 		libcerror_error_set(
277 		 error,
278 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
279 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
280 		 "%s: invalid identifier.",
281 		 function );
282 
283 		return( -1 );
284 	}
285 	internal_identifier = (libfguid_internal_identifier_t *) identifier;
286 
287 	if( byte_stream == NULL )
288 	{
289 		libcerror_error_set(
290 		 error,
291 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
292 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
293 		 "%s: invalid byte stream.",
294 		 function );
295 
296 		return( -1 );
297 	}
298 	if( byte_stream_size < 16 )
299 	{
300 		libcerror_error_set(
301 		 error,
302 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
303 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
304 		 "%s: byte stream too small.",
305 		 function );
306 
307 		return( -1 );
308 	}
309 	if( byte_stream_size > (size_t) SSIZE_MAX )
310 	{
311 		libcerror_error_set(
312 		 error,
313 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
314 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
315 		 "%s: byte stream size exceeds maximum.",
316 		 function );
317 
318 		return( -1 );
319 	}
320 	if( ( byte_order != LIBFGUID_ENDIAN_BIG )
321 	 && ( byte_order != LIBFGUID_ENDIAN_LITTLE ) )
322 	{
323 		libcerror_error_set(
324 		 error,
325 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
326 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
327 		 "%s: unsupported byte order.",
328 		 function );
329 
330 		return( -1 );
331 	}
332 	if( byte_order == LIBFGUID_ENDIAN_LITTLE )
333 	{
334 		byte_stream_copy_from_uint32_little_endian(
335 		 byte_stream,
336 		 internal_identifier->time.lower );
337 
338 		byte_stream += 4;
339 
340 		byte_stream_copy_from_uint16_little_endian(
341 		 byte_stream,
342 		 internal_identifier->time.middle );
343 
344 		byte_stream += 2;
345 
346 		byte_stream_copy_from_uint16_little_endian(
347 		 byte_stream,
348 		 internal_identifier->time.upper );
349 
350 		byte_stream += 2;
351 	}
352 	else if( byte_order == LIBFGUID_ENDIAN_BIG )
353 	{
354 		byte_stream_copy_from_uint32_big_endian(
355 		 byte_stream,
356 		 internal_identifier->time.lower );
357 
358 		byte_stream += 4;
359 
360 		byte_stream_copy_from_uint16_big_endian(
361 		 byte_stream,
362 		 internal_identifier->time.middle );
363 
364 		byte_stream += 2;
365 
366 		byte_stream_copy_from_uint16_big_endian(
367 		 byte_stream,
368 		 internal_identifier->time.upper );
369 
370 		byte_stream += 2;
371 	}
372 	byte_stream[ 0 ] = internal_identifier->clock_sequence.upper;
373 	byte_stream[ 1 ] = internal_identifier->clock_sequence.lower;
374 	byte_stream[ 2 ] = internal_identifier->node[ 0 ];
375 	byte_stream[ 3 ] = internal_identifier->node[ 1 ];
376 	byte_stream[ 4 ] = internal_identifier->node[ 2 ];
377 	byte_stream[ 5 ] = internal_identifier->node[ 3 ];
378 	byte_stream[ 6 ] = internal_identifier->node[ 4 ];
379 	byte_stream[ 7 ] = internal_identifier->node[ 5 ];
380 
381 	return( 1 );
382 }
383 
384 /* Retrieves the size of an UTF-8 encoded string of the identifier
385  * The string size includes the end of string character
386  * Returns 1 if successful or -1 on error
387  */
libfguid_identifier_get_string_size(libfguid_identifier_t * identifier,size_t * string_size,uint32_t string_format_flags,libcerror_error_t ** error)388 int libfguid_identifier_get_string_size(
389      libfguid_identifier_t *identifier,
390      size_t *string_size,
391      uint32_t string_format_flags,
392      libcerror_error_t **error )
393 {
394 	static char *function    = "libfguid_identifier_get_string_size";
395 	uint32_t required_flags  = 0;
396 	uint32_t supported_flags = 0;
397 
398 	if( identifier == NULL )
399 	{
400 		libcerror_error_set(
401 		 error,
402 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
403 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
404 		 "%s: invalid identifier.",
405 		 function );
406 
407 		return( -1 );
408 	}
409 	if( string_size == NULL )
410 	{
411 		libcerror_error_set(
412 		 error,
413 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
414 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
415 		 "%s: invalid string size.",
416 		 function );
417 
418 		return( -1 );
419 	}
420 	required_flags = LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE
421 	               | LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE;
422 
423 	if( ( string_format_flags & required_flags ) == 0 )
424 	{
425 		libcerror_error_set(
426 		 error,
427 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
428 		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
429 		 "%s: missing string format flags.",
430 		 function );
431 
432 		return( -1 );
433 	}
434 	supported_flags = required_flags
435 	                | LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES;
436 
437 	if( ( string_format_flags & ~( supported_flags ) ) != 0 )
438 	{
439 		libcerror_error_set(
440 		 error,
441 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
442 		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
443 		 "%s: unsupported string format flags: 0x%08" PRIx32 ".",
444 		 function,
445 		 string_format_flags );
446 
447 		return( -1 );
448 	}
449 	*string_size = 37;
450 
451 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
452 	{
453 		*string_size += 2;
454 	}
455 	return( 1 );
456 }
457 
458 /* Copies the identifier from an UTF-8 encoded string
459  * Returns 1 if successful or -1 on error
460  */
libfguid_identifier_copy_from_utf8_string(libfguid_identifier_t * identifier,const uint8_t * utf8_string,size_t utf8_string_size,uint32_t string_format_flags,libcerror_error_t ** error)461 int libfguid_identifier_copy_from_utf8_string(
462      libfguid_identifier_t *identifier,
463      const uint8_t *utf8_string,
464      size_t utf8_string_size,
465      uint32_t string_format_flags,
466      libcerror_error_t **error )
467 {
468 	static char *function    = "libfguid_identifier_copy_from_utf8_string";
469 	size_t utf8_string_index = 0;
470 
471 	if( libfguid_identifier_copy_from_utf8_string_with_index(
472 	     identifier,
473 	     utf8_string,
474 	     utf8_string_size,
475 	     &utf8_string_index,
476 	     string_format_flags,
477 	     error ) != 1 )
478 	{
479 		libcerror_error_set(
480 		 error,
481 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
482 		 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
483 		 "%s: unable to copy identifier from UTF-8 string.",
484 		 function );
485 
486 		return( -1 );
487 	}
488 	return( 1 );
489 }
490 
491 /* Copies the identifier from an UTF-8 encoded string
492  * Returns 1 if successful or -1 on error
493  */
libfguid_identifier_copy_from_utf8_string_with_index(libfguid_identifier_t * identifier,const uint8_t * utf8_string,size_t utf8_string_length,size_t * utf8_string_index,uint32_t string_format_flags,libcerror_error_t ** error)494 int libfguid_identifier_copy_from_utf8_string_with_index(
495      libfguid_identifier_t *identifier,
496      const uint8_t *utf8_string,
497      size_t utf8_string_length,
498      size_t *utf8_string_index,
499      uint32_t string_format_flags,
500      libcerror_error_t **error )
501 {
502 	libfguid_internal_identifier_t *internal_identifier = NULL;
503 	static char *function                               = "libfguid_identifier_copy_from_utf8_string_with_index";
504 	size_t byte_index                                   = 0;
505 	size_t node_index                                   = 0;
506 	size_t string_index                                 = 0;
507 	size_t string_length                                = 0;
508 	uint32_t required_flags                             = 0;
509 	uint32_t supported_flags                            = 0;
510 
511 	if( identifier == NULL )
512 	{
513 		libcerror_error_set(
514 		 error,
515 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
516 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
517 		 "%s: invalid identifier.",
518 		 function );
519 
520 		return( -1 );
521 	}
522 	internal_identifier = (libfguid_internal_identifier_t *) identifier;
523 
524 	if( utf8_string == NULL )
525 	{
526 		libcerror_error_set(
527 		 error,
528 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
529 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
530 		 "%s: invalid UTF-8 string.",
531 		 function );
532 
533 		return( -1 );
534 	}
535 	if( utf8_string_length > (size_t) SSIZE_MAX )
536 	{
537 		libcerror_error_set(
538 		 error,
539 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
540 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
541 		 "%s: invalid UTF-8 string size value exceeds maximum.",
542 		 function );
543 
544 		return( -1 );
545 	}
546 	if( utf8_string_index == NULL )
547 	{
548 		libcerror_error_set(
549 		 error,
550 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
551 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
552 		 "%s: invalid UTF-8 index.",
553 		 function );
554 
555 		return( -1 );
556 	}
557 	required_flags = LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE
558 	               | LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE;
559 
560 	if( ( string_format_flags & required_flags ) == 0 )
561 	{
562 		libcerror_error_set(
563 		 error,
564 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
565 		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
566 		 "%s: missing string format flags.",
567 		 function );
568 
569 		return( -1 );
570 	}
571 	supported_flags = required_flags
572 	                | LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES;
573 
574 	if( ( string_format_flags & ~( supported_flags ) ) != 0 )
575 	{
576 		libcerror_error_set(
577 		 error,
578 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
579 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
580 		 "%s: unsupported string format flags: 0x%08" PRIx32 ".",
581 		 function,
582 		 string_format_flags );
583 
584 		return( -1 );
585 	}
586 	string_length = 36;
587 
588 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
589 	{
590 		string_length += 2;
591 	}
592 	string_index = *utf8_string_index;
593 
594 	if( ( string_index + string_length ) > utf8_string_length )
595 	{
596 		libcerror_error_set(
597 		 error,
598 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
599 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
600 		 "%s: UTF-8 string is too small.",
601 		 function );
602 
603 		return( -1 );
604 	}
605 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
606 	{
607 		if( utf8_string[ string_index ] != (uint8_t) '{' )
608 		{
609 			goto on_error;
610 		}
611 		string_index++;
612 	}
613 	for( byte_index = 0;
614 	     byte_index < 8;
615 	     byte_index++ )
616 	{
617 		internal_identifier->time.lower <<= 4;
618 
619 		if( ( utf8_string[ string_index ] >= (uint8_t) '0' )
620 		 && ( utf8_string[ string_index ] <= (uint8_t) '9' ) )
621 		{
622 			internal_identifier->time.lower |= utf8_string[ string_index ] - (uint8_t) '0';
623 		}
624 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
625 		      && ( utf8_string[ string_index ] >= (uint8_t) 'a' )
626 		      && ( utf8_string[ string_index ] <= (uint8_t) 'f' ) )
627 		{
628 			internal_identifier->time.lower |= utf8_string[ string_index ] - (uint8_t) 'a' + 10;
629 		}
630 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
631 		      && ( utf8_string[ string_index ] >= (uint8_t) 'A' )
632 		      && ( utf8_string[ string_index ] <= (uint8_t) 'F' ) )
633 		{
634 			internal_identifier->time.lower |= utf8_string[ string_index ] - (uint8_t) 'A' + 10;
635 		}
636 		else
637 		{
638 			goto on_error;
639 		}
640 		string_index++;
641 	}
642 	if( utf8_string[ string_index ] != (uint8_t) '-' )
643 	{
644 		goto on_error;
645 	}
646 	string_index++;
647 
648 	for( byte_index = 0;
649 	     byte_index < 4;
650 	     byte_index++ )
651 	{
652 		internal_identifier->time.middle <<= 4;
653 
654 		if( ( utf8_string[ string_index ] >= (uint8_t) '0' )
655 		 && ( utf8_string[ string_index ] <= (uint8_t) '9' ) )
656 		{
657 			internal_identifier->time.middle |= utf8_string[ string_index ] - (uint8_t) '0';
658 		}
659 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
660 		      && ( utf8_string[ string_index ] >= (uint8_t) 'a' )
661 		      && ( utf8_string[ string_index ] <= (uint8_t) 'f' ) )
662 		{
663 			internal_identifier->time.middle |= utf8_string[ string_index ] - (uint8_t) 'a' + 10;
664 		}
665 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
666 		      && ( utf8_string[ string_index ] >= (uint8_t) 'A' )
667 		      && ( utf8_string[ string_index ] <= (uint8_t) 'F' ) )
668 		{
669 			internal_identifier->time.middle |= utf8_string[ string_index ] - (uint8_t) 'A' + 10;
670 		}
671 		else
672 		{
673 			goto on_error;
674 		}
675 		string_index++;
676 	}
677 	if( utf8_string[ string_index ] != (uint8_t) '-' )
678 	{
679 		goto on_error;
680 	}
681 	string_index++;
682 
683 	for( byte_index = 0;
684 	     byte_index < 4;
685 	     byte_index++ )
686 	{
687 		internal_identifier->time.upper <<= 4;
688 
689 		if( ( utf8_string[ string_index ] >= (uint8_t) '0' )
690 		 && ( utf8_string[ string_index ] <= (uint8_t) '9' ) )
691 		{
692 			internal_identifier->time.upper |= utf8_string[ string_index ] - (uint8_t) '0';
693 		}
694 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
695 		      && ( utf8_string[ string_index ] >= (uint8_t) 'a' )
696 		      && ( utf8_string[ string_index ] <= (uint8_t) 'f' ) )
697 		{
698 			internal_identifier->time.upper |= utf8_string[ string_index ] - (uint8_t) 'a' + 10;
699 		}
700 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
701 		      && ( utf8_string[ string_index ] >= (uint8_t) 'A' )
702 		      && ( utf8_string[ string_index ] <= (uint8_t) 'F' ) )
703 		{
704 			internal_identifier->time.upper |= utf8_string[ string_index ] - (uint8_t) 'A' + 10;
705 		}
706 		else
707 		{
708 			goto on_error;
709 		}
710 		string_index++;
711 	}
712 	if( utf8_string[ string_index ] != (uint8_t) '-' )
713 	{
714 		goto on_error;
715 	}
716 	string_index++;
717 
718 	for( byte_index = 0;
719 	     byte_index < 2;
720 	     byte_index++ )
721 	{
722 		internal_identifier->clock_sequence.upper <<= 4;
723 
724 		if( ( utf8_string[ string_index ] >= (uint8_t) '0' )
725 		 && ( utf8_string[ string_index ] <= (uint8_t) '9' ) )
726 		{
727 			internal_identifier->clock_sequence.upper |= utf8_string[ string_index ] - (uint8_t) '0';
728 		}
729 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
730 		      && ( utf8_string[ string_index ] >= (uint8_t) 'a' )
731 		      && ( utf8_string[ string_index ] <= (uint8_t) 'f' ) )
732 		{
733 			internal_identifier->clock_sequence.upper |= utf8_string[ string_index ] - (uint8_t) 'a' + 10;
734 		}
735 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
736 		      && ( utf8_string[ string_index ] >= (uint8_t) 'A' )
737 		      && ( utf8_string[ string_index ] <= (uint8_t) 'F' ) )
738 		{
739 			internal_identifier->clock_sequence.upper |= utf8_string[ string_index ] - (uint8_t) 'A' + 10;
740 		}
741 		else
742 		{
743 			goto on_error;
744 		}
745 		string_index++;
746 	}
747 	for( byte_index = 0;
748 	     byte_index < 2;
749 	     byte_index++ )
750 	{
751 		internal_identifier->clock_sequence.lower <<= 4;
752 
753 		if( ( utf8_string[ string_index ] >= (uint8_t) '0' )
754 		 && ( utf8_string[ string_index ] <= (uint8_t) '9' ) )
755 		{
756 			internal_identifier->clock_sequence.lower |= utf8_string[ string_index ] - (uint8_t) '0';
757 		}
758 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
759 		      && ( utf8_string[ string_index ] >= (uint8_t) 'a' )
760 		      && ( utf8_string[ string_index ] <= (uint8_t) 'f' ) )
761 		{
762 			internal_identifier->clock_sequence.lower |= utf8_string[ string_index ] - (uint8_t) 'a' + 10;
763 		}
764 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
765 		      && ( utf8_string[ string_index ] >= (uint8_t) 'A' )
766 		      && ( utf8_string[ string_index ] <= (uint8_t) 'F' ) )
767 		{
768 			internal_identifier->clock_sequence.lower |= utf8_string[ string_index ] - (uint8_t) 'A' + 10;
769 		}
770 		else
771 		{
772 			goto on_error;
773 		}
774 		string_index++;
775 	}
776 	if( utf8_string[ string_index ] != (uint8_t) '-' )
777 	{
778 		goto on_error;
779 	}
780 	string_index++;
781 
782 	for( byte_index = 0;
783 	     byte_index < 12;
784 	     byte_index++ )
785 	{
786 		node_index = byte_index / 2;
787 
788 		internal_identifier->node[ node_index ] <<= 4;
789 
790 		if( ( utf8_string[ string_index ] >= (uint8_t) '0' )
791 		 && ( utf8_string[ string_index ] <= (uint8_t) '9' ) )
792 		{
793 			internal_identifier->node[ node_index ] |= utf8_string[ string_index ] - (uint8_t) '0';
794 		}
795 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
796 		      && ( utf8_string[ string_index ] >= (uint8_t) 'a' )
797 		      && ( utf8_string[ string_index ] <= (uint8_t) 'f' ) )
798 		{
799 			internal_identifier->node[ node_index ] |= utf8_string[ string_index ] - (uint8_t) 'a' + 10;
800 		}
801 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
802 		      && ( utf8_string[ string_index ] >= (uint8_t) 'A' )
803 		      && ( utf8_string[ string_index ] <= (uint8_t) 'F' ) )
804 		{
805 			internal_identifier->node[ node_index ] |= utf8_string[ string_index ] - (uint8_t) 'A' + 10;
806 		}
807 		else
808 		{
809 			goto on_error;
810 		}
811 		string_index++;
812 	}
813 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
814 	{
815 		if( utf8_string[ string_index ] != (uint8_t) '}' )
816 		{
817 			goto on_error;
818 		}
819 		string_index++;
820 	}
821 	*utf8_string_index = string_index;
822 
823 	return( 1 );
824 
825 on_error:
826 	libcerror_error_set(
827 	 error,
828 	 LIBCERROR_ERROR_DOMAIN_RUNTIME,
829 	 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
830 	 "%s: unsupported character value: 0x%02" PRIx8 " at index: %d.",
831 	 function,
832 	 utf8_string[ string_index ],
833 	 string_index );
834 
835 	return( -1 );
836 }
837 
838 /* Copies the identifier to an UTF-8 encoded string
839  * The string size should include the end of string character
840  * Returns 1 if successful or -1 on error
841  */
libfguid_identifier_copy_to_utf8_string(libfguid_identifier_t * identifier,uint8_t * utf8_string,size_t utf8_string_size,uint32_t string_format_flags,libcerror_error_t ** error)842 int libfguid_identifier_copy_to_utf8_string(
843      libfguid_identifier_t *identifier,
844      uint8_t *utf8_string,
845      size_t utf8_string_size,
846      uint32_t string_format_flags,
847      libcerror_error_t **error )
848 {
849 	static char *function    = "libfguid_identifier_copy_to_utf8_string";
850 	size_t utf8_string_index = 0;
851 
852 	if( libfguid_identifier_copy_to_utf8_string_with_index(
853 	     identifier,
854 	     utf8_string,
855 	     utf8_string_size,
856 	     &utf8_string_index,
857 	     string_format_flags,
858 	     error ) != 1 )
859 	{
860 		libcerror_error_set(
861 		 error,
862 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
863 		 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
864 		 "%s: unable to copy identifier to UTF-8 string.",
865 		 function );
866 
867 		return( -1 );
868 	}
869 	return( 1 );
870 }
871 
872 /* Copies the identifier to an UTF-8 encoded string
873  * The string size should include the end of string character
874  * Returns 1 if successful or -1 on error
875  */
libfguid_identifier_copy_to_utf8_string_with_index(libfguid_identifier_t * identifier,uint8_t * utf8_string,size_t utf8_string_size,size_t * utf8_string_index,uint32_t string_format_flags,libcerror_error_t ** error)876 int libfguid_identifier_copy_to_utf8_string_with_index(
877      libfguid_identifier_t *identifier,
878      uint8_t *utf8_string,
879      size_t utf8_string_size,
880      size_t *utf8_string_index,
881      uint32_t string_format_flags,
882      libcerror_error_t **error )
883 {
884 	libfguid_internal_identifier_t *internal_identifier = NULL;
885 	static char *function                               = "libfguid_identifier_copy_to_utf8_string_with_index";
886 	size_t string_index                                 = 0;
887 	size_t string_size                                  = 0;
888 	uint32_t required_flags                             = 0;
889 	uint32_t supported_flags                            = 0;
890 	uint8_t byte_value                                  = 0;
891 	uint8_t node_index                                  = 0;
892 	int8_t byte_shift                                   = 0;
893 
894 	if( identifier == NULL )
895 	{
896 		libcerror_error_set(
897 		 error,
898 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
899 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
900 		 "%s: invalid identifier.",
901 		 function );
902 
903 		return( -1 );
904 	}
905 	internal_identifier = (libfguid_internal_identifier_t *) identifier;
906 
907 	if( utf8_string == NULL )
908 	{
909 		libcerror_error_set(
910 		 error,
911 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
912 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
913 		 "%s: invalid UTF-8.",
914 		 function );
915 
916 		return( -1 );
917 	}
918 	if( utf8_string_size > (size_t) SSIZE_MAX )
919 	{
920 		libcerror_error_set(
921 		 error,
922 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
923 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
924 		 "%s: UTF-8 string size exceeds maximum.",
925 		 function );
926 
927 		return( -1 );
928 	}
929 	if( utf8_string_index == NULL )
930 	{
931 		libcerror_error_set(
932 		 error,
933 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
934 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
935 		 "%s: invalid UTF-8 index.",
936 		 function );
937 
938 		return( -1 );
939 	}
940 	required_flags = LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE
941 	               | LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE;
942 
943 	if( ( string_format_flags & required_flags ) == 0 )
944 	{
945 		libcerror_error_set(
946 		 error,
947 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
948 		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
949 		 "%s: missing string format flags.",
950 		 function );
951 
952 		return( -1 );
953 	}
954 	supported_flags = required_flags
955 	                | LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES;
956 
957 	if( ( string_format_flags & ~( supported_flags ) ) != 0 )
958 	{
959 		libcerror_error_set(
960 		 error,
961 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
962 		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
963 		 "%s: unsupported string format flags: 0x%08" PRIx32 ".",
964 		 function,
965 		 string_format_flags );
966 
967 		return( -1 );
968 	}
969 	string_size = 37;
970 
971 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
972 	{
973 		string_size += 2;
974 	}
975 	string_index = *utf8_string_index;
976 
977 	if( ( string_index + string_size ) > utf8_string_size )
978 	{
979 		libcerror_error_set(
980 		 error,
981 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
982 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
983 		 "%s: UTF-8 string is too small.",
984 		 function );
985 
986 		return( -1 );
987 	}
988 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
989 	{
990 		utf8_string[ string_index++ ] = (uint8_t) '{';
991 	}
992 	byte_shift = 28;
993 
994 	do
995 	{
996 		byte_value = ( internal_identifier->time.lower >> byte_shift ) & 0x0f;
997 
998 		if( byte_value <= 9 )
999 		{
1000 			utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
1001 		}
1002 		else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1003 		{
1004 			utf8_string[ string_index++ ] = (uint8_t) 'A' + byte_value - 10;
1005 		}
1006 		else
1007 		{
1008 			utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
1009 		}
1010 		byte_shift -= 4;
1011 	}
1012 	while( byte_shift >= 0 );
1013 
1014 	utf8_string[ string_index++ ] = (uint8_t) '-';
1015 
1016 	byte_shift = 12;
1017 
1018 	do
1019 	{
1020 		byte_value = ( internal_identifier->time.middle >> byte_shift ) & 0x0f;
1021 
1022 		if( byte_value <= 9 )
1023 		{
1024 			utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
1025 		}
1026 		else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1027 		{
1028 			utf8_string[ string_index++ ] = (uint8_t) 'A' + byte_value - 10;
1029 		}
1030 		else
1031 		{
1032 			utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
1033 		}
1034 		byte_shift -= 4;
1035 	}
1036 	while( byte_shift >= 0 );
1037 
1038 	utf8_string[ string_index++ ] = (uint8_t) '-';
1039 
1040 	byte_shift = 12;
1041 
1042 	do
1043 	{
1044 		byte_value = ( internal_identifier->time.upper >> byte_shift ) & 0x0f;
1045 
1046 		if( byte_value <= 9 )
1047 		{
1048 			utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
1049 		}
1050 		else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1051 		{
1052 			utf8_string[ string_index++ ] = (uint8_t) 'A' + byte_value - 10;
1053 		}
1054 		else
1055 		{
1056 			utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
1057 		}
1058 		byte_shift -= 4;
1059 	}
1060 	while( byte_shift >= 0 );
1061 
1062 	utf8_string[ string_index++ ] = (uint8_t) '-';
1063 
1064 	byte_shift = 4;
1065 
1066 	do
1067 	{
1068 		byte_value = ( internal_identifier->clock_sequence.upper >> byte_shift ) & 0x0f;
1069 
1070 		if( byte_value <= 9 )
1071 		{
1072 			utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
1073 		}
1074 		else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1075 		{
1076 			utf8_string[ string_index++ ] = (uint8_t) 'A' + byte_value - 10;
1077 		}
1078 		else
1079 		{
1080 			utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
1081 		}
1082 		byte_shift -= 4;
1083 	}
1084 	while( byte_shift >= 0 );
1085 
1086 	byte_shift = 4;
1087 
1088 	do
1089 	{
1090 		byte_value = ( internal_identifier->clock_sequence.lower >> byte_shift ) & 0x0f;
1091 
1092 		if( byte_value <= 9 )
1093 		{
1094 			utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
1095 		}
1096 		else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1097 		{
1098 			utf8_string[ string_index++ ] = (uint8_t) 'A' + byte_value - 10;
1099 		}
1100 		else
1101 		{
1102 			utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
1103 		}
1104 		byte_shift -= 4;
1105 	}
1106 	while( byte_shift >= 0 );
1107 
1108 	utf8_string[ string_index++ ] = (uint8_t) '-';
1109 
1110 	for( node_index = 0;
1111 	     node_index < 6;
1112 	     node_index++ )
1113 	{
1114 		byte_shift = 4;
1115 
1116 		do
1117 		{
1118 			byte_value = ( internal_identifier->node[ node_index ] >> byte_shift ) & 0x0f;
1119 
1120 			if( byte_value <= 9 )
1121 			{
1122 				utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
1123 			}
1124 			else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1125 			{
1126 				utf8_string[ string_index++ ] = (uint8_t) 'A' + byte_value - 10;
1127 			}
1128 			else
1129 			{
1130 				utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
1131 			}
1132 			byte_shift -= 4;
1133 		}
1134 		while( byte_shift >= 0 );
1135 	}
1136 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
1137 	{
1138 		utf8_string[ string_index++ ] = (uint8_t) '}';
1139 	}
1140 	utf8_string[ string_index++ ] = 0;
1141 
1142 	*utf8_string_index = string_index;
1143 
1144 	return( 1 );
1145 }
1146 
1147 /* Copies the identifier from an UTF-16 encoded string
1148  * Returns 1 if successful or -1 on error
1149  */
libfguid_identifier_copy_from_utf16_string(libfguid_identifier_t * identifier,const uint16_t * utf16_string,size_t utf16_string_size,uint32_t string_format_flags,libcerror_error_t ** error)1150 int libfguid_identifier_copy_from_utf16_string(
1151      libfguid_identifier_t *identifier,
1152      const uint16_t *utf16_string,
1153      size_t utf16_string_size,
1154      uint32_t string_format_flags,
1155      libcerror_error_t **error )
1156 {
1157 	static char *function     = "libfguid_identifier_copy_from_utf16_string";
1158 	size_t utf16_string_index = 0;
1159 
1160 	if( libfguid_identifier_copy_from_utf16_string_with_index(
1161 	     identifier,
1162 	     utf16_string,
1163 	     utf16_string_size,
1164 	     &utf16_string_index,
1165 	     string_format_flags,
1166 	     error ) != 1 )
1167 	{
1168 		libcerror_error_set(
1169 		 error,
1170 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1171 		 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1172 		 "%s: unable to copy identifier from UTF-16 string.",
1173 		 function );
1174 
1175 		return( -1 );
1176 	}
1177 	return( 1 );
1178 }
1179 
1180 /* Copies the identifier from an UTF-16 encoded string
1181  * Returns 1 if successful or -1 on error
1182  */
libfguid_identifier_copy_from_utf16_string_with_index(libfguid_identifier_t * identifier,const uint16_t * utf16_string,size_t utf16_string_length,size_t * utf16_string_index,uint32_t string_format_flags,libcerror_error_t ** error)1183 int libfguid_identifier_copy_from_utf16_string_with_index(
1184      libfguid_identifier_t *identifier,
1185      const uint16_t *utf16_string,
1186      size_t utf16_string_length,
1187      size_t *utf16_string_index,
1188      uint32_t string_format_flags,
1189      libcerror_error_t **error )
1190 {
1191 	libfguid_internal_identifier_t *internal_identifier = NULL;
1192 	static char *function                               = "libfguid_identifier_copy_from_utf16_string_with_index";
1193 	size_t byte_index                                   = 0;
1194 	size_t node_index                                   = 0;
1195 	size_t string_index                                 = 0;
1196 	size_t string_length                                = 0;
1197 	uint32_t required_flags                             = 0;
1198 	uint32_t supported_flags                            = 0;
1199 
1200 	if( identifier == NULL )
1201 	{
1202 		libcerror_error_set(
1203 		 error,
1204 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1205 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1206 		 "%s: invalid identifier.",
1207 		 function );
1208 
1209 		return( -1 );
1210 	}
1211 	internal_identifier = (libfguid_internal_identifier_t *) identifier;
1212 
1213 	if( utf16_string == NULL )
1214 	{
1215 		libcerror_error_set(
1216 		 error,
1217 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1218 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1219 		 "%s: invalid UTF-16 string.",
1220 		 function );
1221 
1222 		return( -1 );
1223 	}
1224 	if( utf16_string_length > (size_t) SSIZE_MAX )
1225 	{
1226 		libcerror_error_set(
1227 		 error,
1228 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1229 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1230 		 "%s: invalid UTF-16 string size value exceeds maximum.",
1231 		 function );
1232 
1233 		return( -1 );
1234 	}
1235 	if( utf16_string_index == NULL )
1236 	{
1237 		libcerror_error_set(
1238 		 error,
1239 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1240 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1241 		 "%s: invalid UTF-16 index.",
1242 		 function );
1243 
1244 		return( -1 );
1245 	}
1246 	required_flags = LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE
1247 	               | LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE;
1248 
1249 	if( ( string_format_flags & required_flags ) == 0 )
1250 	{
1251 		libcerror_error_set(
1252 		 error,
1253 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1254 		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1255 		 "%s: missing string format flags.",
1256 		 function );
1257 
1258 		return( -1 );
1259 	}
1260 	supported_flags = required_flags
1261 	                | LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES;
1262 
1263 	if( ( string_format_flags & ~( supported_flags ) ) != 0 )
1264 	{
1265 		libcerror_error_set(
1266 		 error,
1267 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1268 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1269 		 "%s: unsupported string format flags: 0x%08" PRIx32 ".",
1270 		 function,
1271 		 string_format_flags );
1272 
1273 		return( -1 );
1274 	}
1275 	string_length = 36;
1276 
1277 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
1278 	{
1279 		string_length += 2;
1280 	}
1281 	string_index = *utf16_string_index;
1282 
1283 	if( ( string_index + string_length ) > utf16_string_length )
1284 	{
1285 		libcerror_error_set(
1286 		 error,
1287 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1288 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1289 		 "%s: UTF-16 string is too small.",
1290 		 function );
1291 
1292 		return( -1 );
1293 	}
1294 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
1295 	{
1296 		if( utf16_string[ string_index ] != (uint16_t) '{' )
1297 		{
1298 			goto on_error;
1299 		}
1300 		string_index++;
1301 	}
1302 	for( byte_index = 0;
1303 	     byte_index < 8;
1304 	     byte_index++ )
1305 	{
1306 		internal_identifier->time.lower <<= 4;
1307 
1308 		if( ( utf16_string[ string_index ] >= (uint16_t) '0' )
1309 		 && ( utf16_string[ string_index ] <= (uint16_t) '9' ) )
1310 		{
1311 			internal_identifier->time.lower |= utf16_string[ string_index ] - (uint16_t) '0';
1312 		}
1313 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
1314 		      && ( utf16_string[ string_index ] >= (uint16_t) 'a' )
1315 		      && ( utf16_string[ string_index ] <= (uint16_t) 'f' ) )
1316 		{
1317 			internal_identifier->time.lower |= utf16_string[ string_index ] - (uint16_t) 'a' + 10;
1318 		}
1319 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1320 		      && ( utf16_string[ string_index ] >= (uint16_t) 'A' )
1321 		      && ( utf16_string[ string_index ] <= (uint16_t) 'F' ) )
1322 		{
1323 			internal_identifier->time.lower |= utf16_string[ string_index ] - (uint16_t) 'A' + 10;
1324 		}
1325 		else
1326 		{
1327 			goto on_error;
1328 		}
1329 		string_index++;
1330 	}
1331 	if( utf16_string[ string_index ] != (uint16_t) '-' )
1332 	{
1333 		goto on_error;
1334 	}
1335 	string_index++;
1336 
1337 	for( byte_index = 0;
1338 	     byte_index < 4;
1339 	     byte_index++ )
1340 	{
1341 		internal_identifier->time.middle <<= 4;
1342 
1343 		if( ( utf16_string[ string_index ] >= (uint16_t) '0' )
1344 		 && ( utf16_string[ string_index ] <= (uint16_t) '9' ) )
1345 		{
1346 			internal_identifier->time.middle |= utf16_string[ string_index ] - (uint16_t) '0';
1347 		}
1348 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
1349 		      && ( utf16_string[ string_index ] >= (uint16_t) 'a' )
1350 		      && ( utf16_string[ string_index ] <= (uint16_t) 'f' ) )
1351 		{
1352 			internal_identifier->time.middle |= utf16_string[ string_index ] - (uint16_t) 'a' + 10;
1353 		}
1354 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1355 		      && ( utf16_string[ string_index ] >= (uint16_t) 'A' )
1356 		      && ( utf16_string[ string_index ] <= (uint16_t) 'F' ) )
1357 		{
1358 			internal_identifier->time.middle |= utf16_string[ string_index ] - (uint16_t) 'A' + 10;
1359 		}
1360 		else
1361 		{
1362 			goto on_error;
1363 		}
1364 		string_index++;
1365 	}
1366 	if( utf16_string[ string_index ] != (uint16_t) '-' )
1367 	{
1368 		goto on_error;
1369 	}
1370 	string_index++;
1371 
1372 	for( byte_index = 0;
1373 	     byte_index < 4;
1374 	     byte_index++ )
1375 	{
1376 		internal_identifier->time.upper <<= 4;
1377 
1378 		if( ( utf16_string[ string_index ] >= (uint16_t) '0' )
1379 		 && ( utf16_string[ string_index ] <= (uint16_t) '9' ) )
1380 		{
1381 			internal_identifier->time.upper |= utf16_string[ string_index ] - (uint16_t) '0';
1382 		}
1383 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
1384 		      && ( utf16_string[ string_index ] >= (uint16_t) 'a' )
1385 		      && ( utf16_string[ string_index ] <= (uint16_t) 'f' ) )
1386 		{
1387 			internal_identifier->time.upper |= utf16_string[ string_index ] - (uint16_t) 'a' + 10;
1388 		}
1389 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1390 		      && ( utf16_string[ string_index ] >= (uint16_t) 'A' )
1391 		      && ( utf16_string[ string_index ] <= (uint16_t) 'F' ) )
1392 		{
1393 			internal_identifier->time.upper |= utf16_string[ string_index ] - (uint16_t) 'A' + 10;
1394 		}
1395 		else
1396 		{
1397 			goto on_error;
1398 		}
1399 		string_index++;
1400 	}
1401 	if( utf16_string[ string_index ] != (uint16_t) '-' )
1402 	{
1403 		goto on_error;
1404 	}
1405 	string_index++;
1406 
1407 	for( byte_index = 0;
1408 	     byte_index < 2;
1409 	     byte_index++ )
1410 	{
1411 		internal_identifier->clock_sequence.upper <<= 4;
1412 
1413 		if( ( utf16_string[ string_index ] >= (uint16_t) '0' )
1414 		 && ( utf16_string[ string_index ] <= (uint16_t) '9' ) )
1415 		{
1416 			internal_identifier->clock_sequence.upper |= utf16_string[ string_index ] - (uint16_t) '0';
1417 		}
1418 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
1419 		      && ( utf16_string[ string_index ] >= (uint16_t) 'a' )
1420 		      && ( utf16_string[ string_index ] <= (uint16_t) 'f' ) )
1421 		{
1422 			internal_identifier->clock_sequence.upper |= utf16_string[ string_index ] - (uint16_t) 'a' + 10;
1423 		}
1424 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1425 		      && ( utf16_string[ string_index ] >= (uint16_t) 'A' )
1426 		      && ( utf16_string[ string_index ] <= (uint16_t) 'F' ) )
1427 		{
1428 			internal_identifier->clock_sequence.upper |= utf16_string[ string_index ] - (uint16_t) 'A' + 10;
1429 		}
1430 		else
1431 		{
1432 			goto on_error;
1433 		}
1434 		string_index++;
1435 	}
1436 	for( byte_index = 0;
1437 	     byte_index < 2;
1438 	     byte_index++ )
1439 	{
1440 		internal_identifier->clock_sequence.lower <<= 4;
1441 
1442 		if( ( utf16_string[ string_index ] >= (uint16_t) '0' )
1443 		 && ( utf16_string[ string_index ] <= (uint16_t) '9' ) )
1444 		{
1445 			internal_identifier->clock_sequence.lower |= utf16_string[ string_index ] - (uint16_t) '0';
1446 		}
1447 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
1448 		      && ( utf16_string[ string_index ] >= (uint16_t) 'a' )
1449 		      && ( utf16_string[ string_index ] <= (uint16_t) 'f' ) )
1450 		{
1451 			internal_identifier->clock_sequence.lower |= utf16_string[ string_index ] - (uint16_t) 'a' + 10;
1452 		}
1453 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1454 		      && ( utf16_string[ string_index ] >= (uint16_t) 'A' )
1455 		      && ( utf16_string[ string_index ] <= (uint16_t) 'F' ) )
1456 		{
1457 			internal_identifier->clock_sequence.lower |= utf16_string[ string_index ] - (uint16_t) 'A' + 10;
1458 		}
1459 		else
1460 		{
1461 			goto on_error;
1462 		}
1463 		string_index++;
1464 	}
1465 	if( utf16_string[ string_index ] != (uint16_t) '-' )
1466 	{
1467 		goto on_error;
1468 	}
1469 	string_index++;
1470 
1471 	for( byte_index = 0;
1472 	     byte_index < 12;
1473 	     byte_index++ )
1474 	{
1475 		node_index = byte_index / 2;
1476 
1477 		internal_identifier->node[ node_index ] <<= 4;
1478 
1479 		if( ( utf16_string[ string_index ] >= (uint16_t) '0' )
1480 		 && ( utf16_string[ string_index ] <= (uint16_t) '9' ) )
1481 		{
1482 			internal_identifier->node[ node_index ] |= utf16_string[ string_index ] - (uint16_t) '0';
1483 		}
1484 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
1485 		      && ( utf16_string[ string_index ] >= (uint16_t) 'a' )
1486 		      && ( utf16_string[ string_index ] <= (uint16_t) 'f' ) )
1487 		{
1488 			internal_identifier->node[ node_index ] |= utf16_string[ string_index ] - (uint16_t) 'a' + 10;
1489 		}
1490 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1491 		      && ( utf16_string[ string_index ] >= (uint16_t) 'A' )
1492 		      && ( utf16_string[ string_index ] <= (uint16_t) 'F' ) )
1493 		{
1494 			internal_identifier->node[ node_index ] |= utf16_string[ string_index ] - (uint16_t) 'A' + 10;
1495 		}
1496 		else
1497 		{
1498 			goto on_error;
1499 		}
1500 		string_index++;
1501 	}
1502 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
1503 	{
1504 		if( utf16_string[ string_index ] != (uint16_t) '}' )
1505 		{
1506 			goto on_error;
1507 		}
1508 		string_index++;
1509 	}
1510 	*utf16_string_index = string_index;
1511 
1512 	return( 1 );
1513 
1514 on_error:
1515 	libcerror_error_set(
1516 	 error,
1517 	 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1518 	 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1519 	 "%s: unsupported character value: 0x%04" PRIx16 " at index: %d.",
1520 	 function,
1521 	 utf16_string[ string_index ],
1522 	 string_index );
1523 
1524 	return( -1 );
1525 }
1526 
1527 /* Copies the identifier to an UTF-16 encoded string
1528  * The string size should include the end of string character
1529  * Returns 1 if successful or -1 on error
1530  */
libfguid_identifier_copy_to_utf16_string(libfguid_identifier_t * identifier,uint16_t * utf16_string,size_t utf16_string_size,uint32_t string_format_flags,libcerror_error_t ** error)1531 int libfguid_identifier_copy_to_utf16_string(
1532      libfguid_identifier_t *identifier,
1533      uint16_t *utf16_string,
1534      size_t utf16_string_size,
1535      uint32_t string_format_flags,
1536      libcerror_error_t **error )
1537 {
1538 	static char *function     = "libfguid_identifier_copy_to_utf16_string";
1539 	size_t utf16_string_index = 0;
1540 
1541 	if( libfguid_identifier_copy_to_utf16_string_with_index(
1542 	     identifier,
1543 	     utf16_string,
1544 	     utf16_string_size,
1545 	     &utf16_string_index,
1546 	     string_format_flags,
1547 	     error ) != 1 )
1548 	{
1549 		libcerror_error_set(
1550 		 error,
1551 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1552 		 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1553 		 "%s: unable to copy identifier to UTF-16 string.",
1554 		 function );
1555 
1556 		return( -1 );
1557 	}
1558 	return( 1 );
1559 }
1560 
1561 /* Copies the identifier to an UTF-16 encoded string
1562  * The string size should include the end of string character
1563  * Returns 1 if successful or -1 on error
1564  */
libfguid_identifier_copy_to_utf16_string_with_index(libfguid_identifier_t * identifier,uint16_t * utf16_string,size_t utf16_string_size,size_t * utf16_string_index,uint32_t string_format_flags,libcerror_error_t ** error)1565 int libfguid_identifier_copy_to_utf16_string_with_index(
1566      libfguid_identifier_t *identifier,
1567      uint16_t *utf16_string,
1568      size_t utf16_string_size,
1569      size_t *utf16_string_index,
1570      uint32_t string_format_flags,
1571      libcerror_error_t **error )
1572 {
1573 	libfguid_internal_identifier_t *internal_identifier = NULL;
1574 	static char *function                               = "libfguid_identifier_copy_to_utf16_string_with_index";
1575 	size_t string_index                                 = 0;
1576 	size_t string_size                                  = 0;
1577 	uint32_t required_flags                             = 0;
1578 	uint32_t supported_flags                            = 0;
1579 	uint8_t byte_value                                  = 0;
1580 	uint8_t node_index                                  = 0;
1581 	int8_t byte_shift                                   = 0;
1582 
1583 	if( identifier == NULL )
1584 	{
1585 		libcerror_error_set(
1586 		 error,
1587 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1588 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1589 		 "%s: invalid identifier.",
1590 		 function );
1591 
1592 		return( -1 );
1593 	}
1594 	internal_identifier = (libfguid_internal_identifier_t *) identifier;
1595 
1596 	if( utf16_string == NULL )
1597 	{
1598 		libcerror_error_set(
1599 		 error,
1600 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1601 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1602 		 "%s: invalid UTF-16.",
1603 		 function );
1604 
1605 		return( -1 );
1606 	}
1607 	if( utf16_string_size > (size_t) SSIZE_MAX )
1608 	{
1609 		libcerror_error_set(
1610 		 error,
1611 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1612 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1613 		 "%s: UTF-16 string size exceeds maximum.",
1614 		 function );
1615 
1616 		return( -1 );
1617 	}
1618 	if( utf16_string_index == NULL )
1619 	{
1620 		libcerror_error_set(
1621 		 error,
1622 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1623 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1624 		 "%s: invalid UTF-16 index.",
1625 		 function );
1626 
1627 		return( -1 );
1628 	}
1629 	required_flags = LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE
1630 	               | LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE;
1631 
1632 	if( ( string_format_flags & required_flags ) == 0 )
1633 	{
1634 		libcerror_error_set(
1635 		 error,
1636 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1637 		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1638 		 "%s: missing string format flags.",
1639 		 function );
1640 
1641 		return( -1 );
1642 	}
1643 	supported_flags = required_flags
1644 	                | LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES;
1645 
1646 	if( ( string_format_flags & ~( supported_flags ) ) != 0 )
1647 	{
1648 		libcerror_error_set(
1649 		 error,
1650 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1651 		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1652 		 "%s: unsupported string format flags: 0x%08" PRIx32 ".",
1653 		 function,
1654 		 string_format_flags );
1655 
1656 		return( -1 );
1657 	}
1658 	string_size = 37;
1659 
1660 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
1661 	{
1662 		string_size += 2;
1663 	}
1664 	string_index = *utf16_string_index;
1665 
1666 	if( ( string_index + string_size ) > utf16_string_size )
1667 	{
1668 		libcerror_error_set(
1669 		 error,
1670 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1671 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1672 		 "%s: UTF-16 string is too small.",
1673 		 function );
1674 
1675 		return( -1 );
1676 	}
1677 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
1678 	{
1679 		utf16_string[ string_index++ ] = (uint16_t) '{';
1680 	}
1681 	byte_shift = 28;
1682 
1683 	do
1684 	{
1685 		byte_value = ( internal_identifier->time.lower >> byte_shift ) & 0x0f;
1686 
1687 		if( byte_value <= 9 )
1688 		{
1689 			utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
1690 		}
1691 		else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1692 		{
1693 			utf16_string[ string_index++ ] = (uint16_t) 'A' + byte_value - 10;
1694 		}
1695 		else
1696 		{
1697 			utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
1698 		}
1699 		byte_shift -= 4;
1700 	}
1701 	while( byte_shift >= 0 );
1702 
1703 	utf16_string[ string_index++ ] = (uint16_t) '-';
1704 
1705 	byte_shift = 12;
1706 
1707 	do
1708 	{
1709 		byte_value = ( internal_identifier->time.middle >> byte_shift ) & 0x0f;
1710 
1711 		if( byte_value <= 9 )
1712 		{
1713 			utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
1714 		}
1715 		else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1716 		{
1717 			utf16_string[ string_index++ ] = (uint16_t) 'A' + byte_value - 10;
1718 		}
1719 		else
1720 		{
1721 			utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
1722 		}
1723 		byte_shift -= 4;
1724 	}
1725 	while( byte_shift >= 0 );
1726 
1727 	utf16_string[ string_index++ ] = (uint16_t) '-';
1728 
1729 	byte_shift = 12;
1730 
1731 	do
1732 	{
1733 		byte_value = ( internal_identifier->time.upper >> byte_shift ) & 0x0f;
1734 
1735 		if( byte_value <= 9 )
1736 		{
1737 			utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
1738 		}
1739 		else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1740 		{
1741 			utf16_string[ string_index++ ] = (uint16_t) 'A' + byte_value - 10;
1742 		}
1743 		else
1744 		{
1745 			utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
1746 		}
1747 		byte_shift -= 4;
1748 	}
1749 	while( byte_shift >= 0 );
1750 
1751 	utf16_string[ string_index++ ] = (uint16_t) '-';
1752 
1753 	byte_shift = 4;
1754 
1755 	do
1756 	{
1757 		byte_value = ( internal_identifier->clock_sequence.upper >> byte_shift ) & 0x0f;
1758 
1759 		if( byte_value <= 9 )
1760 		{
1761 			utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
1762 		}
1763 		else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1764 		{
1765 			utf16_string[ string_index++ ] = (uint16_t) 'A' + byte_value - 10;
1766 		}
1767 		else
1768 		{
1769 			utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
1770 		}
1771 		byte_shift -= 4;
1772 	}
1773 	while( byte_shift >= 0 );
1774 
1775 	byte_shift = 4;
1776 
1777 	do
1778 	{
1779 		byte_value = ( internal_identifier->clock_sequence.lower >> byte_shift ) & 0x0f;
1780 
1781 		if( byte_value <= 9 )
1782 		{
1783 			utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
1784 		}
1785 		else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1786 		{
1787 			utf16_string[ string_index++ ] = (uint16_t) 'A' + byte_value - 10;
1788 		}
1789 		else
1790 		{
1791 			utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
1792 		}
1793 		byte_shift -= 4;
1794 	}
1795 	while( byte_shift >= 0 );
1796 
1797 	utf16_string[ string_index++ ] = (uint16_t) '-';
1798 
1799 	for( node_index = 0;
1800 	     node_index < 6;
1801 	     node_index++ )
1802 	{
1803 		byte_shift = 4;
1804 
1805 		do
1806 		{
1807 			byte_value = ( internal_identifier->node[ node_index ] >> byte_shift ) & 0x0f;
1808 
1809 			if( byte_value <= 9 )
1810 			{
1811 				utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
1812 			}
1813 			else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
1814 			{
1815 				utf16_string[ string_index++ ] = (uint16_t) 'A' + byte_value - 10;
1816 			}
1817 			else
1818 			{
1819 				utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
1820 			}
1821 			byte_shift -= 4;
1822 		}
1823 		while( byte_shift >= 0 );
1824 	}
1825 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
1826 	{
1827 		utf16_string[ string_index++ ] = (uint16_t) '}';
1828 	}
1829 	utf16_string[ string_index++ ] = 0;
1830 
1831 	*utf16_string_index = string_index;
1832 
1833 	return( 1 );
1834 }
1835 
1836 /* Copies the identifier from an UTF-32 encoded string
1837  * Returns 1 if successful or -1 on error
1838  */
libfguid_identifier_copy_from_utf32_string(libfguid_identifier_t * identifier,const uint32_t * utf32_string,size_t utf32_string_size,uint32_t string_format_flags,libcerror_error_t ** error)1839 int libfguid_identifier_copy_from_utf32_string(
1840      libfguid_identifier_t *identifier,
1841      const uint32_t *utf32_string,
1842      size_t utf32_string_size,
1843      uint32_t string_format_flags,
1844      libcerror_error_t **error )
1845 {
1846 	static char *function     = "libfguid_identifier_copy_from_utf32_string";
1847 	size_t utf32_string_index = 0;
1848 
1849 	if( libfguid_identifier_copy_from_utf32_string_with_index(
1850 	     identifier,
1851 	     utf32_string,
1852 	     utf32_string_size,
1853 	     &utf32_string_index,
1854 	     string_format_flags,
1855 	     error ) != 1 )
1856 	{
1857 		libcerror_error_set(
1858 		 error,
1859 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1860 		 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1861 		 "%s: unable to copy identifier from UTF-32 string.",
1862 		 function );
1863 
1864 		return( -1 );
1865 	}
1866 	return( 1 );
1867 }
1868 
1869 /* Copies the identifier from an UTF-32 encoded string
1870  * Returns 1 if successful or -1 on error
1871  */
libfguid_identifier_copy_from_utf32_string_with_index(libfguid_identifier_t * identifier,const uint32_t * utf32_string,size_t utf32_string_length,size_t * utf32_string_index,uint32_t string_format_flags,libcerror_error_t ** error)1872 int libfguid_identifier_copy_from_utf32_string_with_index(
1873      libfguid_identifier_t *identifier,
1874      const uint32_t *utf32_string,
1875      size_t utf32_string_length,
1876      size_t *utf32_string_index,
1877      uint32_t string_format_flags,
1878      libcerror_error_t **error )
1879 {
1880 	libfguid_internal_identifier_t *internal_identifier = NULL;
1881 	static char *function                               = "libfguid_identifier_copy_from_utf32_string_with_index";
1882 	size_t byte_index                                   = 0;
1883 	size_t node_index                                   = 0;
1884 	size_t string_index                                 = 0;
1885 	size_t string_length                                = 0;
1886 	uint32_t required_flags                             = 0;
1887 	uint32_t supported_flags                            = 0;
1888 
1889 	if( identifier == NULL )
1890 	{
1891 		libcerror_error_set(
1892 		 error,
1893 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1894 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1895 		 "%s: invalid identifier.",
1896 		 function );
1897 
1898 		return( -1 );
1899 	}
1900 	internal_identifier = (libfguid_internal_identifier_t *) identifier;
1901 
1902 	if( utf32_string == NULL )
1903 	{
1904 		libcerror_error_set(
1905 		 error,
1906 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1907 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1908 		 "%s: invalid UTF-32 string.",
1909 		 function );
1910 
1911 		return( -1 );
1912 	}
1913 	if( utf32_string_length > (size_t) SSIZE_MAX )
1914 	{
1915 		libcerror_error_set(
1916 		 error,
1917 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1918 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1919 		 "%s: invalid UTF-32 string size value exceeds maximum.",
1920 		 function );
1921 
1922 		return( -1 );
1923 	}
1924 	if( utf32_string_index == NULL )
1925 	{
1926 		libcerror_error_set(
1927 		 error,
1928 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1929 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1930 		 "%s: invalid UTF-32 index.",
1931 		 function );
1932 
1933 		return( -1 );
1934 	}
1935 	required_flags = LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE
1936 	               | LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE;
1937 
1938 	if( ( string_format_flags & required_flags ) == 0 )
1939 	{
1940 		libcerror_error_set(
1941 		 error,
1942 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1943 		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1944 		 "%s: missing string format flags.",
1945 		 function );
1946 
1947 		return( -1 );
1948 	}
1949 	supported_flags = required_flags
1950 	                | LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES;
1951 
1952 	if( ( string_format_flags & ~( supported_flags ) ) != 0 )
1953 	{
1954 		libcerror_error_set(
1955 		 error,
1956 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1957 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1958 		 "%s: unsupported string format flags: 0x%08" PRIx32 ".",
1959 		 function,
1960 		 string_format_flags );
1961 
1962 		return( -1 );
1963 	}
1964 	string_length = 36;
1965 
1966 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
1967 	{
1968 		string_length += 2;
1969 	}
1970 	string_index = *utf32_string_index;
1971 
1972 	if( ( string_index + string_length ) > utf32_string_length )
1973 	{
1974 		libcerror_error_set(
1975 		 error,
1976 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1977 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1978 		 "%s: UTF-32 string is too small.",
1979 		 function );
1980 
1981 		return( -1 );
1982 	}
1983 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
1984 	{
1985 		if( utf32_string[ string_index ] != (uint32_t) '{' )
1986 		{
1987 			goto on_error;
1988 		}
1989 		string_index++;
1990 	}
1991 	for( byte_index = 0;
1992 	     byte_index < 8;
1993 	     byte_index++ )
1994 	{
1995 		internal_identifier->time.lower <<= 4;
1996 
1997 		if( ( utf32_string[ string_index ] >= (uint32_t) '0' )
1998 		 && ( utf32_string[ string_index ] <= (uint32_t) '9' ) )
1999 		{
2000 			internal_identifier->time.lower |= utf32_string[ string_index ] - (uint32_t) '0';
2001 		}
2002 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
2003 		      && ( utf32_string[ string_index ] >= (uint32_t) 'a' )
2004 		      && ( utf32_string[ string_index ] <= (uint32_t) 'f' ) )
2005 		{
2006 			internal_identifier->time.lower |= utf32_string[ string_index ] - (uint32_t) 'a' + 10;
2007 		}
2008 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
2009 		      && ( utf32_string[ string_index ] >= (uint32_t) 'A' )
2010 		      && ( utf32_string[ string_index ] <= (uint32_t) 'F' ) )
2011 		{
2012 			internal_identifier->time.lower |= utf32_string[ string_index ] - (uint32_t) 'A' + 10;
2013 		}
2014 		else
2015 		{
2016 			goto on_error;
2017 		}
2018 		string_index++;
2019 	}
2020 	if( utf32_string[ string_index ] != (uint32_t) '-' )
2021 	{
2022 		goto on_error;
2023 	}
2024 	string_index++;
2025 
2026 	for( byte_index = 0;
2027 	     byte_index < 4;
2028 	     byte_index++ )
2029 	{
2030 		internal_identifier->time.middle <<= 4;
2031 
2032 		if( ( utf32_string[ string_index ] >= (uint32_t) '0' )
2033 		 && ( utf32_string[ string_index ] <= (uint32_t) '9' ) )
2034 		{
2035 			internal_identifier->time.middle |= utf32_string[ string_index ] - (uint32_t) '0';
2036 		}
2037 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
2038 		      && ( utf32_string[ string_index ] >= (uint32_t) 'a' )
2039 		      && ( utf32_string[ string_index ] <= (uint32_t) 'f' ) )
2040 		{
2041 			internal_identifier->time.middle |= utf32_string[ string_index ] - (uint32_t) 'a' + 10;
2042 		}
2043 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
2044 		      && ( utf32_string[ string_index ] >= (uint32_t) 'A' )
2045 		      && ( utf32_string[ string_index ] <= (uint32_t) 'F' ) )
2046 		{
2047 			internal_identifier->time.middle |= utf32_string[ string_index ] - (uint32_t) 'A' + 10;
2048 		}
2049 		else
2050 		{
2051 			goto on_error;
2052 		}
2053 		string_index++;
2054 	}
2055 	if( utf32_string[ string_index ] != (uint32_t) '-' )
2056 	{
2057 		goto on_error;
2058 	}
2059 	string_index++;
2060 
2061 	for( byte_index = 0;
2062 	     byte_index < 4;
2063 	     byte_index++ )
2064 	{
2065 		internal_identifier->time.upper <<= 4;
2066 
2067 		if( ( utf32_string[ string_index ] >= (uint32_t) '0' )
2068 		 && ( utf32_string[ string_index ] <= (uint32_t) '9' ) )
2069 		{
2070 			internal_identifier->time.upper |= utf32_string[ string_index ] - (uint32_t) '0';
2071 		}
2072 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
2073 		      && ( utf32_string[ string_index ] >= (uint32_t) 'a' )
2074 		      && ( utf32_string[ string_index ] <= (uint32_t) 'f' ) )
2075 		{
2076 			internal_identifier->time.upper |= utf32_string[ string_index ] - (uint32_t) 'a' + 10;
2077 		}
2078 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
2079 		      && ( utf32_string[ string_index ] >= (uint32_t) 'A' )
2080 		      && ( utf32_string[ string_index ] <= (uint32_t) 'F' ) )
2081 		{
2082 			internal_identifier->time.upper |= utf32_string[ string_index ] - (uint32_t) 'A' + 10;
2083 		}
2084 		else
2085 		{
2086 			goto on_error;
2087 		}
2088 		string_index++;
2089 	}
2090 	if( utf32_string[ string_index ] != (uint32_t) '-' )
2091 	{
2092 		goto on_error;
2093 	}
2094 	string_index++;
2095 
2096 	for( byte_index = 0;
2097 	     byte_index < 2;
2098 	     byte_index++ )
2099 	{
2100 		internal_identifier->clock_sequence.upper <<= 4;
2101 
2102 		if( ( utf32_string[ string_index ] >= (uint32_t) '0' )
2103 		 && ( utf32_string[ string_index ] <= (uint32_t) '9' ) )
2104 		{
2105 			internal_identifier->clock_sequence.upper |= utf32_string[ string_index ] - (uint32_t) '0';
2106 		}
2107 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
2108 		      && ( utf32_string[ string_index ] >= (uint32_t) 'a' )
2109 		      && ( utf32_string[ string_index ] <= (uint32_t) 'f' ) )
2110 		{
2111 			internal_identifier->clock_sequence.upper |= utf32_string[ string_index ] - (uint32_t) 'a' + 10;
2112 		}
2113 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
2114 		      && ( utf32_string[ string_index ] >= (uint32_t) 'A' )
2115 		      && ( utf32_string[ string_index ] <= (uint32_t) 'F' ) )
2116 		{
2117 			internal_identifier->clock_sequence.upper |= utf32_string[ string_index ] - (uint32_t) 'A' + 10;
2118 		}
2119 		else
2120 		{
2121 			goto on_error;
2122 		}
2123 		string_index++;
2124 	}
2125 	for( byte_index = 0;
2126 	     byte_index < 2;
2127 	     byte_index++ )
2128 	{
2129 		internal_identifier->clock_sequence.lower <<= 4;
2130 
2131 		if( ( utf32_string[ string_index ] >= (uint32_t) '0' )
2132 		 && ( utf32_string[ string_index ] <= (uint32_t) '9' ) )
2133 		{
2134 			internal_identifier->clock_sequence.lower |= utf32_string[ string_index ] - (uint32_t) '0';
2135 		}
2136 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
2137 		      && ( utf32_string[ string_index ] >= (uint32_t) 'a' )
2138 		      && ( utf32_string[ string_index ] <= (uint32_t) 'f' ) )
2139 		{
2140 			internal_identifier->clock_sequence.lower |= utf32_string[ string_index ] - (uint32_t) 'a' + 10;
2141 		}
2142 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
2143 		      && ( utf32_string[ string_index ] >= (uint32_t) 'A' )
2144 		      && ( utf32_string[ string_index ] <= (uint32_t) 'F' ) )
2145 		{
2146 			internal_identifier->clock_sequence.lower |= utf32_string[ string_index ] - (uint32_t) 'A' + 10;
2147 		}
2148 		else
2149 		{
2150 			goto on_error;
2151 		}
2152 		string_index++;
2153 	}
2154 	if( utf32_string[ string_index ] != (uint32_t) '-' )
2155 	{
2156 		goto on_error;
2157 	}
2158 	string_index++;
2159 
2160 	for( byte_index = 0;
2161 	     byte_index < 12;
2162 	     byte_index++ )
2163 	{
2164 		node_index = byte_index / 2;
2165 
2166 		internal_identifier->node[ node_index ] <<= 4;
2167 
2168 		if( ( utf32_string[ string_index ] >= (uint32_t) '0' )
2169 		 && ( utf32_string[ string_index ] <= (uint32_t) '9' ) )
2170 		{
2171 			internal_identifier->node[ node_index ] |= utf32_string[ string_index ] - (uint32_t) '0';
2172 		}
2173 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE ) != 0 )
2174 		      && ( utf32_string[ string_index ] >= (uint32_t) 'a' )
2175 		      && ( utf32_string[ string_index ] <= (uint32_t) 'f' ) )
2176 		{
2177 			internal_identifier->node[ node_index ] |= utf32_string[ string_index ] - (uint32_t) 'a' + 10;
2178 		}
2179 		else if( ( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
2180 		      && ( utf32_string[ string_index ] >= (uint32_t) 'A' )
2181 		      && ( utf32_string[ string_index ] <= (uint32_t) 'F' ) )
2182 		{
2183 			internal_identifier->node[ node_index ] |= utf32_string[ string_index ] - (uint32_t) 'A' + 10;
2184 		}
2185 		else
2186 		{
2187 			goto on_error;
2188 		}
2189 		string_index++;
2190 	}
2191 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
2192 	{
2193 		if( utf32_string[ string_index ] != (uint32_t) '}' )
2194 		{
2195 			goto on_error;
2196 		}
2197 		string_index++;
2198 	}
2199 	*utf32_string_index = string_index;
2200 
2201 	return( 1 );
2202 
2203 on_error:
2204 	libcerror_error_set(
2205 	 error,
2206 	 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2207 	 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2208 	 "%s: unsupported character value: 0x%08" PRIx32 " at index: %d.",
2209 	 function,
2210 	 utf32_string[ string_index ],
2211 	 string_index );
2212 
2213 	return( -1 );
2214 }
2215 
2216 /* Copies the identifier to an UTF-32 encoded string
2217  * The string size should include the end of string character
2218  * Returns 1 if successful or -1 on error
2219  */
libfguid_identifier_copy_to_utf32_string(libfguid_identifier_t * identifier,uint32_t * utf32_string,size_t utf32_string_size,uint32_t string_format_flags,libcerror_error_t ** error)2220 int libfguid_identifier_copy_to_utf32_string(
2221      libfguid_identifier_t *identifier,
2222      uint32_t *utf32_string,
2223      size_t utf32_string_size,
2224      uint32_t string_format_flags,
2225      libcerror_error_t **error )
2226 {
2227 	static char *function     = "libfguid_identifier_copy_to_utf32_string";
2228 	size_t utf32_string_index = 0;
2229 
2230 	if( libfguid_identifier_copy_to_utf32_string_with_index(
2231 	     identifier,
2232 	     utf32_string,
2233 	     utf32_string_size,
2234 	     &utf32_string_index,
2235 	     string_format_flags,
2236 	     error ) != 1 )
2237 	{
2238 		libcerror_error_set(
2239 		 error,
2240 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2241 		 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2242 		 "%s: unable to copy identifier to UTF-32 string.",
2243 		 function );
2244 
2245 		return( -1 );
2246 	}
2247 	return( 1 );
2248 }
2249 
2250 /* Copies the identifier to an UTF-32 encoded string
2251  * The string size should include the end of string character
2252  * Returns 1 if successful or -1 on error
2253  */
libfguid_identifier_copy_to_utf32_string_with_index(libfguid_identifier_t * identifier,uint32_t * utf32_string,size_t utf32_string_size,size_t * utf32_string_index,uint32_t string_format_flags,libcerror_error_t ** error)2254 int libfguid_identifier_copy_to_utf32_string_with_index(
2255      libfguid_identifier_t *identifier,
2256      uint32_t *utf32_string,
2257      size_t utf32_string_size,
2258      size_t *utf32_string_index,
2259      uint32_t string_format_flags,
2260      libcerror_error_t **error )
2261 {
2262 	libfguid_internal_identifier_t *internal_identifier = NULL;
2263 	static char *function                               = "libfguid_identifier_copy_to_utf32_string_with_index";
2264 	size_t string_index                                 = 0;
2265 	size_t string_size                                  = 0;
2266 	uint32_t required_flags                             = 0;
2267 	uint32_t supported_flags                            = 0;
2268 	uint8_t byte_value                                  = 0;
2269 	uint8_t node_index                                  = 0;
2270 	int8_t byte_shift                                   = 0;
2271 
2272 	if( identifier == NULL )
2273 	{
2274 		libcerror_error_set(
2275 		 error,
2276 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2277 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2278 		 "%s: invalid identifier.",
2279 		 function );
2280 
2281 		return( -1 );
2282 	}
2283 	internal_identifier = (libfguid_internal_identifier_t *) identifier;
2284 
2285 	if( utf32_string == NULL )
2286 	{
2287 		libcerror_error_set(
2288 		 error,
2289 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2290 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2291 		 "%s: invalid UTF-32.",
2292 		 function );
2293 
2294 		return( -1 );
2295 	}
2296 	if( utf32_string_size > (size_t) SSIZE_MAX )
2297 	{
2298 		libcerror_error_set(
2299 		 error,
2300 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2301 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2302 		 "%s: UTF-32 string size exceeds maximum.",
2303 		 function );
2304 
2305 		return( -1 );
2306 	}
2307 	if( utf32_string_index == NULL )
2308 	{
2309 		libcerror_error_set(
2310 		 error,
2311 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2312 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2313 		 "%s: invalid UTF-32 index.",
2314 		 function );
2315 
2316 		return( -1 );
2317 	}
2318 	required_flags = LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE
2319 	               | LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE;
2320 
2321 	if( ( string_format_flags & required_flags ) == 0 )
2322 	{
2323 		libcerror_error_set(
2324 		 error,
2325 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2326 		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2327 		 "%s: missing string format flags.",
2328 		 function );
2329 
2330 		return( -1 );
2331 	}
2332 	supported_flags = required_flags
2333 	                | LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES;
2334 
2335 	if( ( string_format_flags & ~( supported_flags ) ) != 0 )
2336 	{
2337 		libcerror_error_set(
2338 		 error,
2339 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2340 		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2341 		 "%s: unsupported string format flags: 0x%08" PRIx32 ".",
2342 		 function,
2343 		 string_format_flags );
2344 
2345 		return( -1 );
2346 	}
2347 	string_size = 37;
2348 
2349 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
2350 	{
2351 		string_size += 2;
2352 	}
2353 	string_index = *utf32_string_index;
2354 
2355 	if( ( string_index + string_size ) > utf32_string_size )
2356 	{
2357 		libcerror_error_set(
2358 		 error,
2359 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2360 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2361 		 "%s: UTF-32 string is too small.",
2362 		 function );
2363 
2364 		return( -1 );
2365 	}
2366 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
2367 	{
2368 		utf32_string[ string_index++ ] = (uint32_t) '{';
2369 	}
2370 	byte_shift = 28;
2371 
2372 	do
2373 	{
2374 		byte_value = ( internal_identifier->time.lower >> byte_shift ) & 0x0f;
2375 
2376 		if( byte_value <= 9 )
2377 		{
2378 			utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
2379 		}
2380 		else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
2381 		{
2382 			utf32_string[ string_index++ ] = (uint32_t) 'A' + byte_value - 10;
2383 		}
2384 		else
2385 		{
2386 			utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
2387 		}
2388 		byte_shift -= 4;
2389 	}
2390 	while( byte_shift >= 0 );
2391 
2392 	utf32_string[ string_index++ ] = (uint32_t) '-';
2393 
2394 	byte_shift = 12;
2395 
2396 	do
2397 	{
2398 		byte_value = ( internal_identifier->time.middle >> byte_shift ) & 0x0f;
2399 
2400 		if( byte_value <= 9 )
2401 		{
2402 			utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
2403 		}
2404 		else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
2405 		{
2406 			utf32_string[ string_index++ ] = (uint32_t) 'A' + byte_value - 10;
2407 		}
2408 		else
2409 		{
2410 			utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
2411 		}
2412 		byte_shift -= 4;
2413 	}
2414 	while( byte_shift >= 0 );
2415 
2416 	utf32_string[ string_index++ ] = (uint32_t) '-';
2417 
2418 	byte_shift = 12;
2419 
2420 	do
2421 	{
2422 		byte_value = ( internal_identifier->time.upper >> byte_shift ) & 0x0f;
2423 
2424 		if( byte_value <= 9 )
2425 		{
2426 			utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
2427 		}
2428 		else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
2429 		{
2430 			utf32_string[ string_index++ ] = (uint32_t) 'A' + byte_value - 10;
2431 		}
2432 		else
2433 		{
2434 			utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
2435 		}
2436 		byte_shift -= 4;
2437 	}
2438 	while( byte_shift >= 0 );
2439 
2440 	utf32_string[ string_index++ ] = (uint32_t) '-';
2441 
2442 	byte_shift = 4;
2443 
2444 	do
2445 	{
2446 		byte_value = ( internal_identifier->clock_sequence.upper >> byte_shift ) & 0x0f;
2447 
2448 		if( byte_value <= 9 )
2449 		{
2450 			utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
2451 		}
2452 		else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
2453 		{
2454 			utf32_string[ string_index++ ] = (uint32_t) 'A' + byte_value - 10;
2455 		}
2456 		else
2457 		{
2458 			utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
2459 		}
2460 		byte_shift -= 4;
2461 	}
2462 	while( byte_shift >= 0 );
2463 
2464 	byte_shift = 4;
2465 
2466 	do
2467 	{
2468 		byte_value = ( internal_identifier->clock_sequence.lower >> byte_shift ) & 0x0f;
2469 
2470 		if( byte_value <= 9 )
2471 		{
2472 			utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
2473 		}
2474 		else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
2475 		{
2476 			utf32_string[ string_index++ ] = (uint32_t) 'A' + byte_value - 10;
2477 		}
2478 		else
2479 		{
2480 			utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
2481 		}
2482 		byte_shift -= 4;
2483 	}
2484 	while( byte_shift >= 0 );
2485 
2486 	utf32_string[ string_index++ ] = (uint32_t) '-';
2487 
2488 	for( node_index = 0;
2489 	     node_index < 6;
2490 	     node_index++ )
2491 	{
2492 		byte_shift = 4;
2493 
2494 		do
2495 		{
2496 			byte_value = ( internal_identifier->node[ node_index ] >> byte_shift ) & 0x0f;
2497 
2498 			if( byte_value <= 9 )
2499 			{
2500 				utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
2501 			}
2502 			else if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_UPPER_CASE ) != 0 )
2503 			{
2504 				utf32_string[ string_index++ ] = (uint32_t) 'A' + byte_value - 10;
2505 			}
2506 			else
2507 			{
2508 				utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
2509 			}
2510 			byte_shift -= 4;
2511 		}
2512 		while( byte_shift >= 0 );
2513 	}
2514 	if( ( string_format_flags & LIBFGUID_STRING_FORMAT_FLAG_USE_SURROUNDING_BRACES ) != 0 )
2515 	{
2516 		utf32_string[ string_index++ ] = (uint32_t) '}';
2517 	}
2518 	utf32_string[ string_index++ ] = 0;
2519 
2520 	*utf32_string_index = string_index;
2521 
2522 	return( 1 );
2523 }
2524 
2525