Coverage Report

Created: 2024-02-25 07:20

/src/libesedb/libfdatetime/libfdatetime_fat_date_time.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * FAT date and time functions
3
 *
4
 * Copyright (C) 2009-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <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
 */
37
int libfdatetime_fat_date_time_initialize(
38
     libfdatetime_fat_date_time_t **fat_date_time,
39
     libcerror_error_t **error )
40
0
{
41
0
  libfdatetime_internal_fat_date_time_t *internal_fat_date_time = NULL;
42
0
  static char *function                                         = "libfdatetime_fat_date_time_initialize";
43
44
0
  if( fat_date_time == NULL )
45
0
  {
46
0
    libcerror_error_set(
47
0
     error,
48
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
49
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
50
0
     "%s: invalid FAT date time.",
51
0
     function );
52
53
0
    return( -1 );
54
0
  }
55
0
  if( *fat_date_time != NULL )
56
0
  {
57
0
    libcerror_error_set(
58
0
     error,
59
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
60
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
61
0
     "%s: invalid FAT date time value already set.",
62
0
     function );
63
64
0
    return( -1 );
65
0
  }
66
0
  internal_fat_date_time = memory_allocate_structure(
67
0
                            libfdatetime_internal_fat_date_time_t );
68
69
0
  if( internal_fat_date_time == NULL )
70
0
  {
71
0
    libcerror_error_set(
72
0
     error,
73
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
74
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
75
0
     "%s: unable to create FAT date time.",
76
0
     function );
77
78
0
    goto on_error;
79
0
  }
80
0
  if( memory_set(
81
0
       internal_fat_date_time,
82
0
       0,
83
0
       sizeof( libfdatetime_internal_fat_date_time_t ) ) == NULL )
84
0
  {
85
0
    libcerror_error_set(
86
0
     error,
87
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
88
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
89
0
     "%s: unable to clear FAT date time.",
90
0
     function );
91
92
0
    goto on_error;
93
0
  }
94
0
  *fat_date_time = (libfdatetime_fat_date_time_t *) internal_fat_date_time;
95
96
0
  return( 1 );
97
98
0
on_error:
99
0
  if( internal_fat_date_time != NULL )
100
0
  {
101
0
    memory_free(
102
0
     internal_fat_date_time );
103
0
  }
104
0
  return( -1 );
105
0
}
106
107
/* Frees a FAT date and time
108
 * Returns 1 if successful or -1 on error
109
 */
110
int libfdatetime_fat_date_time_free(
111
     libfdatetime_fat_date_time_t **fat_date_time,
112
     libcerror_error_t **error )
