Coverage Report

Created: 2024-02-25 07:19

/src/libwrc/libfdatetime/libfdatetime_filetime.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * FILETIME 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_filetime.h"
30
#include "libfdatetime_libcerror.h"
31
#include "libfdatetime_types.h"
32
33
/* Creates a FILETIME
34
 * Make sure the value filetime is referencing, is set to NULL
35
 * Returns 1 if successful or -1 on error
36
 */
37
int libfdatetime_filetime_initialize(
38
     libfdatetime_filetime_t **filetime,
39
     libcerror_error_t **error )
40
0
{
41
0
  libfdatetime_internal_filetime_t *internal_filetime = NULL;
42
0
  static char *function                               = "libfdatetime_filetime_initialize";
43
44
0
  if( filetime == 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 FILETIME.",
51
0
     function );
52
53
0
    return( -1 );
54
0
  }
55
0
  if( *filetime != 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 FILETIME value already set.",
62
0
     function );
63
64
0
    return( -1 );
65
0
  }
66
0
  internal_filetime = memory_allocate_structure(
67
0
                       libfdatetime_internal_filetime_t );
68
69
0
  if( internal_filetime == 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 FILETIME.",
76
0
     function );
77
78
0
    goto on_error;
79
0
  }
80
0
  if( memory_set(
81
0
       internal_filetime,
82
0
       0,
83
0
       sizeof( libfdatetime_internal_filetime_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 FILETIME.",
90
0
     function );
91
92
0
    goto on_error;
93
0
  }
94
0
  *filetime = (libfdatetime_filetime_t *) internal_filetime;
95
96
0
  return( 1 );
97
98
0
on_error:
99
0
  if( internal_filetime != NULL )
100
0
  {
101
0
    memory_free(
102
0
     internal_filetime );
103
0
  }
104
0
  return( -1 );
105
0
}
106
107
/* Frees a FILETIME
108
 * Returns 1 if successful or -1 on error
109
 */
110
int libfdatetime_filetime_free(
111
     libfdatetime_filetime_t **filetime,
112
     libcerror_error_t **error )
113
0
{
114
0
  libfdatetime_internal_filetime_t *internal_filetime = NULL;
115
0
  static char *function                               = "libfdatetime_filetime_free";
116
117
0
  if( filetime == 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 FILETIME.",
124
0
     function );
125
126
0
    return( -1 );
127
0
  }
128
0
  if( *filetime != NULL )
129
0
  {
130
0
    internal_filetime = (libfdatetime_internal_filetime_t *) *filetime;
131
0
    *filetime         = NULL;
132
133
0
    memory_free(
134
0
     internal_filetime );
135
0
  }
136
0
  return( 1 );
137
0
}
138
139
/* Adds the additional FILETIME to the FILETIME
140
 * Returns 1 if successful or -1 on error
141
 */
142
int libfdatetime_filetime_add(
143
     libfdatetime_filetime_t *filetime,
144
     libfdatetime_filetime_t *additional_filetime,
145
     libcerror_error_t **error )
146
0
{
147
0
  libfdatetime_internal_filetime_t *internal_additional_filetime = NULL;
148
0
  libfdatetime_internal_filetime_t *internal_filetime            = NULL;
149
0
  static char *function                                          = "libfdatetime_filetime_add";
150
151
0
  if( filetime == NULL )
152
0
  {
153
0
    libcerror_error_set(
154
0
     error,
155
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
156
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
157
0
     "%s: invalid FILETIME.",
158
0
     function );
159
160
0
    return( -1 );
161
0
  }
162
0
  internal_filetime = (libfdatetime_internal_filetime_t *) filetime;
163
164
0
  if( additional_filetime == NULL )
165
0
  {
166
0
    libcerror_error_set(
167
0
     error,
168
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
169
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
170
0
     "%s: invalid additional FILETIME.",
171
0
     function );
172
173
0
    return( -1 );
174
0
  }
175
0
  internal_additional_filetime = (libfdatetime_internal_filetime_t *) additional_filetime;
176
177
0
  internal_filetime->lower += internal_additional_filetime->lower;
178
0
  internal_filetime->upper += internal_additional_filetime->upper;
179
180
0
  return( 1 );
181
0
}
182
183
/* Converts a byte stream into a FILETIME
184
 * Returns 1 if successful or -1 on error
185
 */
186
int libfdatetime_filetime_copy_from_byte_stream(
187
     libfdatetime_filetime_t *filetime,
188
     const uint8_t *byte_stream,
189
     size_t byte_stream_size,
190
     int byte_order,
191
     libcerror_error_t **error )
