1 /*
2 * FAT date and time 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_fat_date_time.h"
30 #include "libfdatetime_libcerror.h"
31 #include "libfdatetime_types.h"
32
33 /* Creates a FAT date and time
34 * Make sure the value fat_date_time is referencing, is set to NULL
35 * Returns 1 if successful or -1 on error
36 */
libfdatetime_fat_date_time_initialize(libfdatetime_fat_date_time_t ** fat_date_time,libcerror_error_t ** error)37 int libfdatetime_fat_date_time_initialize(
38 libfdatetime_fat_date_time_t **fat_date_time,
39 libcerror_error_t **error )
40 {
41 libfdatetime_internal_fat_date_time_t *internal_fat_date_time = NULL;
42 static char *function = "libfdatetime_fat_date_time_initialize";
43
44 if( fat_date_time == NULL )
45 {
46 libcerror_error_set(
47 error,
48 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
49 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
50 "%s: invalid FAT date time.",
51 function );
52
53 return( -1 );
54 }
55 if( *fat_date_time != NULL )
56 {
57 libcerror_error_set(
58 error,
59 LIBCERROR_ERROR_DOMAIN_RUNTIME,
60 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
61 "%s: invalid FAT date time value already set.",
62 function );
63
64 return( -1 );
65 }
66 internal_fat_date_time = memory_allocate_structure(
67 libfdatetime_internal_fat_date_time_t );
68
69 if( internal_fat_date_time == NULL )
70 {
71 libcerror_error_set(
72 error,
73 LIBCERROR_ERROR_DOMAIN_MEMORY,
74 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
75 "%s: unable to create FAT date time.",
76 function );
77
78 goto on_error;
79 }
80 if( memory_set(
81 internal_fat_date_time,
82 0,
83 sizeof( libfdatetime_internal_fat_date_time_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 FAT date time.",
90 function );
91
92 goto on_error;
93 }
94 *fat_date_time = (libfdatetime_fat_date_time_t *) internal_fat_date_time;
95
96 return( 1 );
97
98 on_error:
99 if( internal_fat_date_time != NULL )
100 {
101 memory_free(
102 internal_fat_date_time );
103 }
104 return( -1 );
105 }
106
107 /* Frees a FAT date and time
108 * Returns 1 if successful or -1 on error
109 */
libfdatetime_fat_date_time_free(libfdatetime_fat_date_time_t ** fat_date_time,libcerror_error_t ** error)110 int libfdatetime_fat_date_time_free(
111 libfdatetime_fat_date_time_t **fat_date_time,
112 libcerror_error_t **error )
113 {
114 libfdatetime_internal_fat_date_time_t *internal_fat_date_time = NULL;
115 static char *function = "libfdatetime_fat_date_time_free";
116
117 if( fat_date_time == NULL )
118 {
119 libcerror_error_set(
120 error,
121 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
122 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
123 "%s: invalid FAT date time.",
124 function );
125
126 return( -1 );
127 }
128 if( *fat_date_time != NULL )
129 {
130 internal_fat_date_time = (libfdatetime_internal_fat_date_time_t *) *fat_date_time;
131 *fat_date_time = NULL;
132
133 memory_free(
134 internal_fat_date_time );
135 }
136 return( 1 );
137 }
138
139 /* Converts a byte stream into a FAT date and time
140 * Returns 1 if successful or -1 on error
141 */
libfdatetime_fat_date_time_copy_from_byte_stream(libfdatetime_fat_date_time_t * fat_date_time,const uint8_t * byte_stream,size_t byte_stream_size,int byte_order,libcerror_error_t ** error)142 int libfdatetime_fat_date_time_copy_from_byte_stream(
143 libfdatetime_fat_date_time_t *fat_date_time,
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_fat_date_time_t *internal_fat_date_time = NULL;
150 static char *function = "libfdatetime_fat_date_time_copy_from_byte_stream";
151
152 if( fat_date_time == NULL )
153 {
154 libcerror_error_set(
155 error,
156 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
157 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
158 "%s: invalid FAT date time.",
159 function );
160
161 return( -1 );
162 }
163 internal_fat_date_time = (libfdatetime_internal_fat_date_time_t *) fat_date_time;
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 < 4 )
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_fat_date_time->date );
215
216 byte_stream += 2;
217
218 byte_stream_copy_to_uint16_little_endian(
219 byte_stream,
220 internal_fat_date_time->time );
221 }
222 else if( byte_order == LIBFDATETIME_ENDIAN_BIG )
223 {
224 byte_stream_copy_to_uint16_big_endian(
225 byte_stream,
226 internal_fat_date_time->date );
227
228 byte_stream += 2;
229
230 byte_stream_copy_to_uint16_big_endian(
231 byte_stream,
232 internal_fat_date_time->time );
233 }
234 return( 1 );
235 }
236
237 /* Converts a 32-bit value into a FAT date and time
238 * Returns 1 if successful or -1 on error
239 */
libfdatetime_fat_date_time_copy_from_32bit(libfdatetime_fat_date_time_t * fat_date_time,uint32_t value_32bit,libcerror_error_t ** error)240 int libfdatetime_fat_date_time_copy_from_32bit(
241 libfdatetime_fat_date_time_t *fat_date_time,
242 uint32_t value_32bit,
243 libcerror_error_t **error )
244 {
245 libfdatetime_internal_fat_date_time_t *internal_fat_date_time = NULL;
246 static char *function = "libfdatetime_fat_date_time_copy_from_32bit";
247
248 if( fat_date_time == NULL )
249 {
250 libcerror_error_set(
251 error,
252 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
253 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
254 "%s: invalid FAT date time.",
255 function );
256
257 return( -1 );
258 }
259 internal_fat_date_time = (libfdatetime_internal_fat_date_time_t *) fat_date_time;
260
261 internal_fat_date_time->date = (uint16_t) ( value_32bit & 0x0ffffL );
262 internal_fat_date_time->time = (uint16_t) ( value_32bit >> 16 );
263
264 return( 1 );
265 }
266
267 /* Converts a FAT date and time into a 32-bit value
268 * Returns 1 if successful or -1 on error
269 */
libfdatetime_fat_date_time_copy_to_32bit(libfdatetime_fat_date_time_t * fat_date_time,uint32_t * value_32bit,libcerror_error_t ** error)270 int libfdatetime_fat_date_time_copy_to_32bit(
271 libfdatetime_fat_date_time_t *fat_date_time,
272 uint32_t *value_32bit,
273 libcerror_error_t **error )
274 {
275 libfdatetime_internal_fat_date_time_t *internal_fat_date_time = NULL;
276 static char *function = "libfdatetime_fat_date_time_copy_to_32bit";
277
278 if( fat_date_time == NULL )
279 {
280 libcerror_error_set(
281 error,
282 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
283 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
284 "%s: invalid FAT date time.",
285 function );
286
287 return( -1 );
288 }
289 internal_fat_date_time = (libfdatetime_internal_fat_date_time_t *) fat_date_time;
290
291 if( value_32bit == NULL )
292 {
293 libcerror_error_set(
294 error,
295 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
296 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
297 "%s: invalid 32-bit value.",
298 function );
299
300 return( -1 );
301 }
302 *value_32bit = internal_fat_date_time->time;
303 *value_32bit <<= 16;
304 *value_32bit |= internal_fat_date_time->date;
305
306 return( 1 );
307 }
308
309 /* Converts a FAT date and time into date time values
310 * Returns 1 if successful or -1 on error
311 */
libfdatetime_internal_fat_date_time_copy_to_date_time_values(libfdatetime_internal_fat_date_time_t * internal_fat_date_time,libfdatetime_date_time_values_t * date_time_values,libcerror_error_t ** error)312 int libfdatetime_internal_fat_date_time_copy_to_date_time_values(
313 libfdatetime_internal_fat_date_time_t *internal_fat_date_time,
314 libfdatetime_date_time_values_t *date_time_values,
315 libcerror_error_t **error )
316 {
317 static char *function = "libfdatetime_internal_fat_date_time_copy_to_date_time_values";
318
319 if( internal_fat_date_time == NULL )
320 {
321 libcerror_error_set(
322 error,
323 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
324 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
325 "%s: invalid FAT date time.",
326 function );
327
328 return( -1 );
329 }
330 if( date_time_values == NULL )
331 {
332 libcerror_error_set(
333 error,
334 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
335 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
336 "%s: invalid date time values.",
337 function );
338
339 return( -1 );
340 }
341 /* The year value is stored in bits 9 - 15 of the date (7 bits)
342 * A year value of 0 represents 1980
343 */
344 date_time_values->year = (uint16_t) ( 1980 + ( ( internal_fat_date_time->date >> 9 ) & 0x7f ) );
345
346 /* The month value is stored in bits 5 - 8 of the date (4 bits)
347 * A month value of 1 represents January
348 */
349 date_time_values->month = (uint8_t) ( ( internal_fat_date_time->date >> 5 ) & 0x0f );
350
351 /* The day value is stored in bits 0 - 4 of the date (5 bits)
352 */
353 date_time_values->day = (uint8_t) ( internal_fat_date_time->date & 0x1f );
354
355 /* The hours value is stored in bits 11 - 15 of the time (5 bits)
356 */
357 date_time_values->hours = (uint8_t) ( ( internal_fat_date_time->time >> 11 ) & 0x1f );
358
359 /* The minutes value is stored in bits 5 - 10 of the time (6 bits)
360 */
361 date_time_values->minutes = (uint8_t) ( ( internal_fat_date_time->time >> 5 ) & 0x3f );
362
363 /* The seconds value is stored in bits 0 - 4 of the time (5 bits)
364 * The seconds are stored as 2 second intervals
365 */
366 date_time_values->seconds = (uint8_t) ( internal_fat_date_time->time & 0x1f ) * 2;
367
368 date_time_values->milli_seconds = 0;
369 date_time_values->micro_seconds = 0;
370 date_time_values->nano_seconds = 0;
371
372 return( 1 );
373 }
374
375 /* Deterimes the size of the string for the FAT date time
376 * The string size includes the end of string character
377 * Returns 1 if successful or -1 on error
378 */
libfdatetime_fat_date_time_get_string_size(libfdatetime_fat_date_time_t * fat_date_time,size_t * string_size,uint32_t string_format_flags,libcerror_error_t ** error)379 int libfdatetime_fat_date_time_get_string_size(
380 libfdatetime_fat_date_time_t *fat_date_time,
381 size_t *string_size,
382 uint32_t string_format_flags,
383 libcerror_error_t **error )
384 {
385 libfdatetime_date_time_values_t date_time_values;
386
387 static char *function = "libfdatetime_fat_date_time_get_string_size";
388 int result = 0;
389
390 if( fat_date_time == NULL )
391 {
392 libcerror_error_set(
393 error,
394 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
395 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
396 "%s: invalid FAT date time.",
397 function );
398
399 return( -1 );
400 }
401 if( string_size == NULL )
402 {
403 libcerror_error_set(
404 error,
405 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
406 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
407 "%s: invalid string size.",
408 function );
409
410 return( -1 );
411 }
412 result = libfdatetime_internal_fat_date_time_copy_to_date_time_values(
413 (libfdatetime_internal_fat_date_time_t *) fat_date_time,
414 &date_time_values,
415 error );
416
417 if( result != 1 )
418 {
419 #if defined( HAVE_DEBUG_OUTPUT )
420 libcerror_error_set(
421 error,
422 LIBCERROR_ERROR_DOMAIN_RUNTIME,
423 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
424 "%s: unable to set date time values.",
425 function );
426
427 /* TODO debug print error */
428
429 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
430
431 if( ( error != NULL )
432 && ( *error != NULL ) )
433 {
434 libcerror_error_free(
435 error );
436 }
437 }
438 else
439 {
440 result = libfdatetime_date_time_values_get_string_size(
441 &date_time_values,
442 string_size,
443 string_format_flags,
444 error );
445
446 if( result == -1 )
447 {
448 libcerror_error_set(
449 error,
450 LIBCERROR_ERROR_DOMAIN_RUNTIME,
451 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
452 "%s: unable to get string size.",
453 function );
454
455 return( -1 );
456 }
457 }
458 if( result != 1 )
459 {
460 /* Make sure the string can hold the hexadecimal representation of the FAT date time
461 */
462 *string_size = 16;
463 }
464 return( 1 );
465 }
466
467 /* Converts the FAT date and time into an UTF-8 string in hexadecimal representation
468 * The string size should include the end of string character
469 * Returns 1 if successful or -1 on error
470 */
libfdatetime_internal_fat_date_time_copy_to_utf8_string_in_hexadecimal(libfdatetime_internal_fat_date_time_t * internal_fat_date_time,uint8_t * utf8_string,size_t utf8_string_size,size_t * utf8_string_index,libcerror_error_t ** error)471 int libfdatetime_internal_fat_date_time_copy_to_utf8_string_in_hexadecimal(
472 libfdatetime_internal_fat_date_time_t *internal_fat_date_time,
473 uint8_t *utf8_string,
474 size_t utf8_string_size,
475 size_t *utf8_string_index,
476 libcerror_error_t **error )
477 {
478 static char *function = "libfdatetime_internal_fat_date_time_copy_to_utf8_string_in_hexadecimal";
479 size_t string_index = 0;
480 uint8_t byte_value = 0;
481 int8_t byte_shift = 0;
482
483 if( internal_fat_date_time == NULL )
484 {
485 libcerror_error_set(
486 error,
487 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
488 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
489 "%s: invalid FAT date time.",
490 function );
491
492 return( -1 );
493 }
494 if( utf8_string == NULL )
495 {
496 libcerror_error_set(
497 error,
498 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
499 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
500 "%s: invalid UTF-8 string.",
501 function );
502
503 return( -1 );
504 }
505 if( utf8_string_size > (size_t) SSIZE_MAX )
506 {
507 libcerror_error_set(
508 error,
509 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
510 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
511 "%s: invalid UTF-8 string size value exceeds maximum.",
512 function );
513
514 return( -1 );
515 }
516 if( utf8_string_index == NULL )
517 {
518 libcerror_error_set(
519 error,
520 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
521 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
522 "%s: invalid UTF-8 string index.",
523 function );
524
525 return( -1 );
526 }
527 if( ( utf8_string_size < 16 )
528 || ( *utf8_string_index > ( utf8_string_size - 16 ) ) )
529 {
530 libcerror_error_set(
531 error,
532 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
533 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
534 "%s: UTF-8 string is too small.",
535 function );
536
537 return( -1 );
538 }
539 string_index = *utf8_string_index;
540
541 utf8_string[ string_index++ ] = (uint8_t) '(';
542 utf8_string[ string_index++ ] = (uint8_t) '0';
543 utf8_string[ string_index++ ] = (uint8_t) 'x';
544
545 byte_shift = 12;
546
547 do
548 {
549 byte_value = ( internal_fat_date_time->date >> byte_shift ) & 0x0f;
550
551 if( byte_value <= 9 )
552 {
553 utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
554 }
555 else
556 {
557 utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
558 }
559 byte_shift -= 4;
560 }
561 while( byte_shift >= 0 );
562
563 utf8_string[ string_index++ ] = (uint8_t) ' ';
564 utf8_string[ string_index++ ] = (uint8_t) '0';
565 utf8_string[ string_index++ ] = (uint8_t) 'x';
566
567 byte_shift = 12;
568
569 do
570 {
571 byte_value = ( internal_fat_date_time->time >> byte_shift ) & 0x0f;
572
573 if( byte_value <= 9 )
574 {
575 utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
576 }
577 else
578 {
579 utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
580 }
581 byte_shift -= 4;
582 }
583 while( byte_shift >= 0 );
584
585 utf8_string[ string_index++ ] = (uint8_t) ')';
586
587 utf8_string[ string_index++ ] = 0;
588
589 *utf8_string_index = string_index;
590
591 return( 1 );
592 }
593
594 /* Converts the FAT date and time into an UTF-8 string
595 * The string size should include the end of string character
596 * Returns 1 if successful or -1 on error
597 */
libfdatetime_fat_date_time_copy_to_utf8_string(libfdatetime_fat_date_time_t * fat_date_time,uint8_t * utf8_string,size_t utf8_string_size,uint32_t string_format_flags,libcerror_error_t ** error)598 int libfdatetime_fat_date_time_copy_to_utf8_string(
599 libfdatetime_fat_date_time_t *fat_date_time,
600 uint8_t *utf8_string,
601 size_t utf8_string_size,
602 uint32_t string_format_flags,
603 libcerror_error_t **error )
604 {
605 static char *function = "libfdatetime_fat_date_time_copy_to_utf8_string";
606 size_t utf8_string_index = 0;
607
608 if( libfdatetime_fat_date_time_copy_to_utf8_string_with_index(
609 fat_date_time,
610 utf8_string,
611 utf8_string_size,
612 &utf8_string_index,
613 string_format_flags,
614 error ) != 1 )
615 {
616 libcerror_error_set(
617 error,
618 LIBCERROR_ERROR_DOMAIN_RUNTIME,
619 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
620 "%s: unable to copy FAT date time to UTF-8 string.",
621 function );
622
623 return( -1 );
624 }
625 return( 1 );
626 }
627
628 /* Converts the FAT date and time into an UTF-8 string
629 * The string size should include the end of string character
630 * Returns 1 if successful or -1 on error
631 */
libfdatetime_fat_date_time_copy_to_utf8_string_with_index(libfdatetime_fat_date_time_t * fat_date_time,uint8_t * utf8_string,size_t utf8_string_size,size_t * utf8_string_index,uint32_t string_format_flags,libcerror_error_t ** error)632 int libfdatetime_fat_date_time_copy_to_utf8_string_with_index(
633 libfdatetime_fat_date_time_t *fat_date_time,
634 uint8_t *utf8_string,
635 size_t utf8_string_size,
636 size_t *utf8_string_index,
637 uint32_t string_format_flags,
638 libcerror_error_t **error )
639 {
640 libfdatetime_date_time_values_t date_time_values;
641
642 libfdatetime_internal_fat_date_time_t *internal_fat_date_time = NULL;
643 static char *function = "libfdatetime_fat_date_time_copy_to_utf8_string_with_index";
644 int result = 0;
645
646 if( fat_date_time == NULL )
647 {
648 libcerror_error_set(
649 error,
650 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
651 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
652 "%s: invalid FAT date time.",
653 function );
654
655 return( -1 );
656 }
657 internal_fat_date_time = (libfdatetime_internal_fat_date_time_t *) fat_date_time;
658
659 result = libfdatetime_internal_fat_date_time_copy_to_date_time_values(
660 internal_fat_date_time,
661 &date_time_values,
662 error );
663
664 if( result != 1 )
665 {
666 #if defined( HAVE_DEBUG_OUTPUT )
667 libcerror_error_set(
668 error,
669 LIBCERROR_ERROR_DOMAIN_RUNTIME,
670 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
671 "%s: unable to set date time values.",
672 function );
673
674 /* TODO debug print error */
675
676 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
677
678 if( ( error != NULL )
679 && ( *error != NULL ) )
680 {
681 libcerror_error_free(
682 error );
683 }
684 }
685 else
686 {
687 result = libfdatetime_date_time_values_copy_to_utf8_string_with_index(
688 &date_time_values,
689 utf8_string,
690 utf8_string_size,
691 utf8_string_index,
692 string_format_flags,
693 error );
694
695 if( result == -1 )
696 {
697 libcerror_error_set(
698 error,
699 LIBCERROR_ERROR_DOMAIN_RUNTIME,
700 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
701 "%s: unable to copy date time values to UTF-8 string.",
702 function );
703
704 return( -1 );
705 }
706 }
707 if( result != 1 )
708 {
709 result = libfdatetime_internal_fat_date_time_copy_to_utf8_string_in_hexadecimal(
710 internal_fat_date_time,
711 utf8_string,
712 utf8_string_size,
713 utf8_string_index,
714 error );
715
716 if( result == -1 )
717 {
718 libcerror_error_set(
719 error,
720 LIBCERROR_ERROR_DOMAIN_RUNTIME,
721 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
722 "%s: unable to FAT date time values to hexadecimal UTF-8 string.",
723 function );
724
725 return( -1 );
726 }
727 }
728 return( 1 );
729 }
730
731 /* Converts the FAT date and time into an UTF-16 string in hexadecimal representation
732 * The string size should include the end of string character
733 * Returns 1 if successful or -1 on error
734 */
libfdatetime_internal_fat_date_time_copy_to_utf16_string_in_hexadecimal(libfdatetime_internal_fat_date_time_t * internal_fat_date_time,uint16_t * utf16_string,size_t utf16_string_size,size_t * utf16_string_index,libcerror_error_t ** error)735 int libfdatetime_internal_fat_date_time_copy_to_utf16_string_in_hexadecimal(
736 libfdatetime_internal_fat_date_time_t *internal_fat_date_time,
737 uint16_t *utf16_string,
738 size_t utf16_string_size,
739 size_t *utf16_string_index,
740 libcerror_error_t **error )
741 {
742 static char *function = "libfdatetime_internal_fat_date_time_copy_to_utf16_string_in_hexadecimal";
743 size_t string_index = 0;
744 uint8_t byte_value = 0;
745 int8_t byte_shift = 0;
746
747 if( internal_fat_date_time == NULL )
748 {
749 libcerror_error_set(
750 error,
751 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
752 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
753 "%s: invalid FAT date time.",
754 function );
755
756 return( -1 );
757 }
758 if( utf16_string == NULL )
759 {
760 libcerror_error_set(
761 error,
762 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
763 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
764 "%s: invalid UTF-16 string.",
765 function );
766
767 return( -1 );
768 }
769 if( utf16_string_size > (size_t) SSIZE_MAX )
770 {
771 libcerror_error_set(
772 error,
773 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
774 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
775 "%s: invalid UTF-16 string size value exceeds maximum.",
776 function );
777
778 return( -1 );
779 }
780 if( utf16_string_index == NULL )
781 {
782 libcerror_error_set(
783 error,
784 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
785 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
786 "%s: invalid UTF-16 string index.",
787 function );
788
789 return( -1 );
790 }
791 if( ( utf16_string_size < 16 )
792 || ( *utf16_string_index > ( utf16_string_size - 16 ) ) )
793 {
794 libcerror_error_set(
795 error,
796 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
797 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
798 "%s: UTF-16 string is too small.",
799 function );
800
801 return( -1 );
802 }
803 string_index = *utf16_string_index;
804
805 utf16_string[ string_index++ ] = (uint16_t) '(';
806 utf16_string[ string_index++ ] = (uint16_t) '0';
807 utf16_string[ string_index++ ] = (uint16_t) 'x';
808
809 byte_shift = 12;
810
811 do
812 {
813 byte_value = ( internal_fat_date_time->date >> byte_shift ) & 0x0f;
814
815 if( byte_value <= 9 )
816 {
817 utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
818 }
819 else
820 {
821 utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
822 }
823 byte_shift -= 4;
824 }
825 while( byte_shift >= 0 );
826
827 utf16_string[ string_index++ ] = (uint16_t) ' ';
828 utf16_string[ string_index++ ] = (uint16_t) '0';
829 utf16_string[ string_index++ ] = (uint16_t) 'x';
830
831 byte_shift = 12;
832
833 do
834 {
835 byte_value = ( internal_fat_date_time->time >> byte_shift ) & 0x0f;
836
837 if( byte_value <= 9 )
838 {
839 utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
840 }
841 else
842 {
843 utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
844 }
845 byte_shift -= 4;
846 }
847 while( byte_shift >= 0 );
848
849 utf16_string[ string_index++ ] = (uint16_t) ')';
850
851 utf16_string[ string_index++ ] = 0;
852
853 *utf16_string_index = string_index;
854
855 return( 1 );
856 }
857
858 /* Converts the FAT date and time into an UTF-16 string
859 * The string size should include the end of string character
860 * Returns 1 if successful or -1 on error
861 */
libfdatetime_fat_date_time_copy_to_utf16_string(libfdatetime_fat_date_time_t * fat_date_time,uint16_t * utf16_string,size_t utf16_string_size,uint32_t string_format_flags,libcerror_error_t ** error)862 int libfdatetime_fat_date_time_copy_to_utf16_string(
863 libfdatetime_fat_date_time_t *fat_date_time,
864 uint16_t *utf16_string,
865 size_t utf16_string_size,
866 uint32_t string_format_flags,
867 libcerror_error_t **error )
868 {
869 static char *function = "libfdatetime_fat_date_time_copy_to_utf16_string";
870 size_t utf16_string_index = 0;
871
872 if( libfdatetime_fat_date_time_copy_to_utf16_string_with_index(
873 fat_date_time,
874 utf16_string,
875 utf16_string_size,
876 &utf16_string_index,
877 string_format_flags,
878 error ) != 1 )
879 {
880 libcerror_error_set(
881 error,
882 LIBCERROR_ERROR_DOMAIN_RUNTIME,
883 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
884 "%s: unable to copy FAT date time to UTF-16 string.",
885 function );
886
887 return( -1 );
888 }
889 return( 1 );
890 }
891
892 /* Converts the FAT date and time into an UTF-16 string
893 * The string size should include the end of string character
894 * Returns 1 if successful or -1 on error
895 */
libfdatetime_fat_date_time_copy_to_utf16_string_with_index(libfdatetime_fat_date_time_t * fat_date_time,uint16_t * utf16_string,size_t utf16_string_size,size_t * utf16_string_index,uint32_t string_format_flags,libcerror_error_t ** error)896 int libfdatetime_fat_date_time_copy_to_utf16_string_with_index(
897 libfdatetime_fat_date_time_t *fat_date_time,
898 uint16_t *utf16_string,
899 size_t utf16_string_size,
900 size_t *utf16_string_index,
901 uint32_t string_format_flags,
902 libcerror_error_t **error )
903 {
904 libfdatetime_date_time_values_t date_time_values;
905
906 libfdatetime_internal_fat_date_time_t *internal_fat_date_time = NULL;
907 static char *function = "libfdatetime_fat_date_time_copy_to_utf16_string_with_index";
908 int result = 0;
909
910 if( fat_date_time == NULL )
911 {
912 libcerror_error_set(
913 error,
914 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
915 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
916 "%s: invalid FAT date time.",
917 function );
918
919 return( -1 );
920 }
921 internal_fat_date_time = (libfdatetime_internal_fat_date_time_t *) fat_date_time;
922
923 result = libfdatetime_internal_fat_date_time_copy_to_date_time_values(
924 (libfdatetime_internal_fat_date_time_t *) fat_date_time,
925 &date_time_values,
926 error );
927
928 if( result != 1 )
929 {
930 #if defined( HAVE_DEBUG_OUTPUT )
931 libcerror_error_set(
932 error,
933 LIBCERROR_ERROR_DOMAIN_RUNTIME,
934 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
935 "%s: unable to set date time values.",
936 function );
937
938 /* TODO debug print error */
939
940 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
941
942 if( ( error != NULL )
943 && ( *error != NULL ) )
944 {
945 libcerror_error_free(
946 error );
947 }
948 }
949 else
950 {
951 result = libfdatetime_date_time_values_copy_to_utf16_string_with_index(
952 &date_time_values,
953 utf16_string,
954 utf16_string_size,
955 utf16_string_index,
956 string_format_flags,
957 error );
958
959 if( result == -1 )
960 {
961 libcerror_error_set(
962 error,
963 LIBCERROR_ERROR_DOMAIN_RUNTIME,
964 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
965 "%s: unable to copy date time values to UTF-16 string.",
966 function );
967
968 return( -1 );
969 }
970 }
971 if( result != 1 )
972 {
973 result = libfdatetime_internal_fat_date_time_copy_to_utf16_string_in_hexadecimal(
974 internal_fat_date_time,
975 utf16_string,
976 utf16_string_size,
977 utf16_string_index,
978 error );
979
980 if( result == -1 )
981 {
982 libcerror_error_set(
983 error,
984 LIBCERROR_ERROR_DOMAIN_RUNTIME,
985 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
986 "%s: unable to FAT date time values to hexadecimal UTF-16 string.",
987 function );
988
989 return( -1 );
990 }
991 }
992 return( 1 );
993 }
994
995 /* Converts the FAT date and time into an UTF-32 string in hexadecimal representation
996 * The string size should include the end of string character
997 * Returns 1 if successful or -1 on error
998 */
libfdatetime_internal_fat_date_time_copy_to_utf32_string_in_hexadecimal(libfdatetime_internal_fat_date_time_t * internal_fat_date_time,uint32_t * utf32_string,size_t utf32_string_size,size_t * utf32_string_index,libcerror_error_t ** error)999 int libfdatetime_internal_fat_date_time_copy_to_utf32_string_in_hexadecimal(
1000 libfdatetime_internal_fat_date_time_t *internal_fat_date_time,
1001 uint32_t *utf32_string,
1002 size_t utf32_string_size,
1003 size_t *utf32_string_index,
1004 libcerror_error_t **error )
1005 {
1006 static char *function = "libfdatetime_internal_fat_date_time_copy_to_utf32_string_in_hexadecimal";
1007 size_t string_index = 0;
1008 uint8_t byte_value = 0;
1009 int8_t byte_shift = 0;
1010
1011 if( internal_fat_date_time == NULL )
1012 {
1013 libcerror_error_set(
1014 error,
1015 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1016 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1017 "%s: invalid FAT date time.",
1018 function );
1019
1020 return( -1 );
1021 }
1022 if( utf32_string == NULL )
1023 {
1024 libcerror_error_set(
1025 error,
1026 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1027 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1028 "%s: invalid UTF-32 string.",
1029 function );
1030
1031 return( -1 );
1032 }
1033 if( utf32_string_size > (size_t) SSIZE_MAX )
1034 {
1035 libcerror_error_set(
1036 error,
1037 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1038 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1039 "%s: invalid UTF-32 string size value exceeds maximum.",
1040 function );
1041
1042 return( -1 );
1043 }
1044 if( utf32_string_index == NULL )
1045 {
1046 libcerror_error_set(
1047 error,
1048 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1049 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1050 "%s: invalid UTF-32 string index.",
1051 function );
1052
1053 return( -1 );
1054 }
1055 if( ( utf32_string_size < 16 )
1056 || ( *utf32_string_index > ( utf32_string_size - 16 ) ) )
1057 {
1058 libcerror_error_set(
1059 error,
1060 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1061 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1062 "%s: UTF-32 string is too small.",
1063 function );
1064
1065 return( -1 );
1066 }
1067 string_index = *utf32_string_index;
1068
1069 utf32_string[ string_index++ ] = (uint32_t) '(';
1070 utf32_string[ string_index++ ] = (uint32_t) '0';
1071 utf32_string[ string_index++ ] = (uint32_t) 'x';
1072
1073 byte_shift = 12;
1074
1075 do
1076 {
1077 byte_value = ( internal_fat_date_time->date >> byte_shift ) & 0x0f;
1078
1079 if( byte_value <= 9 )
1080 {
1081 utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
1082 }
1083 else
1084 {
1085 utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
1086 }
1087 byte_shift -= 4;
1088 }
1089 while( byte_shift >= 0 );
1090
1091 utf32_string[ string_index++ ] = (uint32_t) ' ';
1092 utf32_string[ string_index++ ] = (uint32_t) '0';
1093 utf32_string[ string_index++ ] = (uint32_t) 'x';
1094
1095 byte_shift = 12;
1096
1097 do
1098 {
1099 byte_value = ( internal_fat_date_time->time >> byte_shift ) & 0x0f;
1100
1101 if( byte_value <= 9 )
1102 {
1103 utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
1104 }
1105 else
1106 {
1107 utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
1108 }
1109 byte_shift -= 4;
1110 }
1111 while( byte_shift >= 0 );
1112
1113 utf32_string[ string_index++ ] = (uint32_t) ')';
1114
1115 utf32_string[ string_index++ ] = 0;
1116
1117 *utf32_string_index = string_index;
1118
1119 return( 1 );
1120 }
1121
1122 /* Converts the FAT date and time into an UTF-32 string
1123 * The string size should include the end of string character
1124 * Returns 1 if successful or -1 on error
1125 */
libfdatetime_fat_date_time_copy_to_utf32_string(libfdatetime_fat_date_time_t * fat_date_time,uint32_t * utf32_string,size_t utf32_string_size,uint32_t string_format_flags,libcerror_error_t ** error)1126 int libfdatetime_fat_date_time_copy_to_utf32_string(
1127 libfdatetime_fat_date_time_t *fat_date_time,
1128 uint32_t *utf32_string,
1129 size_t utf32_string_size,
1130 uint32_t string_format_flags,
1131 libcerror_error_t **error )
1132 {
1133 static char *function = "libfdatetime_fat_date_time_copy_to_utf32_string";
1134 size_t utf32_string_index = 0;
1135
1136 if( libfdatetime_fat_date_time_copy_to_utf32_string_with_index(
1137 fat_date_time,
1138 utf32_string,
1139 utf32_string_size,
1140 &utf32_string_index,
1141 string_format_flags,
1142 error ) != 1 )
1143 {
1144 libcerror_error_set(
1145 error,
1146 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1147 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1148 "%s: unable to copy FAT date time to UTF-32 string.",
1149 function );
1150
1151 return( -1 );
1152 }
1153 return( 1 );
1154 }
1155
1156 /* Converts the FAT date and time into an UTF-32 string
1157 * The string size should include the end of string character
1158 * Returns 1 if successful or -1 on error
1159 */
libfdatetime_fat_date_time_copy_to_utf32_string_with_index(libfdatetime_fat_date_time_t * fat_date_time,uint32_t * utf32_string,size_t utf32_string_size,size_t * utf32_string_index,uint32_t string_format_flags,libcerror_error_t ** error)1160 int libfdatetime_fat_date_time_copy_to_utf32_string_with_index(
1161 libfdatetime_fat_date_time_t *fat_date_time,
1162 uint32_t *utf32_string,
1163 size_t utf32_string_size,
1164 size_t *utf32_string_index,
1165 uint32_t string_format_flags,
1166 libcerror_error_t **error )
1167 {
1168 libfdatetime_date_time_values_t date_time_values;
1169
1170 libfdatetime_internal_fat_date_time_t *internal_fat_date_time = NULL;
1171 static char *function = "libfdatetime_fat_date_time_copy_to_utf32_string_with_index";
1172 int result = 0;
1173
1174 if( fat_date_time == NULL )
1175 {
1176 libcerror_error_set(
1177 error,
1178 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1179 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1180 "%s: invalid FAT date time.",
1181 function );
1182
1183 return( -1 );
1184 }
1185 internal_fat_date_time = (libfdatetime_internal_fat_date_time_t *) fat_date_time;
1186
1187 result = libfdatetime_internal_fat_date_time_copy_to_date_time_values(
1188 (libfdatetime_internal_fat_date_time_t *) fat_date_time,
1189 &date_time_values,
1190 error );
1191
1192 if( result != 1 )
1193 {
1194 #if defined( HAVE_DEBUG_OUTPUT )
1195 libcerror_error_set(
1196 error,
1197 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1198 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1199 "%s: unable to set date time values.",
1200 function );
1201
1202 /* TODO debug print error */
1203
1204 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
1205
1206 if( ( error != NULL )
1207 && ( *error != NULL ) )
1208 {
1209 libcerror_error_free(
1210 error );
1211 }
1212 }
1213 else
1214 {
1215 result = libfdatetime_date_time_values_copy_to_utf32_string_with_index(
1216 &date_time_values,
1217 utf32_string,
1218 utf32_string_size,
1219 utf32_string_index,
1220 string_format_flags,
1221 error );
1222
1223 if( result == -1 )
1224 {
1225 libcerror_error_set(
1226 error,
1227 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1228 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1229 "%s: unable to copy date time values to UTF-32 string.",
1230 function );
1231
1232 return( -1 );
1233 }
1234 }
1235 if( result != 1 )
1236 {
1237 result = libfdatetime_internal_fat_date_time_copy_to_utf32_string_in_hexadecimal(
1238 internal_fat_date_time,
1239 utf32_string,
1240 utf32_string_size,
1241 utf32_string_index,
1242 error );
1243
1244 if( result == -1 )
1245 {
1246 libcerror_error_set(
1247 error,
1248 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1249 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1250 "%s: unable to FAT date time values to hexadecimal UTF-32 string.",
1251 function );
1252
1253 return( -1 );
1254 }
1255 }
1256 return( 1 );
1257 }
1258
1259