113
0
{
114
0
  libfdatetime_internal_fat_date_time_t *internal_fat_date_time = NULL;
115
0
  static char *function                                         = "libfdatetime_fat_date_time_free";
116
117
0
  if( fat_date_time == NULL )
118
0
  {
119
0
    libcerror_error_set(
120
0
     error,
121
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
122
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
123
0
     "%s: invalid FAT date time.",
124
0
     function );
125
126
0
    return( -1 );
127
0
  }
128
0
  if( *fat_date_time != NULL )
129
0
  {
130
0
    internal_fat_date_time = (libfdatetime_internal_fat_date_time_t *) *fat_date_time;
131
0
    *fat_date_time         = NULL;
132
133
0
    memory_free(
134
0
     internal_fat_date_time );
135
0
  }
136
0
  return( 1 );
137
0
}
138
139
/* Converts a byte stream into a FAT date and time
140
 * Returns 1 if successful or -1 on error
141
 */
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
0
{
149
0
  libfdatetime_internal_fat_date_time_t *internal_fat_date_time = NULL;
150
0
  static char *function                                         = "libfdatetime_fat_date_time_copy_from_byte_stream";
151
152
0
  if( fat_date_time == NULL )
153
0
  {
154
0
    libcerror_error_set(
155
0
     error,
156
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
157
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
158
0
     "%s: invalid FAT date time.",
159
0
     function );
160
161
0
    return( -1 );
162
0
  }
163
0
  internal_fat_date_time = (libfdatetime_internal_fat_date_time_t *) fat_date_time;
164
165
0
  if( byte_stream == NULL )
166
0
  {
167
0
    libcerror_error_set(
168
0
     error,
169
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
170
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
171
0
     "%s: invalid byte stream.",
172
0
     function );
173
174
0
    return( -1 );
175
0
  }
176
0
  if( byte_stream_size < 4 )
177
0
  {
178
0
    libcerror_error_set(
179
0
     error,
180
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
181
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
182
0
     "%s: byte stream too small.",
183
0
     function );
184
185
0
    return( -1 );
186
0
  }
187
0
  if( byte_stream_size > (size_t) SSIZE_MAX )
188
0
  {
189
0
    libcerror_error_set(
190
0
     error,
191
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
192
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
193
0
     "%s: byte stream size exceeds maximum.",
194
0
     function );
195
196
0
    return( -1 );
197
0
  }
198
0
  if( ( byte_order != LIBFDATETIME_ENDIAN_BIG )
199
0
   && ( byte_order != LIBFDATETIME_ENDIAN_LITTLE ) )
200
0
  {
201
0
    libcerror_error_set(
202
0
     error,
203
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
204
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
205
0
     "%s: unsupported byte order.",
206
0
     function );
207
208
0
    return( -1 );
209
0
  }
210
0
  if( byte_order == LIBFDATETIME_ENDIAN_LITTLE )
211
0
  {
212
0
    byte_stream_copy_to_uint16_little_endian(
213
0
     byte_stream,
214
0
     internal_fat_date_time->date );
215
216
0
    byte_stream += 2;
217
218
0
    byte_stream_copy_to_uint16_little_endian(
219
0
    byte_stream,
220
0
    internal_fat_date_time->time );
221
0
  }
222
0
  else if( byte_order == LIBFDATETIME_ENDIAN_BIG )
223
0
  {
224
0
    byte_stream_copy_to_uint16_big_endian(
225
0
     byte_stream,
226
0
     internal_fat_date_time->date );
227
228
0
    byte_stream += 2;
229
230
0
    byte_stream_copy_to_uint16_big_endian(
231
0
    byte_stream,
232
0
    internal_fat_date_time->time );
233
0
  }
234
0
  return( 1 );
235
0
}
236
237
/* Converts a 32-bit value into a FAT date and time
238
 * Returns 1 if successful or -1 on error
239
 */
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
0
{
245
0
  libfdatetime_internal_fat_date_time_t *internal_fat_date_time = NULL;
246
0
  static char *function                                         = "libfdatetime_fat_date_time_copy_from_32bit";
247
248
0
  if( fat_date_time == NULL )
249
0
  {
250
0
    libcerror_error_set(
251
0
     error,
252
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
253
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
254
0
     "%s: invalid FAT date time.",
255
0
     function );
256
257
0
    return( -1 );
258
0
  }
259
0
  internal_fat_date_time = (libfdatetime_internal_fat_date_time_t *) fat_date_time;
260
261
0
  internal_fat_date_time->date = (uint16_t) ( value_32bit & 0x0ffffL );
262
0
  internal_fat_date_time->time = (uint16_t) ( value_32bit >> 16 );
263
264
0
  return( 1 );
265
0
}
266
267
/* Converts a FAT date and time into a 32-bit value
268
 * Returns 1 if successful or -1 on error
269
 */
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
0
{
275
0
  libfdatetime_internal_fat_date_time_t *internal_fat_date_time = NULL;
276
0
  static char *function                                         = "libfdatetime_fat_date_time_copy_to_32bit";
277
278
0
  if( fat_date_time == NULL )
279
0
  {
280
0
    libcerror_error_set(
281
0
     error,
282
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
283
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
284
0
     "%s: invalid FAT date time.",
285
0
     function );
286
287
0
    return( -1 );
288
0
  }
289
0
  internal_fat_date_time = (libfdatetime_internal_fat_date_time_t *) fat_date_time;
290
291
0
  if( value_32bit == NULL )
292
0
  {
293
0
    libcerror_error_set(
294
0
     error,
295
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
296
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
297
0
     "%s: invalid 32-bit value.",
298
0
     function );
299
300
0
    return( -1 );
301
0
  }
302
0
  *value_32bit   = internal_fat_date_time->time;
303
0
  *value_32bit <<= 16;
304
0
  *value_32bit  |= internal_fat_date_time->date;
305
306
0
  return( 1 );
307
0
}
308
309
/* Converts a FAT date and time into date time values
310
 * Returns 1 if successful or -1 on error
311
 */
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
0
{
317
0
  static char *function = "libfdatetime_internal_fat_date_time_copy_to_date_time_values";
318
319
0
  if( internal_fat_date_time == NULL )
320
0
  {
321
0
    libcerror_error_set(
322
0
     error,
323
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
324
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
325
0
     "%s: invalid FAT date time.",
326
0
     function );
327
328
0
    return( -1 );
329
0
  }
330
0
  if( date_time_values == NULL )
331
0
  {
332
0
    libcerror_error_set(
333
0
     error,
334
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
335
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
336
0
     "%s: invalid date time values.",
337
0
     function );
338
339
0
    return( -1 );
340
0
  }
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
0
  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
0
  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
0
  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
0
  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
0
  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
0
  date_time_values->seconds = (uint8_t) ( internal_fat_date_time->time & 0x1f ) * 2;
367
368
0
        date_time_values->milli_seconds = 0;
369
0
        date_time_values->micro_seconds = 0;
370
0
        date_time_values->nano_seconds  = 0;
371
372
0
  return( 1 );
373
0
}
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
 */
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
0
{
385
0
  libfdatetime_date_time_values_t date_time_values;
386
387
0
  static char *function = "libfdatetime_fat_date_time_get_string_size";
388
0
  int result            = 0;
389
390
0
  if( fat_date_time == NULL )
391
0
  {
392
0
    libcerror_error_set(
393
0
     error,
394
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
395
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
396
0
     "%s: invalid FAT date time.",
397
0
     function );
398
399
0
    return( -1 );
400
0
  }
401
0
  if( string_size == NULL )
402
0
  {
403
0
    libcerror_error_set(
404
0
     error,
405
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
406
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
407
0
     "%s: invalid string size.",
408
0
     function );
409
410
0
    return( -1 );
411
0
  }
412
0
  result = libfdatetime_internal_fat_date_time_copy_to_date_time_values(
413
0
            (libfdatetime_internal_fat_date_time_t *) fat_date_time,
414
0
            &date_time_values,
415
0
            error );
416
417
0
  if( result != 1 )
418
0
  {
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
0
    if( ( error != NULL )
432
0
     && ( *error != NULL ) )
433
0
    {
434
0
      libcerror_error_free(
435
0
       error );
436
0
    }
437
0
  }
438
0
  else
439
0
  {
440
0
    result = libfdatetime_date_time_values_get_string_size(
441
0
              &date_time_values,
442
0
              string_size,
443
0
              string_format_flags,
444
0
              error );
445
446
0
    if( result == -1 )
447
0
    {
448
0
      libcerror_error_set(
449
0
       error,
450
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
451
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
452
0
       "%s: unable to get string size.",
453
0
       function );
454
455
0
      return( -1 );
456
0
    }
457
0
  }
458
0
  if( result != 1 )
459
0
  {
460
    /* Make sure the string can hold the hexadecimal representation of the FAT date time
461
     */
462
0
    *string_size = 16;
463
0
  }
464
0
  return( 1 );
465
0
}
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
 */
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
0
{
478
0
  static char *function = "libfdatetime_internal_fat_date_time_copy_to_utf8_string_in_hexadecimal";
479
0
  size_t string_index   = 0;
480
0
  uint8_t byte_value    = 0;
481
0
  int8_t byte_shift     = 0;
482
483
0
  if( internal_fat_date_time == NULL )
484
0
  {
485
0
    libcerror_error_set(
486
0
     error,
487
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
488
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
489
0
     "%s: invalid FAT date time.",
490
0
     function );
491
492
0
    return( -1 );
493
0
  }
494
0
  if( utf8_string == NULL )
495
0
  {
496
0
    libcerror_error_set(
497
0
     error,
498
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
499
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
500
0
     "%s: invalid UTF-8 string.",
501
0
     function );
502
503
0
    return( -1 );
504
0
  }
505
0
  if( utf8_string_size > (size_t) SSIZE_MAX )
506
0
  {
507
0
    libcerror_error_set(
508
0
     error,
509
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
510
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
511
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
512
0
     function );
513
514
0
    return( -1 );
515
0
  }
516
0
  if( utf8_string_index == NULL )
517
0
  {
518
0
    libcerror_error_set(
519
0
     error,
520
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
521
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
522
0
     "%s: invalid UTF-8 string index.",
523
0
     function );
524
525
0
    return( -1 );
526
0
  }
527
0
  if( ( utf8_string_size < 16 )
528
0
   || ( *utf8_string_index > ( utf8_string_size - 16 ) ) )
529
0
  {
530
0
    libcerror_error_set(
531
0
     error,
532
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
533
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
534
0
     "%s: UTF-8 string is too small.",
535
0
     function );
536
537
0
    return( -1 );
538
0
  }
539
0
  string_index = *utf8_string_index;
540
541
0
  utf8_string[ string_index++ ] = (uint8_t) '(';
542
0
  utf8_string[ string_index++ ] = (uint8_t) '0';
543
0
  utf8_string[ string_index++ ] = (uint8_t) 'x';
544
545
0
  byte_shift = 12;
546
547
0
  do
548
0
  {
549
0
    byte_value = ( internal_fat_date_time->date >> byte_shift ) & 0x0f;
550
551
0
    if( byte_value <= 9 )
552
0
    {
553
0
      utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
554
0
    }
555
0
    else
556
0
    {
557
0
      utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
558
0
    }
559
0
    byte_shift -= 4;
560
0
  }
561
0
  while( byte_shift >= 0 );
562
563
0
  utf8_string[ string_index++ ] = (uint8_t) ' ';
564
0
  utf8_string[ string_index++ ] = (uint8_t) '0';
565
0
  utf8_string[ string_index++ ] = (uint8_t) 'x';
566
567
0
  byte_shift = 12;
568
569
0
  do
570
0
  {
571
0
    byte_value = ( internal_fat_date_time->time >> byte_shift ) & 0x0f;
572
573
0
    if( byte_value <= 9 )
574
0
    {
575
0
      utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
576
0
    }
577
0
    else
578
0
    {
579
0
      utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
580
0
    }
581
0
    byte_shift -= 4;
582
0
  }
583
0
  while( byte_shift >= 0 );
584
585
0
  utf8_string[ string_index++ ] = (uint8_t) ')';
586
587
0
  utf8_string[ string_index++ ] = 0;
588
589
0
  *utf8_string_index = string_index;
590
591
0
  return( 1 );
592
0
}
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
 */
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
0
{
605
0
  static char *function    = "libfdatetime_fat_date_time_copy_to_utf8_string";
606
0
  size_t utf8_string_index = 0;
607
608
0
  if( libfdatetime_fat_date_time_copy_to_utf8_string_with_index(
609
0
       fat_date_time,
610
0
       utf8_string,
611
0
       utf8_string_size,
612
0
       &utf8_string_index,
613
0
       string_format_flags,
614
0
       error ) != 1 )
615
0
  {
616
0
    libcerror_error_set(
617
0
     error,
618
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
619
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
620
0
     "%s: unable to copy FAT date time to UTF-8 string.",
621
0
     function );
622
623
0
    return( -1 );
624
0
  }
625
0
  return( 1 );
626
0
}
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
 */
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
0
{
640
0
  libfdatetime_date_time_values_t date_time_values;
641
642
0
  libfdatetime_internal_fat_date_time_t *internal_fat_date_time = NULL;
643
0
  static char *function                                         = "libfdatetime_fat_date_time_copy_to_utf8_string_with_index";
644
0
  int result                                                    = 0;
645
646
0
  if( fat_date_time == NULL )
647
0
  {
648
0
    libcerror_error_set(
649
0
     error,
650
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
651
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
652
0
     "%s: invalid FAT date time.",
653
0
     function );
654
655
0
    return( -1 );
656
0
  }
657
0
  internal_fat_date_time = (libfdatetime_internal_fat_date_time_t *) fat_date_time;
658
659
0
  result = libfdatetime_internal_fat_date_time_copy_to_date_time_values(
660
0
            internal_fat_date_time,
661
0
            &date_time_values,
662
0
            error );
663
664
0
  if( result != 1 )
665
0
  {
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
0
    if( ( error != NULL )
679
0
     && ( *error != NULL ) )
680
0
    {
681
0
      libcerror_error_free(
682
0
       error );
683
0
    }
684
0
  }
685
0
  else
686
0
  {
687
0
    result = libfdatetime_date_time_values_copy_to_utf8_string_with_index(
688
0
              &date_time_values,
689
0
              utf8_string,
690
0
              utf8_string_size,
691
0
              utf8_string_index,
692
0
              string_format_flags,
693
0
              error );
694
695
0
    if( result == -1 )
696
0
    {
697
0
      libcerror_error_set(
698
0
       error,
699
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
700
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
701
0
       "%s: unable to copy date time values to UTF-8 string.",
702
0
       function );
703
704
0
      return( -1 );
705
0
    }
706
0
  }
707
0
  if( result != 1 )
708
0
  {
709
0
    result = libfdatetime_internal_fat_date_time_copy_to_utf8_string_in_hexadecimal(
710
0
              internal_fat_date_time,
711
0
              utf8_string,
712
0
              utf8_string_size,
713
0
              utf8_string_index,
714
0
              error );
715
716
0
    if( result == -1 )
717
0
    {
718
0
      libcerror_error_set(
719
0
       error,
720
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
721
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
722
0
       "%s: unable to FAT date time values to hexadecimal UTF-8 string.",
723
0
       function );
724
725
0
      return( -1 );
726
0
    }
727
0
  }
728
0
  return( 1 );
729
0
}
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
 */
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
0
{
742
0
  static char *function = "libfdatetime_internal_fat_date_time_copy_to_utf16_string_in_hexadecimal";
743
0
  size_t string_index   = 0;
744
0
  uint8_t byte_value    = 0;
745
0
  int8_t byte_shift     = 0;
746
747
0
  if( internal_fat_date_time == NULL )
748
0
  {
749
0
    libcerror_error_set(
750
0
     error,
751
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
752
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
753
0
     "%s: invalid FAT date time.",
754
0
     function );
755
756
0
    return( -1 );
757
0
  }
758
0
  if( utf16_string == NULL )
759
0
  {
760
0
    libcerror_error_set(
761
0
     error,
762
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
763
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
764
0
     "%s: invalid UTF-16 string.",
765
0
     function );
766
767
0
    return( -1 );
768
0
  }
769
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
770
0
  {
771
0
    libcerror_error_set(
772
0
     error,
773
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
774
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
775
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
776
0
     function );
777
778
0
    return( -1 );
779
0
  }
780
0
  if( utf16_string_index == NULL )
781
0
  {
782
0
    libcerror_error_set(
783
0
     error,
784
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
785
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
786
0
     "%s: invalid UTF-16 string index.",
787
0
     function );
788
789
0
    return( -1 );
790
0
  }
791
0
  if( ( utf16_string_size < 16 )
792
0
   || ( *utf16_string_index > ( utf16_string_size - 16 ) ) )
793
0
  {
794
0
    libcerror_error_set(
795
0
     error,
796
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
797
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
798
0
     "%s: UTF-16 string is too small.",
799
0
     function );
800
801
0
    return( -1 );
802
0
  }
803
0
  string_index = *utf16_string_index;
804
805
0
  utf16_string[ string_index++ ] = (uint16_t) '(';
806
0
  utf16_string[ string_index++ ] = (uint16_t) '0';
807
0
  utf16_string[ string_index++ ] = (uint16_t) 'x';
808
809
0
  byte_shift = 12;
810
811
0
  do
812
0
  {
813
0
    byte_value = ( internal_fat_date_time->date >> byte_shift ) & 0x0f;
814
815
0
    if( byte_value <= 9 )
816
0
    {
817
0
      utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
818
0
    }
819
0
    else
820
0
    {
821
0
      utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
822
0
    }
823
0
    byte_shift -= 4;
824
0
  }
825
0
  while( byte_shift >= 0 );
826
827
0
  utf16_string[ string_index++ ] = (uint16_t) ' ';
828
0
  utf16_string[ string_index++ ] = (uint16_t) '0';
829
0
  utf16_string[ string_index++ ] = (uint16_t) 'x';
830
831
0
  byte_shift = 12;
832
833
0
  do
834
0
  {
835
0
    byte_value = ( internal_fat_date_time->time >> byte_shift ) & 0x0f;
836
837
0
    if( byte_value <= 9 )
838
0
    {
839
0
      utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
840
0
    }
841
0
    else
842
0
    {
843
0
      utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
844
0
    }
845
0
    byte_shift -= 4;
846
0
  }
847
0
  while( byte_shift >= 0 );
848
849
0
  utf16_string[ string_index++ ] = (uint16_t) ')';
850
851
0
  utf16_string[ string_index++ ] = 0;
852
853
0
  *utf16_string_index = string_index;
854
855
0
  return( 1 );
856
0
}
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
 */
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
0
{
869
0
  static char *function     = "libfdatetime_fat_date_time_copy_to_utf16_string";
870
0
  size_t utf16_string_index = 0;
871
872
0
  if( libfdatetime_fat_date_time_copy_to_utf16_string_with_index(
873
0
       fat_date_time,
874
0
       utf16_string,
875
0
       utf16_string_size,
876
0
       &utf16_string_index,
877
0
       string_format_flags,
878
0
       error ) != 1 )
879
0
  {
880
0
    libcerror_error_set(
881
0
     error,
882
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
883
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
884
0
     "%s: unable to copy FAT date time to UTF-16 string.",
885
0
     function );
886
887
0
    return( -1 );
888
0
  }
889
0
  return( 1 );
890
0
}
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
 */
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
0
{
904
0
  libfdatetime_date_time_values_t date_time_values;
905
906
0
  libfdatetime_internal_fat_date_time_t *internal_fat_date_time = NULL;
907
0
  static char *function                                         = "libfdatetime_fat_date_time_copy_to_utf16_string_with_index";
908
0
  int result                                                    = 0;
909
910
0
  if( fat_date_time == NULL )
911
0
  {
912
0
    libcerror_error_set(
913
0
     error,
914
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
915
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
916
0
     "%s: invalid FAT date time.",
917
0
     function );
918
919
0
    return( -1 );
920
0
  }
921
0
  internal_fat_date_time = (libfdatetime_internal_fat_date_time_t *) fat_date_time;
922
923
0
  result = libfdatetime_internal_fat_date_time_copy_to_date_time_values(
924
0
            (libfdatetime_internal_fat_date_time_t *) fat_date_time,
925
0
            &date_time_values,
926
0
            error );
927
928
0
  if( result != 1 )
929
0
  {
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
0
    if( ( error != NULL )
943
0
     && ( *error != NULL ) )
944
0
    {
945
0
      libcerror_error_free(
946
0
       error );
947
0
    }
948
0
  }
949
0
  else
950
0
  {
951
0
    result = libfdatetime_date_time_values_copy_to_utf16_string_with_index(
952
0
              &date_time_values,
953
0
              utf16_string,
954
0
              utf16_string_size,
955
0
              utf16_string_index,
956
0
              string_format_flags,
957
0
              error );
958
959
0
    if( result == -1 )
960
0
    {
961
0
      libcerror_error_set(
962
0
       error,
963
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
964
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
965
0
       "%s: unable to copy date time values to UTF-16 string.",
966
0
       function );
967
968
0
      return( -1 );
969
0
    }
970
0
  }
971
0
  if( result != 1 )
972
0
  {
973
0
    result = libfdatetime_internal_fat_date_time_copy_to_utf16_string_in_hexadecimal(
974
0
              internal_fat_date_time,
975
0
              utf16_string,
976
0
              utf16_string_size,
977
0
              utf16_string_index,
978
0
              error );
979
980
0
    if( result == -1 )
981
0
    {
982
0
      libcerror_error_set(
983
0
       error,
984
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
985
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
986
0
       "%s: unable to FAT date time values to hexadecimal UTF-16 string.",
987
0
       function );
988
989
0
      return( -1 );
990
0
    }
991
0
  }
992
0
  return( 1 );
993
0
}
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
 */
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
0
{
1006
0
  static char *function = "libfdatetime_internal_fat_date_time_copy_to_utf32_string_in_hexadecimal";
1007
0
  size_t string_index   = 0;
1008
0
  uint8_t byte_value    = 0;
1009
0
  int8_t byte_shift     = 0;
1010
1011
0
  if( internal_fat_date_time == NULL )
1012
0
  {
1013
0
    libcerror_error_set(
1014
0
     error,
1015
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1016
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1017
0
     "%s: invalid FAT date time.",
1018
0
     function );
1019
1020
0
    return( -1 );
1021
0
  }
1022
0
  if( utf32_string == NULL )
1023
0
  {
1024
0
    libcerror_error_set(
1025
0
     error,
1026
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1027
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1028
0
     "%s: invalid UTF-32 string.",
1029
0
     function );
1030
1031
0
    return( -1 );
1032
0
  }
1033
0
  if( utf32_string_size > (size_t) SSIZE_MAX )
1034
0
  {
1035
0
    libcerror_error_set(
1036
0
     error,
1037
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1038
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1039
0
     "%s: invalid UTF-32 string size value exceeds maximum.",
1040
0
     function );
1041
1042
0
    return( -1 );
1043
0
  }
1044
0
  if( utf32_string_index == NULL )
1045
0
  {
1046
0
    libcerror_error_set(
1047
0
     error,
1048
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1049
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1050
0
     "%s: invalid UTF-32 string index.",
1051
0
     function );
1052
1053
0
    return( -1 );
1054
0
  }
1055
0
  if( ( utf32_string_size < 16 )
1056
0
   || ( *utf32_string_index > ( utf32_string_size - 16 ) ) )
1057
0
  {
1058
0
    libcerror_error_set(
1059
0
     error,
1060
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1061
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1062
0
     "%s: UTF-32 string is too small.",
1063
0
     function );
1064
1065
0
    return( -1 );
1066
0
  }
1067
0
  string_index = *utf32_string_index;
1068
1069
0
  utf32_string[ string_index++ ] = (uint32_t) '(';
1070
0
  utf32_string[ string_index++ ] = (uint32_t) '0';
1071
0
  utf32_string[ string_index++ ] = (uint32_t) 'x';
1072
1073
0
  byte_shift = 12;
1074
1075
0
  do
1076
0
  {
1077
0
    byte_value = ( internal_fat_date_time->date >> byte_shift ) & 0x0f;
1078
1079
0
    if( byte_value <= 9 )
1080
0
    {
1081
0
      utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
1082
0
    }
1083
0
    else
1084
0
    {
1085
0
      utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
1086
0
    }
1087
0
    byte_shift -= 4;
1088
0
  }
1089
0
  while( byte_shift >= 0 );
1090
1091
0
  utf32_string[ string_index++ ] = (uint32_t) ' ';
1092
0
  utf32_string[ string_index++ ] = (uint32_t) '0';
1093
0
  utf32_string[ string_index++ ] = (uint32_t) 'x';
1094
1095
0
  byte_shift = 12;
1096
1097
0
  do
1098
0
  {
1099
0
    byte_value = ( internal_fat_date_time->time >> byte_shift ) & 0x0f;
1100
1101
0
    if( byte_value <= 9 )
1102
0
    {
1103
0
      utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
1104
0
    }
1105
0
    else
1106
0
    {
1107
0
      utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
1108
0
    }
1109
0
    byte_shift -= 4;
1110
0
  }
1111
0
  while( byte_shift >= 0 );
1112
1113
0
  utf32_string[ string_index++ ] = (uint32_t) ')';
1114
1115
0
  utf32_string[ string_index++ ] = 0;
1116
1117
0
  *utf32_string_index = string_index;
1118
1119
0
  return( 1 );
1120
0
}
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
 */
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
0
{
1133
0
  static char *function     = "libfdatetime_fat_date_time_copy_to_utf32_string";
1134
0
  size_t utf32_string_index = 0;
1135
1136
0
  if( libfdatetime_fat_date_time_copy_to_utf32_string_with_index(
1137
0
       fat_date_time,
1138
0
       utf32_string,
1139
0
       utf32_string_size,
1140
0
       &utf32_string_index,
1141
0
       string_format_flags,
1142
0
       error ) != 1 )
1143
0
  {
1144
0
    libcerror_error_set(
1145
0
     error,
1146
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1147
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1148
0
     "%s: unable to copy FAT date time to UTF-32 string.",
1149
0
     function );
1150
1151
0
    return( -1 );
1152
0
  }
1153
0
  return( 1 );
1154
0
}
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
 */
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
0
{
1168
0
  libfdatetime_date_time_values_t date_time_values;
1169
1170
0
  libfdatetime_internal_fat_date_time_t *internal_fat_date_time = NULL;
1171
0
  static char *function                                         = "libfdatetime_fat_date_time_copy_to_utf32_string_with_index";
1172
0
  int result                                                    = 0;
1173
1174
0
  if( fat_date_time == NULL )
1175
0
  {
1176
0
    libcerror_error_set(
1177
0
     error,
1178
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1179
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1180
0
     "%s: invalid FAT date time.",
1181
0
     function );
1182
1183
0
    return( -1 );
1184
0
  }
1185
0
  internal_fat_date_time = (libfdatetime_internal_fat_date_time_t *) fat_date_time;
1186
1187
0
  result = libfdatetime_internal_fat_date_time_copy_to_date_time_values(
1188
0
            (libfdatetime_internal_fat_date_time_t *) fat_date_time,
1189
0
            &date_time_values,
1190
0
            error );
1191
1192
0
  if( result != 1 )
1193
0
  {
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
0
    if( ( error != NULL )
1207
0
     && ( *error != NULL ) )
1208
0
    {
1209
0
      libcerror_error_free(
1210
0
       error );
1211
0
    }
1212
0
  }
1213
0
  else
1214
0
  {
1215
0
    result = libfdatetime_date_time_values_copy_to_utf32_string_with_index(
1216
0
              &date_time_values,
1217
0
              utf32_string,
1218
0
              utf32_string_size,
1219
0
              utf32_string_index,
1220
0
              string_format_flags,
1221
0
              error );
1222
1223
0
    if( result == -1 )
1224
0
    {
1225
0
      libcerror_error_set(
1226
0
       error,
1227
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1228
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1229
0
       "%s: unable to copy date time values to UTF-32 string.",
1230
0
       function );
1231
1232
0
      return( -1 );
1233
0
    }
1234
0
  }
1235
0
  if( result != 1 )
1236
0
  {
1237
0
    result = libfdatetime_internal_fat_date_time_copy_to_utf32_string_in_hexadecimal(
1238
0
              internal_fat_date_time,
1239
0
              utf32_string,
1240
0
              utf32_string_size,
1241
0
              utf32_string_index,
1242
0
              error );
1243
1244
0
    if( result == -1 )
1245
0
    {
1246
0
      libcerror_error_set(
1247
0
       error,
1248
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1249
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1250
0
       "%s: unable to FAT date time values to hexadecimal UTF-32 string.",
1251
0
       function );
1252
1253
0
      return( -1 );
1254
0
    }
1255
0
  }
1256
0
  return( 1 );
1257
0
}
1258