192
0
{
193
0
  libfdatetime_internal_filetime_t *internal_filetime = NULL;
194
0
  static char *function                               = "libfdatetime_filetime_copy_from_byte_stream";
195
196
0
  if( filetime == NULL )
197
0
  {
198
0
    libcerror_error_set(
199
0
     error,
200
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
201
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
202
0
     "%s: invalid FILETIME.",
203
0
     function );
204
205
0
    return( -1 );
206
0
  }
207
0
  internal_filetime = (libfdatetime_internal_filetime_t *) filetime;
208
209
0
  if( byte_stream == NULL )
210
0
  {
211
0
    libcerror_error_set(
212
0
     error,
213
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
214
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
215
0
     "%s: invalid byte stream.",
216
0
     function );
217
218
0
    return( -1 );
219
0
  }
220
0
  if( byte_stream_size < 8 )
221
0
  {
222
0
    libcerror_error_set(
223
0
     error,
224
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
225
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
226
0
     "%s: byte stream too small.",
227
0
     function );
228
229
0
    return( -1 );
230
0
  }
231
0
  if( byte_stream_size > (size_t) SSIZE_MAX )
232
0
  {
233
0
    libcerror_error_set(
234
0
     error,
235
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
236
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
237
0
     "%s: byte stream size exceeds maximum.",
238
0
     function );
239
240
0
    return( -1 );
241
0
  }
242
0
  if( ( byte_order != LIBFDATETIME_ENDIAN_BIG )
243
0
   && ( byte_order != LIBFDATETIME_ENDIAN_LITTLE ) )
244
0
  {
245
0
    libcerror_error_set(
246
0
     error,
247
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
248
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
249
0
     "%s: unsupported byte order.",
250
0
     function );
251
252
0
    return( -1 );
253
0
  }
254
0
  if( byte_order == LIBFDATETIME_ENDIAN_LITTLE )
255
0
  {
256
0
    byte_stream_copy_to_uint32_little_endian(
257
0
     byte_stream,
258
0
     internal_filetime->lower );
259
260
0
    byte_stream += 4;
261
262
0
    byte_stream_copy_to_uint32_little_endian(
263
0
     byte_stream,
264
0
     internal_filetime->upper );
265
0
  }
266
0
  else if( byte_order == LIBFDATETIME_ENDIAN_BIG )
267
0
  {
268
0
    byte_stream_copy_to_uint32_big_endian(
269
0
     byte_stream,
270
0
     internal_filetime->upper );
271
272
0
    byte_stream += 4;
273
274
0
    byte_stream_copy_to_uint32_big_endian(
275
0
     byte_stream,
276
0
     internal_filetime->lower );
277
0
  }
278
0
  return( 1 );
279
0
}
280
281
/* Converts a 64-bit value into a FILETIME
282
 * Returns 1 if successful or -1 on error
283
 */
284
int libfdatetime_filetime_copy_from_64bit(
285
     libfdatetime_filetime_t *filetime,
286
     uint64_t value_64bit,
287
     libcerror_error_t **error )
288
0
{
289
0
  libfdatetime_internal_filetime_t *internal_filetime = NULL;
290
0
  static char *function                               = "libfdatetime_filetime_copy_from_64bit";
291
292
0
  if( filetime == NULL )
293
0
  {
294
0
    libcerror_error_set(
295
0
     error,
296
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
297
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
298
0
     "%s: invalid FILETIME.",
299
0
     function );
300
301
0
    return( -1 );
302
0
  }
303
0
  internal_filetime = (libfdatetime_internal_filetime_t *) filetime;
304
305
0
  internal_filetime->upper = value_64bit >> 32;
306
0
  internal_filetime->lower = value_64bit & 0xffffffffUL;
307
308
0
  return( 1 );
309
0
}
310
311
/* Converts a FILETIME into a 64-bit value
312
 * Returns 1 if successful or -1 on error
313
 */
314
int libfdatetime_filetime_copy_to_64bit(
315
     libfdatetime_filetime_t *filetime,
316
     uint64_t *value_64bit,
317
     libcerror_error_t **error )
318
0
{
319
0
  libfdatetime_internal_filetime_t *internal_filetime = NULL;
320
0
  static char *function                               = "libfdatetime_filetime_copy_to_64bit";
321
322
0
  if( filetime == NULL )
323
0
  {
324
0
    libcerror_error_set(
325
0
     error,
326
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
327
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
328
0
     "%s: invalid FILETIME.",
329
0
     function );
330
331
0
    return( -1 );
332
0
  }
333
0
  internal_filetime = (libfdatetime_internal_filetime_t *) filetime;
334
335
0
  if( value_64bit == NULL )
336
0
  {
337
0
    libcerror_error_set(
338
0
     error,
339
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
340
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
341
0
     "%s: invalid 64-bit value.",
342
0
     function );
343
344
0
    return( -1 );
345
0
  }
346
0
  *value_64bit   = internal_filetime->upper;
347
0
  *value_64bit <<= 32;
348
0
  *value_64bit  |= internal_filetime->lower;
349
350
0
  return( 1 );
351
0
}
352
353
/* Converts a FILETIME into date time values
354
 * Returns 1 if successful or -1 on error
355
 */
356
int libfdatetime_internal_filetime_copy_to_date_time_values(
357
     libfdatetime_internal_filetime_t *internal_filetime,
358
     libfdatetime_date_time_values_t *date_time_values,
359
     libcerror_error_t **error )
