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