1 /*
2  * SYSTEMTIME functions
3  *
4  * Copyright (C) 2009-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 "libfdatetime_definitions.h"
28 #include "libfdatetime_date_time_values.h"
29 #include "libfdatetime_libcerror.h"
30 #include "libfdatetime_systemtime.h"
31 #include "libfdatetime_types.h"
32 
33 /* Creates a SYSTEMTIME
34  * Make sure the value systemtime is referencing, is set to NULL
35  * Returns 1 if successful or -1 on error
36  */
libfdatetime_systemtime_initialize(libfdatetime_systemtime_t ** systemtime,libcerror_error_t ** error)37 int libfdatetime_systemtime_initialize(
38      libfdatetime_systemtime_t **systemtime,
39      libcerror_error_t **error )
40 {
41 	libfdatetime_internal_systemtime_t *internal_systemtime = NULL;
42 	static char *function                                   = "libfdatetime_systemtime_initialize";
43 
44 	if( systemtime == NULL )
45 	{
46 		libcerror_error_set(
47 		 error,
48 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
49 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
50 		 "%s: invalid SYSTEMTIME.",
51 		 function );
52 
53 		return( -1 );
54 	}
55 	if( *systemtime != NULL )
56 	{
57 		libcerror_error_set(
58 		 error,
59 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
60 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
61 		 "%s: invalid SYSTEMTIME value already set.",
62 		 function );
63 
64 		return( -1 );
65 	}
66 	internal_systemtime = memory_allocate_structure(
67 	                       libfdatetime_internal_systemtime_t );
68 
69 	if( internal_systemtime == NULL )
70 	{
71 		libcerror_error_set(
72 		 error,
73 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
74 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
75 		 "%s: unable to create SYSTEMTIME.",
76 		 function );
77 
78 		goto on_error;
79 	}
80 	if( memory_set(
81 	     internal_systemtime,
82 	     0,
83 	     sizeof( libfdatetime_internal_systemtime_t ) ) == NULL )
84 	{
85 		libcerror_error_set(
86 		 error,
87 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
88 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
89 		 "%s: unable to clear SYSTEMTIME.",
90 		 function );
91 
92 		goto on_error;
93 	}
94 	*systemtime = (libfdatetime_systemtime_t *) internal_systemtime;
95 
96 	return( 1 );
97 
98 on_error:
99 	if( internal_systemtime != NULL )
100 	{
101 		memory_free(
102 		 internal_systemtime );
103 	}
104 	return( -1 );
105 }
106 
107 /* Frees a SYSTEMTIME
108  * Returns 1 if successful or -1 on error
109  */
libfdatetime_systemtime_free(libfdatetime_systemtime_t ** systemtime,libcerror_error_t ** error)110 int libfdatetime_systemtime_free(
111      libfdatetime_systemtime_t **systemtime,
112      libcerror_error_t **error )
113 {
114 	libfdatetime_internal_systemtime_t *internal_systemtime = NULL;
115 	static char *function                                   = "libfdatetime_systemtime_free";
116 
117 	if( systemtime == NULL )
118 	{
119 		libcerror_error_set(
120 		 error,
121 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
122 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
123 		 "%s: invalid SYSTEMTIME.",
124 		 function );
125 
126 		return( -1 );
127 	}
128 	if( *systemtime != NULL )
129 	{
130 		internal_systemtime = (libfdatetime_internal_systemtime_t *) *systemtime;
131 		*systemtime         = NULL;
132 
133 		memory_free(
134 		 internal_systemtime );
135 	}
136 	return( 1 );
137 }
138 
139 /* Converts a byte stream into a systemtime
140  * Returns 1 if successful or -1 on error
141  */
libfdatetime_systemtime_copy_from_byte_stream(libfdatetime_systemtime_t * systemtime,const uint8_t * byte_stream,size_t byte_stream_size,int byte_order,libcerror_error_t ** error)142 int libfdatetime_systemtime_copy_from_byte_stream(
143      libfdatetime_systemtime_t *systemtime,
144      const uint8_t *byte_stream,
145      size_t byte_stream_size,
146      int byte_order,
147      libcerror_error_t **error )
148 {
149 	libfdatetime_internal_systemtime_t *internal_systemtime = NULL;
150 	static char *function                                   = "libfdatetime_systemtime_copy_from_byte_stream";
151 
152 	if( systemtime == NULL )
153 	{
154 		libcerror_error_set(
155 		 error,
156 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
157 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
158 		 "%s: invalid SYSTEMTIME.",
159 		 function );
160 
161 		return( -1 );
162 	}
163 	internal_systemtime = (libfdatetime_internal_systemtime_t *) systemtime;
164 
165 	if( byte_stream == NULL )
166 	{
167 		libcerror_error_set(
168 		 error,
169 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
170 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
171 		 "%s: invalid byte stream.",
172 		 function );
173 
174 		return( -1 );
175 	}
176 	if( byte_stream_size < 16 )
177 	{
178 		libcerror_error_set(
179 		 error,
180 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
181 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
182 		 "%s: byte stream too small.",
183 		 function );
184 
185 		return( -1 );
186 	}
187 	if( byte_stream_size > (size_t) SSIZE_MAX )
188 	{
189 		libcerror_error_set(
190 		 error,
191 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
192 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
193 		 "%s: byte stream size exceeds maximum.",
194 		 function );
195 
196 		return( -1 );
197 	}
198 	if( ( byte_order != LIBFDATETIME_ENDIAN_BIG )
199 	 && ( byte_order != LIBFDATETIME_ENDIAN_LITTLE ) )
200 	{
201 		libcerror_error_set(
202 		 error,
203 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
204 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
205 		 "%s: unsupported byte order.",
206 		 function );
207 
208 		return( -1 );
209 	}
210 	if( byte_order == LIBFDATETIME_ENDIAN_LITTLE )
211 	{
212 		byte_stream_copy_to_uint16_little_endian(
213 		 byte_stream,
214 		 internal_systemtime->year );
215 
216 		byte_stream += 2;
217 
218 		byte_stream_copy_to_uint16_little_endian(
219 		 byte_stream,
220 		 internal_systemtime->month );
221 
222 		byte_stream += 2;
223 
224 		byte_stream_copy_to_uint16_little_endian(
225 		 byte_stream,
226 		 internal_systemtime->day_of_week );
227 
228 		byte_stream += 2;
229 
230 		byte_stream_copy_to_uint16_little_endian(
231 		 byte_stream,
232 		 internal_systemtime->day_of_month );
233 
234 		byte_stream += 2;
235 
236 		byte_stream_copy_to_uint16_little_endian(
237 		 byte_stream,
238 		 internal_systemtime->hours );
239 
240 		byte_stream += 2;
241 
242 		byte_stream_copy_to_uint16_little_endian(
243 		 byte_stream,
244 		 internal_systemtime->minutes );
245 
246 		byte_stream += 2;
247 
248 		byte_stream_copy_to_uint16_little_endian(
249 		 byte_stream,
250 		 internal_systemtime->seconds );
251 
252 		byte_stream += 2;
253 
254 		byte_stream_copy_to_uint16_little_endian(
255 		 byte_stream,
256 		 internal_systemtime->milli_seconds );
257 	}
258 	else if( byte_order == LIBFDATETIME_ENDIAN_BIG )
259 	{
260 		byte_stream_copy_to_uint16_big_endian(
261 		 byte_stream,
262 		 internal_systemtime->year );
263 
264 		byte_stream += 2;
265 
266 		byte_stream_copy_to_uint16_big_endian(
267 		 byte_stream,
268 		 internal_systemtime->month );
269 
270 		byte_stream += 2;
271 
272 		byte_stream_copy_to_uint16_big_endian(
273 		 byte_stream,
274 		 internal_systemtime->day_of_week );
275 
276 		byte_stream += 2;
277 
278 		byte_stream_copy_to_uint16_big_endian(
279 		 byte_stream,
280 		 internal_systemtime->day_of_month );
281 
282 		byte_stream += 2;
283 
284 		byte_stream_copy_to_uint16_big_endian(
285 		 byte_stream,
286 		 internal_systemtime->hours );
287 
288 		byte_stream += 2;
289 
290 		byte_stream_copy_to_uint16_big_endian(
291 		 byte_stream,
292 		 internal_systemtime->minutes );
293 
294 		byte_stream += 2;
295 
296 		byte_stream_copy_to_uint16_big_endian(
297 		 byte_stream,
298 		 internal_systemtime->seconds );
299 
300 		byte_stream += 2;
301 
302 		byte_stream_copy_to_uint16_big_endian(
303 		 byte_stream,
304 		 internal_systemtime->milli_seconds );
305 	}
306 	return( 1 );
307 }
308 
309 /* Converts a SYSTEMTIME into date time values
310  * Returns 1 if successful or -1 on error
311  */
libfdatetime_internal_systemtime_copy_to_date_time_values(libfdatetime_internal_systemtime_t * internal_systemtime,libfdatetime_date_time_values_t * date_time_values,libcerror_error_t ** error)312 int libfdatetime_internal_systemtime_copy_to_date_time_values(
313      libfdatetime_internal_systemtime_t *internal_systemtime,
314      libfdatetime_date_time_values_t *date_time_values,
315      libcerror_error_t **error )
316 {
317 	static char *function = "libfdatetime_internal_systemtime_copy_to_date_time_values";
318 	uint8_t days_in_month = 0;
319 
320 	if( internal_systemtime == NULL )
321 	{
322 		libcerror_error_set(
323 		 error,
324 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
325 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
326 		 "%s: invalid SYSTEMTIME.",
327 		 function );
328 
329 		return( -1 );
330 	}
331 	if( date_time_values == NULL )
332 	{
333 		libcerror_error_set(
334 		 error,
335 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
336 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
337 		 "%s: invalid date time values.",
338 		 function );
339 
340 		return( -1 );
341 	}
342 	if( internal_systemtime->milli_seconds > 999 )
343 	{
344 		libcerror_error_set(
345 		 error,
346 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
347 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
348 		 "%s: invalid SYSTEMTIME - milli seconds value out of bounds.",
349 		 function );
350 
351 		return( -1 );
352 	}
353 	date_time_values->nano_seconds  = 0;
354 	date_time_values->micro_seconds = 0;
355 	date_time_values->milli_seconds = internal_systemtime->milli_seconds;
356 
357 	if( internal_systemtime->seconds > 59 )
358 	{
359 		libcerror_error_set(
360 		 error,
361 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
362 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
363 		 "%s: invalid SYSTEMTIME - seconds value out of bounds.",
364 		 function );
365 
366 		return( -1 );
367 	}
368 	date_time_values->seconds = (uint8_t) internal_systemtime->seconds;
369 
370 	if( internal_systemtime->minutes > 59 )
371 	{
372 		libcerror_error_set(
373 		 error,
374 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
375 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
376 		 "%s: invalid SYSTEMTIME - minutes value out of bounds.",
377 		 function );
378 
379 		return( -1 );
380 	}
381 	date_time_values->minutes = (uint8_t) internal_systemtime->minutes;
382 
383 	if( internal_systemtime->hours > 23 )
384 	{
385 		libcerror_error_set(
386 		 error,
387 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
388 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
389 		 "%s: invalid SYSTEMTIME - hours value out of bounds.",
390 		 function );
391 
392 		return( -1 );
393 	}
394 	date_time_values->hours = (uint8_t) internal_systemtime->hours;
395 
396 	if( internal_systemtime->year > 9999 )
397 	{
398 		libcerror_error_set(
399 		 error,
400 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
401 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
402 		 "%s: invalid SYSTEMTIME - year value out of bounds.",
403 		 function );
404 
405 		return( -1 );
406 	}
407 	date_time_values->year = (uint16_t) internal_systemtime->year;
408 
409 	if( ( internal_systemtime->month == 0 )
410 	 || ( internal_systemtime->month > 12 ) )
411 	{
412 		libcerror_error_set(
413 		 error,
414 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
415 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
416 		 "%s: invalid SYSTEMTIME - month value out of bounds.",
417 		 function );
418 
419 		return( -1 );
420 	}
421 	date_time_values->month = (uint8_t) internal_systemtime->month;
422 
423 	if( internal_systemtime->day_of_week > 6 )
424 	{
425 		libcerror_error_set(
426 		 error,
427 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
428 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
429 		 "%s: invalid SYSTEMTIME - day of week value out of bounds.",
430 		 function );
431 
432 		return( -1 );
433 	}
434 	/* February (2)
435 	 */
436 	if( date_time_values->month == 2 )
437 	{
438 		if( ( ( ( date_time_values->year % 4 ) == 0 )
439 		  &&  ( ( date_time_values->year % 100 ) != 0 ) )
440 		 || ( ( date_time_values->year % 400 ) == 0 ) )
441 		{
442 			days_in_month = 29;
443 		}
444 		else
445 		{
446 			days_in_month = 28;
447 		}
448 	}
449 	/* April (4), June (6), September (9), November (11)
450 	 */
451 	else if( ( date_time_values->month == 4 )
452 	      || ( date_time_values->month == 6 )
453 	      || ( date_time_values->month == 9 )
454 	      || ( date_time_values->month == 11 ) )
455 	{
456 		days_in_month = 30;
457 	}
458 	/* January (1), March (3), May (5), July (7), August (8), October (10), December (12)
459 	 */
460 	else if( ( date_time_values->month == 1 )
461 	      || ( date_time_values->month == 3 )
462 	      || ( date_time_values->month == 5 )
463 	      || ( date_time_values->month == 7 )
464 	      || ( date_time_values->month == 8 )
465 	      || ( date_time_values->month == 10 )
466 	      || ( date_time_values->month == 12 ) )
467 	{
468 		days_in_month = 31;
469 	}
470 	/* This should never happen, but just in case
471 	 */
472 	else
473 	{
474 		libcerror_error_set(
475 		 error,
476 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
477 		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
478 		 "%s: unsupported month: %d.",
479 		 function,
480 		 date_time_values->month );
481 
482 		return( -1 );
483 	}
484 	if( internal_systemtime->day_of_month > (uint16_t) days_in_month )
485 	{
486 		libcerror_error_set(
487 		 error,
488 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
489 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
490 		 "%s: invalid SYSTEMTIME - day of month value out of bounds.",
491 		 function );
492 
493 		return( -1 );
494 	}
495 	date_time_values->day = (uint8_t) internal_systemtime->day_of_month;
496 
497 	return( 1 );
498 }
499 
500 /* Deterimes the size of the string for the SYSTEMTIME
501  * The string size includes the end of string character
502  * Returns 1 if successful or -1 on error
503  */
libfdatetime_systemtime_get_string_size(libfdatetime_systemtime_t * systemtime,size_t * string_size,uint32_t string_format_flags,libcerror_error_t ** error)504 int libfdatetime_systemtime_get_string_size(
505      libfdatetime_systemtime_t *systemtime,
506      size_t *string_size,
507      uint32_t string_format_flags,
508      libcerror_error_t **error )
509 {
510 	libfdatetime_date_time_values_t date_time_values;
511 
512 	static char *function = "libfdatetime_systemtime_get_string_size";
513 	int result            = 0;
514 
515 	if( systemtime == NULL )
516 	{
517 		libcerror_error_set(
518 		 error,
519 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
520 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
521 		 "%s: invalid SYSTEMTIME.",
522 		 function );
523 
524 		return( -1 );
525 	}
526 	if( string_size == NULL )
527 	{
528 		libcerror_error_set(
529 		 error,
530 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
531 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
532 		 "%s: invalid string size.",
533 		 function );
534 
535 		return( -1 );
536 	}
537 	result = libfdatetime_internal_systemtime_copy_to_date_time_values(
538 	          (libfdatetime_internal_systemtime_t *) systemtime,
539 	          &date_time_values,
540 	          error );
541 
542 	if( result != 1 )
543 	{
544 #if defined( HAVE_DEBUG_OUTPUT )
545 		libcerror_error_set(
546 		 error,
547 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
548 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
549 		 "%s: unable to set date time values.",
550 		 function );
551 
552 /* TODO debug print error */
553 
554 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
555 
556 		if( ( error != NULL )
557 		 && ( *error != NULL ) )
558 		{
559 			libcerror_error_free(
560 			 error );
561 		}
562 	}
563 	else
564 	{
565 		result = libfdatetime_date_time_values_get_string_size(
566 		          &date_time_values,
567 		          string_size,
568 		          string_format_flags,
569 		          error );
570 
571 		if( result == -1 )
572 		{
573 			libcerror_error_set(
574 			 error,
575 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
576 			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
577 			 "%s: unable to get string size.",
578 			 function );
579 
580 			return( -1 );
581 		}
582 	}
583 	if( result != 1 )
584 	{
585 		/* Make sure the string can hold the hexadecimal representation of the SYSTEMTIME
586 		 */
587 		*string_size = 58;
588 	}
589 	return( 1 );
590 }
591 
592 /* Converts the SYSTEMTIME into an UTF-8 string in hexadecimal representation
593  * The string size should include the end of string character
594  * Returns 1 if successful or -1 on error
595  */
libfdatetime_internal_systemtime_copy_to_utf8_string_in_hexadecimal(libfdatetime_internal_systemtime_t * internal_systemtime,uint8_t * utf8_string,size_t utf8_string_size,size_t * utf8_string_index,libcerror_error_t ** error)596 int libfdatetime_internal_systemtime_copy_to_utf8_string_in_hexadecimal(
597      libfdatetime_internal_systemtime_t *internal_systemtime,
598      uint8_t *utf8_string,
599      size_t utf8_string_size,
600      size_t *utf8_string_index,
601      libcerror_error_t **error )
602 {
603 	static char *function = "libfdatetime_internal_systemtime_copy_to_utf8_string_in_hexadecimal";
604 	size_t string_index   = 0;
605 	uint8_t byte_value    = 0;
606 	int8_t byte_shift     = 0;
607 
608 	if( internal_systemtime == NULL )
609 	{
610 		libcerror_error_set(
611 		 error,
612 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
613 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
614 		 "%s: invalid SYSTEMTIME.",
615 		 function );
616 
617 		return( -1 );
618 	}
619 	if( utf8_string == NULL )
620 	{
621 		libcerror_error_set(
622 		 error,
623 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
624 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
625 		 "%s: invalid UTF-8 string.",
626 		 function );
627 
628 		return( -1 );
629 	}
630 	if( utf8_string_size > (size_t) SSIZE_MAX )
631 	{
632 		libcerror_error_set(
633 		 error,
634 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
635 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
636 		 "%s: invalid UTF-8 string size value exceeds maximum.",
637 		 function );
638 
639 		return( -1 );
640 	}
641 	if( utf8_string_index == NULL )
642 	{
643 		libcerror_error_set(
644 		 error,
645 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
646 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
647 		 "%s: invalid UTF-8 string index.",
648 		 function );
649 
650 		return( -1 );
651 	}
652 	if( ( utf8_string_size < 58 )
653 	 || ( *utf8_string_index > ( utf8_string_size - 58 ) ) )
654 	{
655 		libcerror_error_set(
656 		 error,
657 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
658 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
659 		 "%s: UTF-8 string is too small.",
660 		 function );
661 
662 		return( -1 );
663 	}
664 	string_index = *utf8_string_index;
665 
666 	utf8_string[ string_index++ ] = (uint8_t) '(';
667 	utf8_string[ string_index++ ] = (uint8_t) '0';
668 	utf8_string[ string_index++ ] = (uint8_t) 'x';
669 
670 	byte_shift = 14;
671 
672 	do
673 	{
674 		byte_value = ( internal_systemtime->year >> byte_shift ) & 0x0f;
675 
676 		if( byte_value <= 9 )
677 		{
678 			utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
679 		}
680 		else
681 		{
682 			utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
683 		}
684 		byte_shift -= 4;
685 	}
686 	while( byte_shift >= 0 );
687 
688 	utf8_string[ string_index++ ] = (uint8_t) ' ';
689 	utf8_string[ string_index++ ] = (uint8_t) '0';
690 	utf8_string[ string_index++ ] = (uint8_t) 'x';
691 
692 	byte_shift = 14;
693 
694 	do
695 	{
696 		byte_value = ( internal_systemtime->month >> byte_shift ) & 0x0f;
697 
698 		if( byte_value <= 9 )
699 		{
700 			utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
701 		}
702 		else
703 		{
704 			utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
705 		}
706 		byte_shift -= 4;
707 	}
708 	while( byte_shift >= 0 );
709 
710 	utf8_string[ string_index++ ] = (uint8_t) ' ';
711 	utf8_string[ string_index++ ] = (uint8_t) '0';
712 	utf8_string[ string_index++ ] = (uint8_t) 'x';
713 
714 	byte_shift = 14;
715 
716 	do
717 	{
718 		byte_value = ( internal_systemtime->day_of_week >> byte_shift ) & 0x0f;
719 
720 		if( byte_value <= 9 )
721 		{
722 			utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
723 		}
724 		else
725 		{
726 			utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
727 		}
728 		byte_shift -= 4;
729 	}
730 	while( byte_shift >= 0 );
731 
732 	utf8_string[ string_index++ ] = (uint8_t) ' ';
733 	utf8_string[ string_index++ ] = (uint8_t) '0';
734 	utf8_string[ string_index++ ] = (uint8_t) 'x';
735 
736 	byte_shift = 14;
737 
738 	do
739 	{
740 		byte_value = ( internal_systemtime->day_of_month >> byte_shift ) & 0x0f;
741 
742 		if( byte_value <= 9 )
743 		{
744 			utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
745 		}
746 		else
747 		{
748 			utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
749 		}
750 		byte_shift -= 4;
751 	}
752 	while( byte_shift >= 0 );
753 
754 	utf8_string[ string_index++ ] = (uint8_t) ' ';
755 	utf8_string[ string_index++ ] = (uint8_t) '0';
756 	utf8_string[ string_index++ ] = (uint8_t) 'x';
757 
758 	byte_shift = 14;
759 
760 	do
761 	{
762 		byte_value = ( internal_systemtime->hours >> byte_shift ) & 0x0f;
763 
764 		if( byte_value <= 9 )
765 		{
766 			utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
767 		}
768 		else
769 		{
770 			utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
771 		}
772 		byte_shift -= 4;
773 	}
774 	while( byte_shift >= 0 );
775 
776 	utf8_string[ string_index++ ] = (uint8_t) ' ';
777 	utf8_string[ string_index++ ] = (uint8_t) '0';
778 	utf8_string[ string_index++ ] = (uint8_t) 'x';
779 
780 	byte_shift = 14;
781 
782 	do
783 	{
784 		byte_value = ( internal_systemtime->minutes >> byte_shift ) & 0x0f;
785 
786 		if( byte_value <= 9 )
787 		{
788 			utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
789 		}
790 		else
791 		{
792 			utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
793 		}
794 		byte_shift -= 4;
795 	}
796 	while( byte_shift >= 0 );
797 
798 	utf8_string[ string_index++ ] = (uint8_t) ' ';
799 	utf8_string[ string_index++ ] = (uint8_t) '0';
800 	utf8_string[ string_index++ ] = (uint8_t) 'x';
801 
802 	byte_shift = 14;
803 
804 	do
805 	{
806 		byte_value = ( internal_systemtime->seconds >> byte_shift ) & 0x0f;
807 
808 		if( byte_value <= 9 )
809 		{
810 			utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
811 		}
812 		else
813 		{
814 			utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
815 		}
816 		byte_shift -= 4;
817 	}
818 	while( byte_shift >= 0 );
819 
820 	utf8_string[ string_index++ ] = (uint8_t) ' ';
821 	utf8_string[ string_index++ ] = (uint8_t) '0';
822 	utf8_string[ string_index++ ] = (uint8_t) 'x';
823 
824 	byte_shift = 14;
825 
826 	do
827 	{
828 		byte_value = ( internal_systemtime->milli_seconds >> byte_shift ) & 0x0f;
829 
830 		if( byte_value <= 9 )
831 		{
832 			utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
833 		}
834 		else
835 		{
836 			utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
837 		}
838 		byte_shift -= 4;
839 	}
840 	while( byte_shift >= 0 );
841 
842 	utf8_string[ string_index++ ] = (uint8_t) ')';
843 
844 	utf8_string[ string_index++ ] = 0;
845 
846 	*utf8_string_index = string_index;
847 
848 	return( 1 );
849 }
850 
851 /* Converts the SYSTEMTIME into an UTF-8 string
852  * The string size should include the end of string character
853  * Returns 1 if successful or -1 on error
854  */
libfdatetime_systemtime_copy_to_utf8_string(libfdatetime_systemtime_t * systemtime,uint8_t * utf8_string,size_t utf8_string_size,uint32_t string_format_flags,libcerror_error_t ** error)855 int libfdatetime_systemtime_copy_to_utf8_string(
856      libfdatetime_systemtime_t *systemtime,
857      uint8_t *utf8_string,
858      size_t utf8_string_size,
859      uint32_t string_format_flags,
860      libcerror_error_t **error )
861 {
862 	static char *function    = "libfdatetime_systemtime_copy_to_utf8_string";
863 	size_t utf8_string_index = 0;
864 
865 	if( libfdatetime_systemtime_copy_to_utf8_string_with_index(
866 	     systemtime,
867 	     utf8_string,
868 	     utf8_string_size,
869 	     &utf8_string_index,
870 	     string_format_flags,
871 	     error ) != 1 )
872 	{
873 		libcerror_error_set(
874 		 error,
875 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
876 		 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
877 		 "%s: unable to copy SYSTEMTIME to UTF-8 string.",
878 		 function );
879 
880 		return( -1 );
881 	}
882 	return( 1 );
883 }
884 
885 /* Converts the SYSTEMTIME into an UTF-8 string
886  * The string size should include the end of string character
887  * Returns 1 if successful or -1 on error
888  */
libfdatetime_systemtime_copy_to_utf8_string_with_index(libfdatetime_systemtime_t * systemtime,uint8_t * utf8_string,size_t utf8_string_size,size_t * utf8_string_index,uint32_t string_format_flags,libcerror_error_t ** error)889 int libfdatetime_systemtime_copy_to_utf8_string_with_index(
890      libfdatetime_systemtime_t *systemtime,
891      uint8_t *utf8_string,
892      size_t utf8_string_size,
893      size_t *utf8_string_index,
894      uint32_t string_format_flags,
895      libcerror_error_t **error )
896 {
897 	libfdatetime_date_time_values_t date_time_values;
898 
899 	libfdatetime_internal_systemtime_t *internal_systemtime = NULL;
900 	static char *function                                   = "libfdatetime_systemtime_copy_to_utf8_string_with_index";
901 	int result                                              = 0;
902 
903 	if( systemtime == NULL )
904 	{
905 		libcerror_error_set(
906 		 error,
907 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
908 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
909 		 "%s: invalid SYSTEMTIME.",
910 		 function );
911 
912 		return( -1 );
913 	}
914 	internal_systemtime = (libfdatetime_internal_systemtime_t *) systemtime;
915 
916 	result = libfdatetime_internal_systemtime_copy_to_date_time_values(
917 	          internal_systemtime,
918 	          &date_time_values,
919 	          error );
920 
921 	if( result != 1 )
922 	{
923 #if defined( HAVE_DEBUG_OUTPUT )
924 		libcerror_error_set(
925 		 error,
926 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
927 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
928 		 "%s: unable to set date time values.",
929 		 function );
930 
931 /* TODO debug print error */
932 
933 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
934 
935 		if( ( error != NULL )
936 		 && ( *error != NULL ) )
937 		{
938 			libcerror_error_free(
939 			 error );
940 		}
941 	}
942 	else
943 	{
944 		result = libfdatetime_date_time_values_copy_to_utf8_string_with_index(
945 		          &date_time_values,
946 		          utf8_string,
947 		          utf8_string_size,
948 		          utf8_string_index,
949 		          string_format_flags,
950 		          error );
951 
952 		if( result == -1 )
953 		{
954 			libcerror_error_set(
955 			 error,
956 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
957 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
958 			 "%s: unable to copy date time values to UTF-8 string.",
959 			 function );
960 
961 			return( -1 );
962 		}
963 	}
964 	if( result != 1 )
965 	{
966 		result = libfdatetime_internal_systemtime_copy_to_utf8_string_in_hexadecimal(
967 		          internal_systemtime,
968 		          utf8_string,
969 		          utf8_string_size,
970 		          utf8_string_index,
971 		          error );
972 
973 		if( result == -1 )
974 		{
975 			libcerror_error_set(
976 			 error,
977 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
978 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
979 			 "%s: unable to SYSTEMTIME to hexadecimal UTF-8 string.",
980 			 function );
981 
982 			return( -1 );
983 		}
984 	}
985 	return( 1 );
986 }
987 
988 /* Converts the SYSTEMTIME into an UTF-16 string in hexadecimal representation
989  * The string size should include the end of string character
990  * Returns 1 if successful or -1 on error
991  */
libfdatetime_internal_systemtime_copy_to_utf16_string_in_hexadecimal(libfdatetime_internal_systemtime_t * internal_systemtime,uint16_t * utf16_string,size_t utf16_string_size,size_t * utf16_string_index,libcerror_error_t ** error)992 int libfdatetime_internal_systemtime_copy_to_utf16_string_in_hexadecimal(
993      libfdatetime_internal_systemtime_t *internal_systemtime,
994      uint16_t *utf16_string,
995      size_t utf16_string_size,
996      size_t *utf16_string_index,
997      libcerror_error_t **error )
998 {
999 	static char *function = "libfdatetime_internal_systemtime_copy_to_utf16_string_in_hexadecimal";
1000 	size_t string_index   = 0;
1001 	uint8_t byte_value    = 0;
1002 	int8_t byte_shift     = 0;
1003 
1004 	if( internal_systemtime == NULL )
1005 	{
1006 		libcerror_error_set(
1007 		 error,
1008 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1009 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1010 		 "%s: invalid SYSTEMTIME.",
1011 		 function );
1012 
1013 		return( -1 );
1014 	}
1015 	if( utf16_string == NULL )
1016 	{
1017 		libcerror_error_set(
1018 		 error,
1019 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1020 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1021 		 "%s: invalid UTF-16 string.",
1022 		 function );
1023 
1024 		return( -1 );
1025 	}
1026 	if( utf16_string_size > (size_t) SSIZE_MAX )
1027 	{
1028 		libcerror_error_set(
1029 		 error,
1030 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1031 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1032 		 "%s: invalid UTF-16 string size value exceeds maximum.",
1033 		 function );
1034 
1035 		return( -1 );
1036 	}
1037 	if( utf16_string_index == NULL )
1038 	{
1039 		libcerror_error_set(
1040 		 error,
1041 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1042 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1043 		 "%s: invalid UTF-16 string index.",
1044 		 function );
1045 
1046 		return( -1 );
1047 	}
1048 	if( ( utf16_string_size < 58 )
1049 	 || ( *utf16_string_index > ( utf16_string_size - 58 ) ) )
1050 	{
1051 		libcerror_error_set(
1052 		 error,
1053 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1054 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1055 		 "%s: UTF-16 string is too small.",
1056 		 function );
1057 
1058 		return( -1 );
1059 	}
1060 	string_index = *utf16_string_index;
1061 
1062 	utf16_string[ string_index++ ] = (uint16_t) '(';
1063 	utf16_string[ string_index++ ] = (uint16_t) '0';
1064 	utf16_string[ string_index++ ] = (uint16_t) 'x';
1065 
1066 	byte_shift = 14;
1067 
1068 	do
1069 	{
1070 		byte_value = ( internal_systemtime->year >> byte_shift ) & 0x0f;
1071 
1072 		if( byte_value <= 9 )
1073 		{
1074 			utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
1075 		}
1076 		else
1077 		{
1078 			utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
1079 		}
1080 		byte_shift -= 4;
1081 	}
1082 	while( byte_shift >= 0 );
1083 
1084 	utf16_string[ string_index++ ] = (uint16_t) ' ';
1085 	utf16_string[ string_index++ ] = (uint16_t) '0';
1086 	utf16_string[ string_index++ ] = (uint16_t) 'x';
1087 
1088 	byte_shift = 14;
1089 
1090 	do
1091 	{
1092 		byte_value = ( internal_systemtime->month >> byte_shift ) & 0x0f;
1093 
1094 		if( byte_value <= 9 )
1095 		{
1096 			utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
1097 		}
1098 		else
1099 		{
1100 			utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
1101 		}
1102 		byte_shift -= 4;
1103 	}
1104 	while( byte_shift >= 0 );
1105 
1106 	utf16_string[ string_index++ ] = (uint16_t) ' ';
1107 	utf16_string[ string_index++ ] = (uint16_t) '0';
1108 	utf16_string[ string_index++ ] = (uint16_t) 'x';
1109 
1110 	byte_shift = 14;
1111 
1112 	do
1113 	{
1114 		byte_value = ( internal_systemtime->day_of_week >> byte_shift ) & 0x0f;
1115 
1116 		if( byte_value <= 9 )
1117 		{
1118 			utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
1119 		}
1120 		else
1121 		{
1122 			utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
1123 		}
1124 		byte_shift -= 4;
1125 	}
1126 	while( byte_shift >= 0 );
1127 
1128 	utf16_string[ string_index++ ] = (uint16_t) ' ';
1129 	utf16_string[ string_index++ ] = (uint16_t) '0';
1130 	utf16_string[ string_index++ ] = (uint16_t) 'x';
1131 
1132 	byte_shift = 14;
1133 
1134 	do
1135 	{
1136 		byte_value = ( internal_systemtime->day_of_month >> byte_shift ) & 0x0f;
1137 
1138 		if( byte_value <= 9 )
1139 		{
1140 			utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
1141 		}
1142 		else
1143 		{
1144 			utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
1145 		}
1146 		byte_shift -= 4;
1147 	}
1148 	while( byte_shift >= 0 );
1149 
1150 	utf16_string[ string_index++ ] = (uint16_t) ' ';
1151 	utf16_string[ string_index++ ] = (uint16_t) '0';
1152 	utf16_string[ string_index++ ] = (uint16_t) 'x';
1153 
1154 	byte_shift = 14;
1155 
1156 	do
1157 	{
1158 		byte_value = ( internal_systemtime->hours >> byte_shift ) & 0x0f;
1159 
1160 		if( byte_value <= 9 )
1161 		{
1162 			utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
1163 		}
1164 		else
1165 		{
1166 			utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
1167 		}
1168 		byte_shift -= 4;
1169 	}
1170 	while( byte_shift >= 0 );
1171 
1172 	utf16_string[ string_index++ ] = (uint16_t) ' ';
1173 	utf16_string[ string_index++ ] = (uint16_t) '0';
1174 	utf16_string[ string_index++ ] = (uint16_t) 'x';
1175 
1176 	byte_shift = 14;
1177 
1178 	do
1179 	{
1180 		byte_value = ( internal_systemtime->minutes >> byte_shift ) & 0x0f;
1181 
1182 		if( byte_value <= 9 )
1183 		{
1184 			utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
1185 		}
1186 		else
1187 		{
1188 			utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
1189 		}
1190 		byte_shift -= 4;
1191 	}
1192 	while( byte_shift >= 0 );
1193 
1194 	utf16_string[ string_index++ ] = (uint16_t) ' ';
1195 	utf16_string[ string_index++ ] = (uint16_t) '0';
1196 	utf16_string[ string_index++ ] = (uint16_t) 'x';
1197 
1198 	byte_shift = 14;
1199 
1200 	do
1201 	{
1202 		byte_value = ( internal_systemtime->seconds >> byte_shift ) & 0x0f;
1203 
1204 		if( byte_value <= 9 )
1205 		{
1206 			utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
1207 		}
1208 		else
1209 		{
1210 			utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
1211 		}
1212 		byte_shift -= 4;
1213 	}
1214 	while( byte_shift >= 0 );
1215 
1216 	utf16_string[ string_index++ ] = (uint16_t) ' ';
1217 	utf16_string[ string_index++ ] = (uint16_t) '0';
1218 	utf16_string[ string_index++ ] = (uint16_t) 'x';
1219 
1220 	byte_shift = 14;
1221 
1222 	do
1223 	{
1224 		byte_value = ( internal_systemtime->milli_seconds >> byte_shift ) & 0x0f;
1225 
1226 		if( byte_value <= 9 )
1227 		{
1228 			utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
1229 		}
1230 		else
1231 		{
1232 			utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
1233 		}
1234 		byte_shift -= 4;
1235 	}
1236 	while( byte_shift >= 0 );
1237 
1238 	utf16_string[ string_index++ ] = (uint16_t) ')';
1239 
1240 	utf16_string[ string_index++ ] = 0;
1241 
1242 	*utf16_string_index = string_index;
1243 
1244 	return( 1 );
1245 }
1246 
1247 /* Converts the SYSTEMTIME into an UTF-16 string
1248  * The string size should include the end of string character
1249  * Returns 1 if successful or -1 on error
1250  */
libfdatetime_systemtime_copy_to_utf16_string(libfdatetime_systemtime_t * systemtime,uint16_t * utf16_string,size_t utf16_string_size,uint32_t string_format_flags,libcerror_error_t ** error)1251 int libfdatetime_systemtime_copy_to_utf16_string(
1252      libfdatetime_systemtime_t *systemtime,
1253      uint16_t *utf16_string,
1254      size_t utf16_string_size,
1255      uint32_t string_format_flags,
1256      libcerror_error_t **error )
1257 {
1258 	static char *function     = "libfdatetime_systemtime_copy_to_utf16_string";
1259 	size_t utf16_string_index = 0;
1260 
1261 	if( libfdatetime_systemtime_copy_to_utf16_string_with_index(
1262 	     systemtime,
1263 	     utf16_string,
1264 	     utf16_string_size,
1265 	     &utf16_string_index,
1266 	     string_format_flags,
1267 	     error ) != 1 )
1268 	{
1269 		libcerror_error_set(
1270 		 error,
1271 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1272 		 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1273 		 "%s: unable to copy SYSTEMTIME to UTF-16 string.",
1274 		 function );
1275 
1276 		return( -1 );
1277 	}
1278 	return( 1 );
1279 }
1280 
1281 /* Converts the SYSTEMTIME into an UTF-16 string
1282  * The string size should include the end of string character
1283  * Returns 1 if successful or -1 on error
1284  */
libfdatetime_systemtime_copy_to_utf16_string_with_index(libfdatetime_systemtime_t * systemtime,uint16_t * utf16_string,size_t utf16_string_size,size_t * utf16_string_index,uint32_t string_format_flags,libcerror_error_t ** error)1285 int libfdatetime_systemtime_copy_to_utf16_string_with_index(
1286      libfdatetime_systemtime_t *systemtime,
1287      uint16_t *utf16_string,
1288      size_t utf16_string_size,
1289      size_t *utf16_string_index,
1290      uint32_t string_format_flags,
1291      libcerror_error_t **error )
1292 {
1293 	libfdatetime_date_time_values_t date_time_values;
1294 
1295 	libfdatetime_internal_systemtime_t *internal_systemtime = NULL;
1296 	static char *function                                   = "libfdatetime_systemtime_copy_to_utf16_string_with_index";
1297 	int result                                              = 0;
1298 
1299 	if( systemtime == NULL )
1300 	{
1301 		libcerror_error_set(
1302 		 error,
1303 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1304 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1305 		 "%s: invalid SYSTEMTIME.",
1306 		 function );
1307 
1308 		return( -1 );
1309 	}
1310 	internal_systemtime = (libfdatetime_internal_systemtime_t *) systemtime;
1311 
1312 	result = libfdatetime_internal_systemtime_copy_to_date_time_values(
1313 	          internal_systemtime,
1314 	          &date_time_values,
1315 	          error );
1316 
1317 	if( result != 1 )
1318 	{
1319 #if defined( HAVE_DEBUG_OUTPUT )
1320 		libcerror_error_set(
1321 		 error,
1322 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1323 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1324 		 "%s: unable to set date time values.",
1325 		 function );
1326 
1327 /* TODO debug print error */
1328 
1329 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
1330 
1331 		if( ( error != NULL )
1332 		 && ( *error != NULL ) )
1333 		{
1334 			libcerror_error_free(
1335 			 error );
1336 		}
1337 	}
1338 	else
1339 	{
1340 		result = libfdatetime_date_time_values_copy_to_utf16_string_with_index(
1341 		          &date_time_values,
1342 		          utf16_string,
1343 		          utf16_string_size,
1344 		          utf16_string_index,
1345 		          string_format_flags,
1346 		          error );
1347 
1348 		if( result == -1 )
1349 		{
1350 			libcerror_error_set(
1351 			 error,
1352 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1353 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1354 			 "%s: unable to copy date time values to UTF-16 string.",
1355 			 function );
1356 
1357 			return( -1 );
1358 		}
1359 	}
1360 	if( result != 1 )
1361 	{
1362 		result = libfdatetime_internal_systemtime_copy_to_utf16_string_in_hexadecimal(
1363 		          internal_systemtime,
1364 		          utf16_string,
1365 		          utf16_string_size,
1366 		          utf16_string_index,
1367 		          error );
1368 
1369 		if( result == -1 )
1370 		{
1371 			libcerror_error_set(
1372 			 error,
1373 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1374 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1375 			 "%s: unable to SYSTEMTIME to hexadecimal UTF-16 string.",
1376 			 function );
1377 
1378 			return( -1 );
1379 		}
1380 	}
1381 	return( 1 );
1382 }
1383 
1384 /* Converts the SYSTEMTIME into an UTF-32 string in hexadecimal representation
1385  * The string size should include the end of string character
1386  * Returns 1 if successful or -1 on error
1387  */
libfdatetime_internal_systemtime_copy_to_utf32_string_in_hexadecimal(libfdatetime_internal_systemtime_t * internal_systemtime,uint32_t * utf32_string,size_t utf32_string_size,size_t * utf32_string_index,libcerror_error_t ** error)1388 int libfdatetime_internal_systemtime_copy_to_utf32_string_in_hexadecimal(
1389      libfdatetime_internal_systemtime_t *internal_systemtime,
1390      uint32_t *utf32_string,
1391      size_t utf32_string_size,
1392      size_t *utf32_string_index,
1393      libcerror_error_t **error )
1394 {
1395 	static char *function = "libfdatetime_internal_systemtime_copy_to_utf32_string_in_hexadecimal";
1396 	size_t string_index   = 0;
1397 	uint8_t byte_value    = 0;
1398 	int8_t byte_shift     = 0;
1399 
1400 	if( internal_systemtime == NULL )
1401 	{
1402 		libcerror_error_set(
1403 		 error,
1404 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1405 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1406 		 "%s: invalid SYSTEMTIME.",
1407 		 function );
1408 
1409 		return( -1 );
1410 	}
1411 	if( utf32_string == NULL )
1412 	{
1413 		libcerror_error_set(
1414 		 error,
1415 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1416 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1417 		 "%s: invalid UTF-32 string.",
1418 		 function );
1419 
1420 		return( -1 );
1421 	}
1422 	if( utf32_string_size > (size_t) SSIZE_MAX )
1423 	{
1424 		libcerror_error_set(
1425 		 error,
1426 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1427 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1428 		 "%s: invalid UTF-32 string size value exceeds maximum.",
1429 		 function );
1430 
1431 		return( -1 );
1432 	}
1433 	if( utf32_string_index == NULL )
1434 	{
1435 		libcerror_error_set(
1436 		 error,
1437 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1438 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1439 		 "%s: invalid UTF-32 string index.",
1440 		 function );
1441 
1442 		return( -1 );
1443 	}
1444 	if( ( utf32_string_size < 58 )
1445 	 || ( *utf32_string_index > ( utf32_string_size - 58 ) ) )
1446 	{
1447 		libcerror_error_set(
1448 		 error,
1449 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1450 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1451 		 "%s: UTF-32 string is too small.",
1452 		 function );
1453 
1454 		return( -1 );
1455 	}
1456 	string_index = *utf32_string_index;
1457 
1458 	utf32_string[ string_index++ ] = (uint32_t) '(';
1459 	utf32_string[ string_index++ ] = (uint32_t) '0';
1460 	utf32_string[ string_index++ ] = (uint32_t) 'x';
1461 
1462 	byte_shift = 14;
1463 
1464 	do
1465 	{
1466 		byte_value = ( internal_systemtime->year >> byte_shift ) & 0x0f;
1467 
1468 		if( byte_value <= 9 )
1469 		{
1470 			utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
1471 		}
1472 		else
1473 		{
1474 			utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
1475 		}
1476 		byte_shift -= 4;
1477 	}
1478 	while( byte_shift >= 0 );
1479 
1480 	utf32_string[ string_index++ ] = (uint32_t) ' ';
1481 	utf32_string[ string_index++ ] = (uint32_t) '0';
1482 	utf32_string[ string_index++ ] = (uint32_t) 'x';
1483 
1484 	byte_shift = 14;
1485 
1486 	do
1487 	{
1488 		byte_value = ( internal_systemtime->month >> byte_shift ) & 0x0f;
1489 
1490 		if( byte_value <= 9 )
1491 		{
1492 			utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
1493 		}
1494 		else
1495 		{
1496 			utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
1497 		}
1498 		byte_shift -= 4;
1499 	}
1500 	while( byte_shift >= 0 );
1501 
1502 	utf32_string[ string_index++ ] = (uint32_t) ' ';
1503 	utf32_string[ string_index++ ] = (uint32_t) '0';
1504 	utf32_string[ string_index++ ] = (uint32_t) 'x';
1505 
1506 	byte_shift = 14;
1507 
1508 	do
1509 	{
1510 		byte_value = ( internal_systemtime->day_of_week >> byte_shift ) & 0x0f;
1511 
1512 		if( byte_value <= 9 )
1513 		{
1514 			utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
1515 		}
1516 		else
1517 		{
1518 			utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
1519 		}
1520 		byte_shift -= 4;
1521 	}
1522 	while( byte_shift >= 0 );
1523 
1524 	utf32_string[ string_index++ ] = (uint32_t) ' ';
1525 	utf32_string[ string_index++ ] = (uint32_t) '0';
1526 	utf32_string[ string_index++ ] = (uint32_t) 'x';
1527 
1528 	byte_shift = 14;
1529 
1530 	do
1531 	{
1532 		byte_value = ( internal_systemtime->day_of_month >> byte_shift ) & 0x0f;
1533 
1534 		if( byte_value <= 9 )
1535 		{
1536 			utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
1537 		}
1538 		else
1539 		{
1540 			utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
1541 		}
1542 		byte_shift -= 4;
1543 	}
1544 	while( byte_shift >= 0 );
1545 
1546 	utf32_string[ string_index++ ] = (uint32_t) ' ';
1547 	utf32_string[ string_index++ ] = (uint32_t) '0';
1548 	utf32_string[ string_index++ ] = (uint32_t) 'x';
1549 
1550 	byte_shift = 14;
1551 
1552 	do
1553 	{
1554 		byte_value = ( internal_systemtime->hours >> byte_shift ) & 0x0f;
1555 
1556 		if( byte_value <= 9 )
1557 		{
1558 			utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
1559 		}
1560 		else
1561 		{
1562 			utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
1563 		}
1564 		byte_shift -= 4;
1565 	}
1566 	while( byte_shift >= 0 );
1567 
1568 	utf32_string[ string_index++ ] = (uint32_t) ' ';
1569 	utf32_string[ string_index++ ] = (uint32_t) '0';
1570 	utf32_string[ string_index++ ] = (uint32_t) 'x';
1571 
1572 	byte_shift = 14;
1573 
1574 	do
1575 	{
1576 		byte_value = ( internal_systemtime->minutes >> byte_shift ) & 0x0f;
1577 
1578 		if( byte_value <= 9 )
1579 		{
1580 			utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
1581 		}
1582 		else
1583 		{
1584 			utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
1585 		}
1586 		byte_shift -= 4;
1587 	}
1588 	while( byte_shift >= 0 );
1589 
1590 	utf32_string[ string_index++ ] = (uint32_t) ' ';
1591 	utf32_string[ string_index++ ] = (uint32_t) '0';
1592 	utf32_string[ string_index++ ] = (uint32_t) 'x';
1593 
1594 	byte_shift = 14;
1595 
1596 	do
1597 	{
1598 		byte_value = ( internal_systemtime->seconds >> byte_shift ) & 0x0f;
1599 
1600 		if( byte_value <= 9 )
1601 		{
1602 			utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
1603 		}
1604 		else
1605 		{
1606 			utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
1607 		}
1608 		byte_shift -= 4;
1609 	}
1610 	while( byte_shift >= 0 );
1611 
1612 	utf32_string[ string_index++ ] = (uint32_t) ' ';
1613 	utf32_string[ string_index++ ] = (uint32_t) '0';
1614 	utf32_string[ string_index++ ] = (uint32_t) 'x';
1615 
1616 	byte_shift = 14;
1617 
1618 	do
1619 	{
1620 		byte_value = ( internal_systemtime->milli_seconds >> byte_shift ) & 0x0f;
1621 
1622 		if( byte_value <= 9 )
1623 		{
1624 			utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
1625 		}
1626 		else
1627 		{
1628 			utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
1629 		}
1630 		byte_shift -= 4;
1631 	}
1632 	while( byte_shift >= 0 );
1633 
1634 	utf32_string[ string_index++ ] = (uint32_t) ')';
1635 
1636 	utf32_string[ string_index++ ] = 0;
1637 
1638 	*utf32_string_index = string_index;
1639 
1640 	return( 1 );
1641 }
1642 
1643 /* Converts the SYSTEMTIME into an UTF-32 string
1644  * The string size should include the end of string character
1645  * Returns 1 if successful or -1 on error
1646  */
libfdatetime_systemtime_copy_to_utf32_string(libfdatetime_systemtime_t * systemtime,uint32_t * utf32_string,size_t utf32_string_size,uint32_t string_format_flags,libcerror_error_t ** error)1647 int libfdatetime_systemtime_copy_to_utf32_string(
1648      libfdatetime_systemtime_t *systemtime,
1649      uint32_t *utf32_string,
1650      size_t utf32_string_size,
1651      uint32_t string_format_flags,
1652      libcerror_error_t **error )
1653 {
1654 	static char *function     = "libfdatetime_systemtime_copy_to_utf32_string";
1655 	size_t utf32_string_index = 0;
1656 
1657 	if( libfdatetime_systemtime_copy_to_utf32_string_with_index(
1658 	     systemtime,
1659 	     utf32_string,
1660 	     utf32_string_size,
1661 	     &utf32_string_index,
1662 	     string_format_flags,
1663 	     error ) != 1 )
1664 	{
1665 		libcerror_error_set(
1666 		 error,
1667 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1668 		 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1669 		 "%s: unable to copy SYSTEMTIME to UTF-32 string.",
1670 		 function );
1671 
1672 		return( -1 );
1673 	}
1674 	return( 1 );
1675 }
1676 
1677 /* Converts the SYSTEMTIME into an UTF-32 string
1678  * The string size should include the end of string character
1679  * Returns 1 if successful or -1 on error
1680  */
libfdatetime_systemtime_copy_to_utf32_string_with_index(libfdatetime_systemtime_t * systemtime,uint32_t * utf32_string,size_t utf32_string_size,size_t * utf32_string_index,uint32_t string_format_flags,libcerror_error_t ** error)1681 int libfdatetime_systemtime_copy_to_utf32_string_with_index(
1682      libfdatetime_systemtime_t *systemtime,
1683      uint32_t *utf32_string,
1684      size_t utf32_string_size,
1685      size_t *utf32_string_index,
1686      uint32_t string_format_flags,
1687      libcerror_error_t **error )
1688 {
1689 	libfdatetime_date_time_values_t date_time_values;
1690 
1691 	libfdatetime_internal_systemtime_t *internal_systemtime = NULL;
1692 	static char *function                                   = "libfdatetime_systemtime_copy_to_utf32_string_with_index";
1693 	int result                                              = 0;
1694 
1695 	if( systemtime == NULL )
1696 	{
1697 		libcerror_error_set(
1698 		 error,
1699 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1700 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1701 		 "%s: invalid SYSTEMTIME.",
1702 		 function );
1703 
1704 		return( -1 );
1705 	}
1706 	internal_systemtime = (libfdatetime_internal_systemtime_t *) systemtime;
1707 
1708 	result = libfdatetime_internal_systemtime_copy_to_date_time_values(
1709 	          internal_systemtime,
1710 	          &date_time_values,
1711 	          error );
1712 
1713 	if( result != 1 )
1714 	{
1715 #if defined( HAVE_DEBUG_OUTPUT )
1716 		libcerror_error_set(
1717 		 error,
1718 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1719 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1720 		 "%s: unable to set date time values.",
1721 		 function );
1722 
1723 /* TODO debug print error */
1724 
1725 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
1726 
1727 		if( ( error != NULL )
1728 		 && ( *error != NULL ) )
1729 		{
1730 			libcerror_error_free(
1731 			 error );
1732 		}
1733 	}
1734 	else
1735 	{
1736 		result = libfdatetime_date_time_values_copy_to_utf32_string_with_index(
1737 		          &date_time_values,
1738 		          utf32_string,
1739 		          utf32_string_size,
1740 		          utf32_string_index,
1741 		          string_format_flags,
1742 		          error );
1743 
1744 		if( result == -1 )
1745 		{
1746 			libcerror_error_set(
1747 			 error,
1748 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1749 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1750 			 "%s: unable to copy date time values to UTF-32 string.",
1751 			 function );
1752 
1753 			return( -1 );
1754 		}
1755 	}
1756 	if( result != 1 )
1757 	{
1758 		result = libfdatetime_internal_systemtime_copy_to_utf32_string_in_hexadecimal(
1759 		          internal_systemtime,
1760 		          utf32_string,
1761 		          utf32_string_size,
1762 		          utf32_string_index,
1763 		          error );
1764 
1765 		if( result == -1 )
1766 		{
1767 			libcerror_error_set(
1768 			 error,
1769 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1770 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1771 			 "%s: unable to SYSTEMTIME to hexadecimal UTF-32 string.",
1772 			 function );
1773 
1774 			return( -1 );
1775 		}
1776 	}
1777 	return( 1 );
1778 }
1779 
1780