360
0
{
361
0
  static char *function    = "libfdatetime_internal_filetime_copy_to_date_time_values";
362
0
  uint64_t filetimestamp   = 0;
363
0
  uint32_t days_in_century = 0;
364
0
  uint16_t days_in_year    = 0;
365
0
  uint8_t days_in_month    = 0;
366
367
0
  if( internal_filetime == NULL )
368
0
  {
369
0
    libcerror_error_set(
370
0
     error,
371
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
372
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
373
0
     "%s: invalid FILETIME.",
374
0
     function );
375
376
0
    return( -1 );
377
0
  }
378
0
  if( date_time_values == NULL )
379
0
  {
380
0
    libcerror_error_set(
381
0
     error,
382
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
383
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
384
0
     "%s: invalid date time values.",
385
0
     function );
386
387
0
    return( -1 );
388
0
  }
389
  /* Combine the lower and upper filetime parts into a single filetime timestamp
390
   */
391
0
  filetimestamp = ( (uint64_t) ( internal_filetime->upper ) << 32 ) + internal_filetime->lower;
392
393
  /* The timestamp is in units of 100 nano seconds correct the value to seconds
394
   */
395
0
  date_time_values->nano_seconds = ( filetimestamp % 10 ) * 100;
396
0
  filetimestamp                 /= 10;
397
398
0
  date_time_values->micro_seconds = filetimestamp % 1000;
399
0
  filetimestamp                  /= 1000;
400
401
0
  date_time_values->milli_seconds = filetimestamp % 1000;
402
0
  filetimestamp                  /= 1000;
403
404
  /* There are 60 seconds in a minute correct the value to minutes
405
   */
406
0
  date_time_values->seconds = filetimestamp % 60;
407
0
  filetimestamp            /= 60;
408
409
  /* There are 60 minutes in an hour correct the value to hours
410
   */
411
0
  date_time_values->minutes = filetimestamp % 60;
412
0
  filetimestamp            /= 60;
413
414
  /* There are 24 hours in a day correct the value to days
415
   */
416
0
  date_time_values->hours = filetimestamp % 24;
417
0
  filetimestamp          /= 24;
418
419
  /* Add 1 day to compensate that Jan 1 1601 is represented as 0
420
   */
421
0
  filetimestamp += 1;
422
423
  /* Determine the number of years starting at '1 Jan 1601 00:00:00'
424
   * correct the value to days within the year
425
   */
426
0
  date_time_values->year = 1601;
427
428
0
  if( filetimestamp >= 36159 )
429
0
  {
430
0
    date_time_values->year = 1700;
431
432
0
    filetimestamp -= 36159;
433
0
  }
434
0
  while( filetimestamp > 0 )
435
0
  {
436
0
    if( ( date_time_values->year % 400 ) == 0 )
437
0
    {
438
0
      days_in_century = 36525;
439
0
    }
440
0
    else
441
0
    {
442
0
      days_in_century = 36524;
443
0
    }
444
0
    if( filetimestamp <= days_in_century )
445
0
    {
446
0
      break;
447
0
    }
448
0
    filetimestamp -= days_in_century;
449
450
0
    date_time_values->year += 100;
451
0
  }
452
0
  while( filetimestamp > 0 )
453
0
  {
454
    /* Check for a leap year
455
     * The year is ( ( dividable by 4 ) and ( not dividable by 100 ) ) or ( dividable by 400 )
456
     */
457
0
    if( ( ( ( date_time_values->year % 4 ) == 0 )
458
0
      &&  ( ( date_time_values->year % 100 ) != 0 ) )
459
0
     || ( ( date_time_values->year % 400 ) == 0 ) )
460
0
    {
461
0
      days_in_year = 366;
462
0
    }
463
0
    else
464
0
    {
465
0
      days_in_year = 365;
466
0
    }
467
0
    if( filetimestamp <= days_in_year )
468
0
    {
469
0
      break;
470
0
    }
471
0
    filetimestamp -= days_in_year;
472
473
0
    date_time_values->year += 1;
474
0
  }
475
0
  if( date_time_values->year > 9999 )
476
0
  {
477
0
    libcerror_error_set(
478
0
     error,
479
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
480
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
481
0
     "%s: invalid FILETIME - year value out of bounds.",
482
0
     function );
483
484
0
    return( -1 );
485
0
  }
486
  /* Determine the month correct the value to days within the month
487
   */
488
0
  date_time_values->month = 1;
489
490
0
  while( filetimestamp > 0 )
491
0
  {
492
    /* February (2)
493
     */
494
0
    if( date_time_values->month == 2 )
495
0
    {
496
0
      if( ( ( ( date_time_values->year % 4 ) == 0 )
497
0
        &&  ( ( date_time_values->year % 100 ) != 0 ) )
498
0
       || ( ( date_time_values->year % 400 ) == 0 ) )
499
0
      {
500
0
        days_in_month = 29;
501
0
      }
502
0
      else
503
0
      {
504
0
        days_in_month = 28;
505
0
      }
506
0
    }
507
    /* April (4), June (6), September (9), November (11)
508
     */
509
0
    else if( ( date_time_values->month == 4 )
510
0
          || ( date_time_values->month == 6 )
511
0
          || ( date_time_values->month == 9 )
512
0
          || ( date_time_values->month == 11 ) )
513
0
    {
514
0
      days_in_month = 30;
515
0
    }
516
    /* January (1), March (3), May (5), July (7), August (8), October (10), December (12)
517
     */
518
0
    else if( ( date_time_values->month == 1 )
519
0
          || ( date_time_values->month == 3 )
520
0
          || ( date_time_values->month == 5 )
521
0
          || ( date_time_values->month == 7 )
522
0
          || ( date_time_values->month == 8 )
523
0
          || ( date_time_values->month == 10 )
524
0
          || ( date_time_values->month == 12 ) )
525
0
    {
526
0
      days_in_month = 31;
527
0
    }
528
    /* This should never happen, but just in case
529
     */
530
0
    else
531
0
    {
532
0
      libcerror_error_set(
533
0
       error,
534
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
535
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
536
0
       "%s: unsupported month: %d.",
537
0
       function,
538
0
       date_time_values->month );
539
540
0
      return( -1 );
541
0
    }
542
0
    if( filetimestamp <= days_in_month )
543
0
    {
544
0
      break;
545
0
    }
546
0
    filetimestamp -= days_in_month;
547
548
0
    date_time_values->month += 1;
549
0
  }
550
  /* Determine the day
551
   */
552
0
  date_time_values->day = (uint8_t) filetimestamp;
553
554
0
  return( 1 );
555
0
}
556
557
/* Deterimes the size of the string for the FILETIME
558
 * The string size includes the end of string character
559
 * Returns 1 if successful or -1 on error
560
 */
561
int libfdatetime_filetime_get_string_size(
562
     libfdatetime_filetime_t *filetime,
563
     size_t *string_size,
564
     uint32_t string_format_flags,
565
     libcerror_error_t **error )
566
0
{
567
0
  libfdatetime_date_time_values_t date_time_values;
568
569
0
  static char *function = "libfdatetime_filetime_get_string_size";
570
0
  int result            = 0;
571
572
0
  if( filetime == NULL )
573
0
  {
574
0
    libcerror_error_set(
575
0
     error,
576
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
577
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
578
0
     "%s: invalid FILETIME.",
579
0
     function );
580
581
0
    return( -1 );
582
0
  }
583
0
  if( string_size == NULL )
584
0
  {
585
0
    libcerror_error_set(
586
0
     error,
587
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
588
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
589
0
     "%s: invalid string size.",
590
0
     function );
591
592
0
    return( -1 );
593
0
  }
594
0
  result = libfdatetime_internal_filetime_copy_to_date_time_values(
595
0
            (libfdatetime_internal_filetime_t *) filetime,
596
0
            &date_time_values,
597
0
            error );
598
599
0
  if( result != 1 )
600
0
  {
601
#if defined( HAVE_DEBUG_OUTPUT )
602
    libcerror_error_set(
603
     error,
604
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
605
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
606
     "%s: unable to set date time values.",
607
     function );
608
609
/* TODO debug print error */
610
611
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
612
613
0
    if( ( error != NULL )
614
0
     && ( *error != NULL ) )
615
0
    {
616
0
      libcerror_error_free(
617
0
       error );
618
0
    }
619
0
  }
620
0
  else
621
0
  {
622
0
    result = libfdatetime_date_time_values_get_string_size(
623
0
              &date_time_values,
624
0
              string_size,
625
0
              string_format_flags,
626
0
              error );
627
628
0
    if( result == -1 )
629
0
    {
630
0
      libcerror_error_set(
631
0
       error,
632
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
633
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
634
0
       "%s: unable to get string size.",
635
0
       function );
636
637
0
      return( -1 );
638
0
    }
639
0
  }
640
0
  if( result != 1 )
641
0
  {
642
    /* Make sure the string can hold the hexadecimal representation of the filetime
643
     */
644
0
    *string_size = 24;
645
0
  }
646
0
  return( 1 );
647
0
}
648
649
/* Converts the FILETIME into an UTF-8 string in hexadecimal representation
650
 * The string size should include the end of string character
651
 * Returns 1 if successful or -1 on error
652
 */
653
int libfdatetime_internal_filetime_copy_to_utf8_string_in_hexadecimal(
654
     libfdatetime_internal_filetime_t *internal_filetime,
655
     uint8_t *utf8_string,
656
     size_t utf8_string_size,
657
     size_t *utf8_string_index,
658
     libcerror_error_t **error )
659
0
{
660
0
  static char *function = "libfdatetime_internal_filetime_copy_to_utf8_string_in_hexadecimal";
661
0
  size_t string_index   = 0;
662
0
  uint8_t byte_value    = 0;
663
0
  int8_t byte_shift     = 0;
664
665
0
  if( internal_filetime == NULL )
666
0
  {
667
0
    libcerror_error_set(
668
0
     error,
669
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
670
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
671
0
     "%s: invalid FILETIME.",
672
0
     function );
673
674
0
    return( -1 );
675
0
  }
676
0
  if( utf8_string == NULL )
677
0
  {
678
0
    libcerror_error_set(
679
0
     error,
680
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
681
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
682
0
     "%s: invalid UTF-8 string.",
683
0
     function );
684
685
0
    return( -1 );
686
0
  }
687
0
  if( utf8_string_size > (size_t) SSIZE_MAX )
688
0
  {
689
0
    libcerror_error_set(
690
0
     error,
691
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
692
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
693
0
     "%s: invalid UTF-8 string size value exceeds maximum.",
694
0
     function );
695
696
0
    return( -1 );
697
0
  }
698
0
  if( utf8_string_index == NULL )
699
0
  {
700
0
    libcerror_error_set(
701
0
     error,
702
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
703
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
704
0
     "%s: invalid UTF-8 string index.",
705
0
     function );
706
707
0
    return( -1 );
708
0
  }
709
0
  if( ( utf8_string_size < 24 )
710
0
   || ( *utf8_string_index > ( utf8_string_size - 24 ) ) )
711
0
  {
712
0
    libcerror_error_set(
713
0
     error,
714
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
715
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
716
0
     "%s: UTF-8 string is too small.",
717
0
     function );
718
719
0
    return( -1 );
720
0
  }
721
0
  string_index = *utf8_string_index;
722
723
0
  utf8_string[ string_index++ ] = (uint8_t) '(';
724
0
  utf8_string[ string_index++ ] = (uint8_t) '0';
725
0
  utf8_string[ string_index++ ] = (uint8_t) 'x';
726
727
0
  byte_shift = 28;
728
729
0
  do
730
0
  {
731
0
    byte_value = ( internal_filetime->upper >> byte_shift ) & 0x0f;
732
733
0
    if( byte_value <= 9 )
734
0
    {
735
0
      utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
736
0
    }
737
0
    else
738
0
    {
739
0
      utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
740
0
    }
741
0
    byte_shift -= 4;
742
0
  }
743
0
  while( byte_shift >= 0 );
744
745
0
  utf8_string[ string_index++ ] = (uint8_t) ' ';
746
0
  utf8_string[ string_index++ ] = (uint8_t) '0';
747
0
  utf8_string[ string_index++ ] = (uint8_t) 'x';
748
749
0
  byte_shift = 28;
750
751
0
  do
752
0
  {
753
0
    byte_value = ( internal_filetime->lower >> byte_shift ) & 0x0f;
754
755
0
    if( byte_value <= 9 )
756
0
    {
757
0
      utf8_string[ string_index++ ] = (uint8_t) '0' + byte_value;
758
0
    }
759
0
    else
760
0
    {
761
0
      utf8_string[ string_index++ ] = (uint8_t) 'a' + byte_value - 10;
762
0
    }
763
0
    byte_shift -= 4;
764
0
  }
765
0
  while( byte_shift >= 0 );
766
767
0
  utf8_string[ string_index++ ] = (uint8_t) ')';
768
769
0
  utf8_string[ string_index++ ] = 0;
770
771
0
  *utf8_string_index = string_index;
772
773
0
  return( 1 );
774
0
}
775
776
/* Converts the FILETIME into an UTF-8 string
777
 * The string size should include the end of string character
778
 * Returns 1 if successful or -1 on error
779
 */
780
int libfdatetime_filetime_copy_to_utf8_string(
781
     libfdatetime_filetime_t *filetime,
782
     uint8_t *utf8_string,
783
     size_t utf8_string_size,
784
     uint32_t string_format_flags,
785
     libcerror_error_t **error )
786
0
{
787
0
  static char *function    = "libfdatetime_filetime_copy_to_utf8_string";
788
0
  size_t utf8_string_index = 0;
789
790
0
  if( libfdatetime_filetime_copy_to_utf8_string_with_index(
791
0
       filetime,
792
0
       utf8_string,
793
0
       utf8_string_size,
794
0
       &utf8_string_index,
795
0
       string_format_flags,
796
0
       error ) != 1 )
797
0
  {
798
0
    libcerror_error_set(
799
0
     error,
800
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
801
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
802
0
     "%s: unable to copy FILETIME to UTF-8 string.",
803
0
     function );
804
805
0
    return( -1 );
806
0
  }
807
0
  return( 1 );
808
0
}
809
810
/* Converts the FILETIME into an UTF-8 string
811
 * The string size should include the end of string character
812
 * Returns 1 if successful or -1 on error
813
 */
814
int libfdatetime_filetime_copy_to_utf8_string_with_index(
815
     libfdatetime_filetime_t *filetime,
816
     uint8_t *utf8_string,
817
     size_t utf8_string_size,
818
     size_t *utf8_string_index,
819
     uint32_t string_format_flags,
820
     libcerror_error_t **error )
821
0
{
822
0
  libfdatetime_date_time_values_t date_time_values;
823
824
0
  libfdatetime_internal_filetime_t *internal_filetime = NULL;
825
0
  static char *function                               = "libfdatetime_filetime_copy_to_utf8_string_with_index";
826
0
  int result                                          = 0;
827
828
0
  if( filetime == NULL )
829
0
  {
830
0
    libcerror_error_set(
831
0
     error,
832
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
833
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
834
0
     "%s: invalid FILETIME.",
835
0
     function );
836
837
0
    return( -1 );
838
0
  }
839
0
  internal_filetime = (libfdatetime_internal_filetime_t *) filetime;
840
841
0
  result = libfdatetime_internal_filetime_copy_to_date_time_values(
842
0
            internal_filetime,
843
0
            &date_time_values,
844
0
            error );
845
846
0
  if( result != 1 )
847
0
  {
848
#if defined( HAVE_DEBUG_OUTPUT )
849
    libcerror_error_set(
850
     error,
851
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
852
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
853
     "%s: unable to set date time values.",
854
     function );
855
856
/* TODO debug print error */
857
858
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
859
860
0
    if( ( error != NULL )
861
0
     && ( *error != NULL ) )
862
0
    {
863
0
      libcerror_error_free(
864
0
       error );
865
0
    }
866
0
  }
867
0
  else
868
0
  {
869
0
    result = libfdatetime_date_time_values_copy_to_utf8_string_with_index(
870
0
              &date_time_values,
871
0
              utf8_string,
872
0
              utf8_string_size,
873
0
              utf8_string_index,
874
0
              string_format_flags,
875
0
              error );
876
877
0
    if( result == -1 )
878
0
    {
879
0
      libcerror_error_set(
880
0
       error,
881
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
882
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
883
0
       "%s: unable to copy date time values to UTF-8 string.",
884
0
       function );
885
886
0
      return( -1 );
887
0
    }
888
0
  }
889
0
  if( result != 1 )
890
0
  {
891
0
    result = libfdatetime_internal_filetime_copy_to_utf8_string_in_hexadecimal(
892
0
              internal_filetime,
893
0
              utf8_string,
894
0
              utf8_string_size,
895
0
              utf8_string_index,
896
0
              error );
897
898
0
    if( result == -1 )
899
0
    {
900
0
      libcerror_error_set(
901
0
       error,
902
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
903
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
904
0
       "%s: unable to FILETIME to hexadecimal UTF-8 string.",
905
0
       function );
906
907
0
      return( -1 );
908
0
    }
909
0
  }
910
0
  return( 1 );
911
0
}
912
913
/* Converts the FILETIME into an UTF-16 string in hexadecimal representation
914
 * The string size should include the end of string character
915
 * Returns 1 if successful or -1 on error
916
 */
917
int libfdatetime_internal_filetime_copy_to_utf16_string_in_hexadecimal(
918
     libfdatetime_internal_filetime_t *internal_filetime,
919
     uint16_t *utf16_string,
920
     size_t utf16_string_size,
921
     size_t *utf16_string_index,
922
     libcerror_error_t **error )
923
0
{
924
0
  static char *function = "libfdatetime_internal_filetime_copy_to_utf16_string_in_hexadecimal";
925
0
  size_t string_index   = 0;
926
0
  uint8_t byte_value    = 0;
927
0
  int8_t byte_shift     = 0;
928
929
0
  if( internal_filetime == NULL )
930
0
  {
931
0
    libcerror_error_set(
932
0
     error,
933
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
934
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
935
0
     "%s: invalid FILETIME.",
936
0
     function );
937
938
0
    return( -1 );
939
0
  }
940
0
  if( utf16_string == NULL )
941
0
  {
942
0
    libcerror_error_set(
943
0
     error,
944
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
945
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
946
0
     "%s: invalid UTF-16 string.",
947
0
     function );
948
949
0
    return( -1 );
950
0
  }
951
0
  if( utf16_string_size > (size_t) SSIZE_MAX )
952
0
  {
953
0
    libcerror_error_set(
954
0
     error,
955
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
956
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
957
0
     "%s: invalid UTF-16 string size value exceeds maximum.",
958
0
     function );
959
960
0
    return( -1 );
961
0
  }
962
0
  if( utf16_string_index == NULL )
963
0
  {
964
0
    libcerror_error_set(
965
0
     error,
966
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
967
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
968
0
     "%s: invalid UTF-16 string index.",
969
0
     function );
970
971
0
    return( -1 );
972
0
  }
973
0
  if( ( utf16_string_size < 24 )
974
0
   || ( *utf16_string_index > ( utf16_string_size - 24 ) ) )
975
0
  {
976
0
    libcerror_error_set(
977
0
     error,
978
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
979
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
980
0
     "%s: UTF-16 string is too small.",
981
0
     function );
982
983
0
    return( -1 );
984
0
  }
985
0
  string_index = *utf16_string_index;
986
987
0
  utf16_string[ string_index++ ] = (uint16_t) '(';
988
0
  utf16_string[ string_index++ ] = (uint16_t) '0';
989
0
  utf16_string[ string_index++ ] = (uint16_t) 'x';
990
991
0
  byte_shift = 28;
992
993
0
  do
994
0
  {
995
0
    byte_value = ( internal_filetime->upper >> byte_shift ) & 0x0f;
996
997
0
    if( byte_value <= 9 )
998
0
    {
999
0
      utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
1000
0
    }
1001
0
    else
1002
0
    {
1003
0
      utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
1004
0
    }
1005
0
    byte_shift -= 4;
1006
0
  }
1007
0
  while( byte_shift >= 0 );
1008
1009
0
  utf16_string[ string_index++ ] = (uint16_t) ' ';
1010
0
  utf16_string[ string_index++ ] = (uint16_t) '0';
1011
0
  utf16_string[ string_index++ ] = (uint16_t) 'x';
1012
1013
0
  byte_shift = 28;
1014
1015
0
  do
1016
0
  {
1017
0
    byte_value = ( internal_filetime->lower >> byte_shift ) & 0x0f;
1018
1019
0
    if( byte_value <= 9 )
1020
0
    {
1021
0
      utf16_string[ string_index++ ] = (uint16_t) '0' + byte_value;
1022
0
    }
1023
0
    else
1024
0
    {
1025
0
      utf16_string[ string_index++ ] = (uint16_t) 'a' + byte_value - 10;
1026
0
    }
1027
0
    byte_shift -= 4;
1028
0
  }
1029
0
  while( byte_shift >= 0 );
1030
1031
0
  utf16_string[ string_index++ ] = (uint16_t) ')';
1032
1033
0
  utf16_string[ string_index++ ] = 0;
1034
1035
0
  *utf16_string_index = string_index;
1036
1037
0
  return( 1 );
1038
0
}
1039
1040
/* Converts the FILETIME into an UTF-16 string
1041
 * The string size should include the end of string character
1042
 * Returns 1 if successful or -1 on error
1043
 */
1044
int libfdatetime_filetime_copy_to_utf16_string(
1045
     libfdatetime_filetime_t *filetime,
1046
     uint16_t *utf16_string,
1047
     size_t utf16_string_size,
1048
     uint32_t string_format_flags,
1049
     libcerror_error_t **error )
1050
0
{
1051
0
  static char *function     = "libfdatetime_filetime_copy_to_utf16_string";
1052
0
  size_t utf16_string_index = 0;
1053
1054
0
  if( libfdatetime_filetime_copy_to_utf16_string_with_index(
1055
0
       filetime,
1056
0
       utf16_string,
1057
0
       utf16_string_size,
1058
0
       &utf16_string_index,
1059
0
       string_format_flags,
1060
0
       error ) != 1 )
1061
0
  {
1062
0
    libcerror_error_set(
1063
0
     error,
1064
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1065
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1066
0
     "%s: unable to copy FILETIME to UTF-16 string.",
1067
0
     function );
1068
1069
0
    return( -1 );
1070
0
  }
1071
0
  return( 1 );
1072
0
}
1073
1074
/* Converts the FILETIME into an UTF-16 string
1075
 * The string size should include the end of string character
1076
 * Returns 1 if successful or -1 on error
1077
 */
1078
int libfdatetime_filetime_copy_to_utf16_string_with_index(
1079
     libfdatetime_filetime_t *filetime,
1080
     uint16_t *utf16_string,
1081
     size_t utf16_string_size,
1082
     size_t *utf16_string_index,
1083
     uint32_t string_format_flags,
1084
     libcerror_error_t **error )
1085
0
{
1086
0
  libfdatetime_date_time_values_t date_time_values;
1087
1088
0
  libfdatetime_internal_filetime_t *internal_filetime = NULL;
1089
0
  static char *function                               = "libfdatetime_filetime_copy_to_utf16_string_with_index";
1090
0
  int result                                          = 0;
1091
1092
0
  if( filetime == NULL )
1093
0
  {
1094
0
    libcerror_error_set(
1095
0
     error,
1096
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1097
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1098
0
     "%s: invalid FILETIME.",
1099
0
     function );
1100
1101
0
    return( -1 );
1102
0
  }
1103
0
  internal_filetime = (libfdatetime_internal_filetime_t *) filetime;
1104
1105
0
  result = libfdatetime_internal_filetime_copy_to_date_time_values(
1106
0
            internal_filetime,
1107
0
            &date_time_values,
1108
0
            error );
1109
1110
0
  if( result != 1 )
1111
0
  {
1112
#if defined( HAVE_DEBUG_OUTPUT )
1113
    libcerror_error_set(
1114
     error,
1115
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1116
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1117
     "%s: unable to set date time values.",
1118
     function );
1119
1120
/* TODO debug print error */
1121
1122
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1123
1124
0
    if( ( error != NULL )
1125
0
     && ( *error != NULL ) )
1126
0
    {
1127
0
      libcerror_error_free(
1128
0
       error );
1129
0
    }
1130
0
  }
1131
0
  else
1132
0
  {
1133
0
    result = libfdatetime_date_time_values_copy_to_utf16_string_with_index(
1134
0
              &date_time_values,
1135
0
              utf16_string,
1136
0
              utf16_string_size,
1137
0
              utf16_string_index,
1138
0
              string_format_flags,
1139
0
              error );
1140
1141
0
    if( result == -1 )
1142
0
    {
1143
0
      libcerror_error_set(
1144
0
       error,
1145
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1146
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1147
0
       "%s: unable to set UTF-16 string.",
1148
0
       function );
1149
1150
0
      return( -1 );
1151
0
    }
1152
0
  }
1153
0
  if( result != 1 )
1154
0
  {
1155
0
    if( utf16_string == NULL )
1156
0
    {
1157
0
      libcerror_error_set(
1158
0
       error,
1159
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1160
0
       LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1161
0
       "%s: invalid UTF-16 string.",
1162
0
       function );
1163
1164
0
      return( -1 );
1165
0
    }
1166
0
    if( utf16_string_size > (size_t) SSIZE_MAX )
1167
0
    {
1168
0
      libcerror_error_set(
1169
0
       error,
1170
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1171
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1172
0
       "%s: unable to copy date time values to UTF-16 string.",
1173
0
       function );
1174
1175
0
      return( -1 );
1176
0
    }
1177
0
  }
1178
0
  if( result != 1 )
1179
0
  {
1180
0
    result = libfdatetime_internal_filetime_copy_to_utf16_string_in_hexadecimal(
1181
0
              internal_filetime,
1182
0
              utf16_string,
1183
0
              utf16_string_size,
1184
0
              utf16_string_index,
1185
0
              error );
1186
1187
0
    if( result == -1 )
1188
0
    {
1189
0
      libcerror_error_set(
1190
0
       error,
1191
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1192
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1193
0
       "%s: unable to FILETIME to hexadecimal UTF-16 string.",
1194
0
       function );
1195
1196
0
      return( -1 );
1197
0
    }
1198
0
  }
1199
0
  return( 1 );
1200
0
}
1201
1202
/* Converts the FILETIME into an UTF-32 string in hexadecimal representation
1203
 * The string size should include the end of string character
1204
 * Returns 1 if successful or -1 on error
1205
 */
1206
int libfdatetime_internal_filetime_copy_to_utf32_string_in_hexadecimal(
1207
     libfdatetime_internal_filetime_t *internal_filetime,
1208
     uint32_t *utf32_string,
1209
     size_t utf32_string_size,
1210
     size_t *utf32_string_index,
1211
     libcerror_error_t **error )
1212
0
{
1213
0
  static char *function = "libfdatetime_internal_filetime_copy_to_utf32_string_in_hexadecimal";
1214
0
  size_t string_index   = 0;
1215
0
  uint8_t byte_value    = 0;
1216
0
  int8_t byte_shift     = 0;
1217
1218
0
  if( internal_filetime == NULL )
1219
0
  {
1220
0
    libcerror_error_set(
1221
0
     error,
1222
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1223
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1224
0
     "%s: invalid FILETIME.",
1225
0
     function );
1226
1227
0
    return( -1 );
1228
0
  }
1229
0
  if( utf32_string == NULL )
1230
0
  {
1231
0
    libcerror_error_set(
1232
0
     error,
1233
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1234
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1235
0
     "%s: invalid UTF-32 string.",
1236
0
     function );
1237
1238
0
    return( -1 );
1239
0
  }
1240
0
  if( utf32_string_size > (size_t) SSIZE_MAX )
1241
0
  {
1242
0
    libcerror_error_set(
1243
0
     error,
1244
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1245
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1246
0
     "%s: invalid UTF-32 string size value exceeds maximum.",
1247
0
     function );
1248
1249
0
    return( -1 );
1250
0
  }
1251
0
  if( utf32_string_index == NULL )
1252
0
  {
1253
0
    libcerror_error_set(
1254
0
     error,
1255
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1256
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1257
0
     "%s: invalid UTF-32 string index.",
1258
0
     function );
1259
1260
0
    return( -1 );
1261
0
  }
1262
0
  if( ( utf32_string_size < 24 )
1263
0
   || ( *utf32_string_index > ( utf32_string_size - 24 ) ) )
1264
0
  {
1265
0
    libcerror_error_set(
1266
0
     error,
1267
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1268
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1269
0
     "%s: UTF-32 string is too small.",
1270
0
     function );
1271
1272
0
    return( -1 );
1273
0
  }
1274
0
  string_index = *utf32_string_index;
1275
1276
0
  utf32_string[ string_index++ ] = (uint32_t) '(';
1277
0
  utf32_string[ string_index++ ] = (uint32_t) '0';
1278
0
  utf32_string[ string_index++ ] = (uint32_t) 'x';
1279
1280
0
  byte_shift = 28;
1281
1282
0
  do
1283
0
  {
1284
0
    byte_value = ( internal_filetime->upper >> byte_shift ) & 0x0f;
1285
1286
0
    if( byte_value <= 9 )
1287
0
    {
1288
0
      utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
1289
0
    }
1290
0
    else
1291
0
    {
1292
0
      utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
1293
0
    }
1294
0
    byte_shift -= 4;
1295
0
  }
1296
0
  while( byte_shift >= 0 );
1297
1298
0
  utf32_string[ string_index++ ] = (uint32_t) ' ';
1299
0
  utf32_string[ string_index++ ] = (uint32_t) '0';
1300
0
  utf32_string[ string_index++ ] = (uint32_t) 'x';
1301
1302
0
  byte_shift = 28;
1303
1304
0
  do
1305
0
  {
1306
0
    byte_value = ( internal_filetime->lower >> byte_shift ) & 0x0f;
1307
1308
0
    if( byte_value <= 9 )
1309
0
    {
1310
0
      utf32_string[ string_index++ ] = (uint32_t) '0' + byte_value;
1311
0
    }
1312
0
    else
1313
0
    {
1314
0
      utf32_string[ string_index++ ] = (uint32_t) 'a' + byte_value - 10;
1315
0
    }
1316
0
    byte_shift -= 4;
1317
0
  }
1318
0
  while( byte_shift >= 0 );
1319
1320
0
  utf32_string[ string_index++ ] = (uint32_t) ')';
1321
1322
0
  utf32_string[ string_index++ ] = 0;
1323
1324
0
  *utf32_string_index = string_index;
1325
1326
0
  return( 1 );
1327
0
}
1328
1329
/* Converts the FILETIME into an UTF-32 string
1330
 * The string size should include the end of string character
1331
 * Returns 1 if successful or -1 on error
1332
 */
1333
int libfdatetime_filetime_copy_to_utf32_string(
1334
     libfdatetime_filetime_t *filetime,
1335
     uint32_t *utf32_string,
1336
     size_t utf32_string_size,
1337
     uint32_t string_format_flags,
1338
     libcerror_error_t **error )
1339
0
{
1340
0
  static char *function     = "libfdatetime_filetime_copy_to_utf32_string";
1341
0
  size_t utf32_string_index = 0;
1342
1343
0
  if( libfdatetime_filetime_copy_to_utf32_string_with_index(
1344
0
       filetime,
1345
0
       utf32_string,
1346
0
       utf32_string_size,
1347
0
       &utf32_string_index,
1348
0
       string_format_flags,
1349
0
       error ) != 1 )
1350
0
  {
1351
0
    libcerror_error_set(
1352
0
     error,
1353
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1354
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
1355
0
     "%s: unable to copy FILETIME to UTF-32 string.",
1356
0
     function );
1357
1358
0
    return( -1 );
1359
0
  }
1360
0
  return( 1 );
1361
0
}
1362
1363
/* Converts the FILETIME into an UTF-32 string
1364
 * The string size should include the end of string character
1365
 * Returns 1 if successful or -1 on error
1366
 */
1367
int libfdatetime_filetime_copy_to_utf32_string_with_index(
1368
     libfdatetime_filetime_t *filetime,
1369
     uint32_t *utf32_string,
1370
     size_t utf32_string_size,
1371
     size_t *utf32_string_index,
1372
     uint32_t string_format_flags,
1373
     libcerror_error_t **error )
1374
0
{
1375
0
  libfdatetime_date_time_values_t date_time_values;
1376
1377
0
  libfdatetime_internal_filetime_t *internal_filetime = NULL;
1378
0
  static char *function                               = "libfdatetime_filetime_copy_to_utf32_string_with_index";
1379
0
  int result                                          = 0;
1380
1381
0
  if( filetime == NULL )
1382
0
  {
1383
0
    libcerror_error_set(
1384
0
     error,
1385
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1386
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1387
0
     "%s: invalid FILETIME.",
1388
0
     function );
1389
1390
0
    return( -1 );
1391
0
  }
1392
0
  internal_filetime = (libfdatetime_internal_filetime_t *) filetime;
1393
1394
0
  result = libfdatetime_internal_filetime_copy_to_date_time_values(
1395
0
            internal_filetime,
1396
0
            &date_time_values,
1397
0
            error );
1398
1399
0
  if( result != 1 )
1400
0
  {
1401
#if defined( HAVE_DEBUG_OUTPUT )
1402
    libcerror_error_set(
1403
     error,
1404
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1405
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1406
     "%s: unable to set date time values.",
1407
     function );
1408
1409
/* TODO debug print error */
1410
1411
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1412
1413
0
    if( ( error != NULL )
1414
0
     && ( *error != NULL ) )
1415
0
    {
1416
0
      libcerror_error_free(
1417
0
       error );
1418
0
    }
1419
0
  }
1420
0
  else
1421
0
  {
1422
0
    result = libfdatetime_date_time_values_copy_to_utf32_string_with_index(
1423
0
              &date_time_values,
1424
0
              utf32_string,
1425
0
              utf32_string_size,
1426
0
              utf32_string_index,
1427
0
              string_format_flags,
1428
0
              error );
1429
1430
0
    if( result == -1 )
1431
0
    {
1432
0
      libcerror_error_set(
1433
0
       error,
1434
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1435
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1436
0
       "%s: unable to copy date time values to UTF-32 string.",
1437
0
       function );
1438
1439
0
      return( -1 );
1440
0
    }
1441
0
  }
1442
0
  if( result != 1 )
1443
0
  {
1444
0
    result = libfdatetime_internal_filetime_copy_to_utf32_string_in_hexadecimal(
1445
0
              internal_filetime,
1446
0
              utf32_string,
1447
0
              utf32_string_size,
1448
0
              utf32_string_index,
1449
0
              error );
1450
1451
0
    if( result == -1 )
1452
0
    {
1453
0
      libcerror_error_set(
1454
0
       error,
1455
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1456
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1457
0
       "%s: unable to FILETIME to hexadecimal UTF-32 string.",
1458
0
       function );
1459
1460
0
      return( -1 );
1461
0
    }
1462
0
  }
1463
0
  return( 1 );
1464
0
}
1465