Coverage Report

Created: 2026-03-05 07:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libfsntfs/libfsntfs/libfsntfs_file_name_values.c
Line
Count
Source
1
/*
2
 * File name attribute ($FILE_NAME) values functions
3
 *
4
 * Copyright (C) 2010-2026, 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 <narrow_string.h>
26
#include <system_string.h>
27
#include <types.h>
28
#include <wide_string.h>
29
30
#include "libfsntfs_debug.h"
31
#include "libfsntfs_definitions.h"
32
#include "libfsntfs_file_name_values.h"
33
#include "libfsntfs_libcdata.h"
34
#include "libfsntfs_libcerror.h"
35
#include "libfsntfs_libcnotify.h"
36
#include "libfsntfs_libfdatetime.h"
37
#include "libfsntfs_libuna.h"
38
#include "libfsntfs_mft_attribute.h"
39
#include "libfsntfs_name.h"
40
41
#include "fsntfs_file_name.h"
42
43
/* Creates file name values
44
 * Make sure the value file_name_values is referencing, is set to NULL
45
 * Returns 1 if successful or -1 on error
46
 */
47
int libfsntfs_file_name_values_initialize(
48
     libfsntfs_file_name_values_t **file_name_values,
49
     libcerror_error_t **error )
50
6.46k
{
51
6.46k
  static char *function = "libfsntfs_file_name_values_initialize";
52
53
6.46k
  if( file_name_values == NULL )
54
0
  {
55
0
    libcerror_error_set(
56
0
     error,
57
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
58
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
59
0
     "%s: invalid file name values.",
60
0
     function );
61
62
0
    return( -1 );
63
0
  }
64
6.46k
  if( *file_name_values != NULL )
65
0
  {
66
0
    libcerror_error_set(
67
0
     error,
68
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
69
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
70
0
     "%s: invalid file name values value already set.",
71
0
     function );
72
73
0
    return( -1 );
74
0
  }
75
6.46k
  *file_name_values = memory_allocate_structure(
76
6.46k
                       libfsntfs_file_name_values_t );
77
78
6.46k
  if( *file_name_values == NULL )
79
0
  {
80
0
    libcerror_error_set(
81
0
     error,
82
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
83
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
84
0
     "%s: unable to create file name values.",
85
0
     function );
86
87
0
    goto on_error;
88
0
  }
89
6.46k
  if( memory_set(
90
6.46k
       *file_name_values,
91
6.46k
       0,
92
6.46k
       sizeof( libfsntfs_file_name_values_t ) ) == NULL )
93
0
  {
94
0
    libcerror_error_set(
95
0
     error,
96
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
97
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
98
0
     "%s: unable to clear file name values.",
99
0
     function );
100
101
0
    goto on_error;
102
0
  }
103
6.46k
  return( 1 );
104
105
0
on_error:
106
0
  if( *file_name_values != NULL )
107
0
  {
108
0
    memory_free(
109
0
     *file_name_values );
110
111
0
    *file_name_values = NULL;
112
0
  }
113
0
  return( -1 );
114
6.46k
}
115
116
/* Frees file name values
117
 * Returns 1 if successful or -1 on error
118
 */
119
int libfsntfs_file_name_values_free(
120
     libfsntfs_file_name_values_t **file_name_values,
121
     libcerror_error_t **error )
122
6.49k
{
123
6.49k
  static char *function = "libfsntfs_file_name_values_free";
124
125
6.49k
  if( file_name_values == NULL )
126
0
  {
127
0
    libcerror_error_set(
128
0
     error,
129
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
130
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
131
0
     "%s: invalid file name values.",
132
0
     function );
133
134
0
    return( -1 );
135
0
  }
136
6.49k
  if( *file_name_values != NULL )
137
6.49k
  {
138
6.49k
    if( ( *file_name_values )->name != NULL )
139
6.42k
    {
140
6.42k
      memory_free(
141
6.42k
       ( *file_name_values )->name );
142
6.42k
    }
143
6.49k
    memory_free(
144
6.49k
     *file_name_values );
145
146
6.49k
    *file_name_values = NULL;
147
6.49k
  }
148
6.49k
  return( 1 );
149
6.49k
}
150
151
/* Clones file name values
152
 * Returns 1 if successful or -1 on error
153
 */
154
int libfsntfs_file_name_values_clone(
155
     libfsntfs_file_name_values_t **destination_file_name_values,
156
     libfsntfs_file_name_values_t *source_file_name_values,
157
     libcerror_error_t **error )
158
67
{
159
67
  static char *function = "libfsntfs_file_name_values_clone";
160
161
67
  if( destination_file_name_values == NULL )
162
0
  {
163
0
    libcerror_error_set(
164
0
     error,
165
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
166
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
167
0
     "%s: invalid file name values.",
168
0
     function );
169
170
0
    return( -1 );
171
0
  }
172
67
  if( *destination_file_name_values != NULL )
173
0
  {
174
0
    libcerror_error_set(
175
0
     error,
176
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
177
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
178
0
     "%s: invalid destination file name values value already set.",
179
0
     function );
180
181
0
    return( -1 );
182
0
  }
183
67
  if( source_file_name_values == NULL )
184
32
  {
185
32
    *destination_file_name_values = source_file_name_values;
186
187
32
    return( 1 );
188
32
  }
189
35
  *destination_file_name_values = memory_allocate_structure(
190
35
                                   libfsntfs_file_name_values_t );
191
192
35
  if( *destination_file_name_values == NULL )
193
0
  {
194
0
    libcerror_error_set(
195
0
     error,
196
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
197
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
198
0
     "%s: unable to create destination file name values.",
199
0
     function );
200
201
0
    goto on_error;
202
0
  }
203
35
  if( memory_copy(
204
35
       *destination_file_name_values,
205
35
       source_file_name_values,
206
35
       sizeof( libfsntfs_file_name_values_t ) ) == NULL )
207
0
  {
208
0
    libcerror_error_set(
209
0
     error,
210
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
211
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
212
0
     "%s: unable to copy source file name values to destination.",
213
0
     function );
214
215
0
    goto on_error;
216
0
  }
217
35
  ( *destination_file_name_values )->name      = NULL;
218
35
  ( *destination_file_name_values )->name_size = 0;
219
220
35
  if( libfsntfs_file_name_values_set_name(
221
35
       *destination_file_name_values,
222
35
       source_file_name_values->name,
223
35
       source_file_name_values->name_size,
224
35
       error ) != 1 )
225
0
  {
226
0
    libcerror_error_set(
227
0
     error,
228
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
229
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
230
0
     "%s: unable to set destination name.",
231
0
     function );
232
233
0
    goto on_error;
234
0
  }
235
35
  return( 1 );
236
237
0
on_error:
238
0
  if( *destination_file_name_values != NULL )
239
0
  {
240
0
    memory_free(
241
0
     *destination_file_name_values );
242
243
0
    *destination_file_name_values = NULL;
244
0
  }
245
0
  return( -1 );
246
35
}
247
248
/* Sets the name
249
 * The size should include the end of string character
250
 * Returns 1 if successful or -1 on error
251
 */
252
int libfsntfs_file_name_values_set_name(
253
     libfsntfs_file_name_values_t *file_name_values,
254
     const uint8_t *utf16_stream,
255
     size_t utf16_stream_size,
256
     libcerror_error_t **error )
257
6.42k
{
258
6.42k
  static char *function = "libfsntfs_file_name_values_set_name";
259
260
6.42k
  if( file_name_values == NULL )
261
0
  {
262
0
    libcerror_error_set(
263
0
     error,
264
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
265
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
266
0
     "%s: invalid file name values.",
267
0
     function );
268
269
0
    return( -1 );
270
0
  }
271
6.42k
  if( file_name_values->name != NULL )
272
0
  {
273
0
    libcerror_error_set(
274
0
     error,
275
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
276
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
277
0
     "%s: invalid file name values - name value already set.",
278
0
     function );
279
280
0
    return( -1 );
281
0
  }
282
6.42k
  if( utf16_stream == NULL )
283
0
  {
284
0
    libcerror_error_set(
285
0
     error,
286
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
287
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
288
0
     "%s: invalid UTF-16 stream.",
289
0
     function );
290
291
0
    return( -1 );
292
0
  }
293
6.42k
  if( ( utf16_stream_size == 0 )
294
6.42k
   || ( utf16_stream_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
295
0
  {
296
0
    libcerror_error_set(
297
0
     error,
298
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
299
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
300
0
     "%s: invalid UTF-16 stream size value out of bounds.",
301
0
     function );
302
303
0
    return( -1 );
304
0
  }
305
6.42k
  file_name_values->name = (uint8_t *) memory_allocate(
306
6.42k
                                        sizeof( uint8_t ) * (size_t) utf16_stream_size );
307
308
6.42k
  if( file_name_values->name == NULL )
309
0
  {
310
0
    libcerror_error_set(
311
0
     error,
312
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
313
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
314
0
     "%s: unable to create name.",
315
0
     function );
316
317
0
    goto on_error;
318
0
  }
319
6.42k
  if( memory_copy(
320
6.42k
       file_name_values->name,
321
6.42k
       utf16_stream,
322
6.42k
       utf16_stream_size ) == NULL )
323
0
  {
324
0
    libcerror_error_set(
325
0
     error,
326
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
327
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
328
0
     "%s: unable to copy name.",
329
0
     function );
330
331
0
    goto on_error;
332
0
  }
333
6.42k
  file_name_values->name_size = utf16_stream_size;
334
335
6.42k
  return( 1 );
336
337
0
on_error:
338
0
  if( file_name_values->name != NULL )
339
0
  {
340
0
    memory_free(
341
0
     file_name_values->name );
342
343
0
    file_name_values->name = NULL;
344
0
  }
345
0
  file_name_values->name_size = 0;
346
347
0
  return( -1 );
348
6.42k
}
349
350
/* Reads the file name values
351
 * Returns 1 if successful or -1 on error
352
 */
353
int libfsntfs_file_name_values_read_data(
354
     libfsntfs_file_name_values_t *file_name_values,
355
     const uint8_t *data,
356
     size_t data_size,
357
     libcerror_error_t **error )
358
6.45k
{
359
6.45k
  static char *function = "libfsntfs_file_name_values_read_data";
360
6.45k
  size_t data_offset    = 0;
361
6.45k
  uint16_t name_size    = 0;
362
363
#if defined( HAVE_DEBUG_OUTPUT )
364
  uint64_t value_64bit  = 0;
365
  uint32_t value_32bit  = 0;
366
#endif
367
368
6.45k
  if( file_name_values == NULL )
369
0
  {
370
0
    libcerror_error_set(
371
0
     error,
372
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
373
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
374
0
     "%s: invalid file name values.",
375
0
     function );
376
377
0
    return( -1 );
378
0
  }
379
6.45k
  if( file_name_values->name != NULL )
380
0
  {
381
0
    libcerror_error_set(
382
0
     error,
383
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
384
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
385
0
     "%s: invalid file name values - name already set.",
386
0
     function );
387
388
0
    return( -1 );
389
0
  }
390
6.45k
  if( data == NULL )
391
15
  {
392
15
    libcerror_error_set(
393
15
     error,
394
15
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
395
15
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
396
15
     "%s: invalid data.",
397
15
     function );
398
399
15
    return( -1 );
400
15
  }
401
6.43k
  if( data_size > (size_t) SSIZE_MAX )
402
0
  {
403
0
    libcerror_error_set(
404
0
     error,
405
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
406
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
407
0
     "%s: invalid data size value exceeds maximum.",
408
0
     function );
409
410
0
    return( -1 );
411
0
  }
412
6.43k
  if( data_size < sizeof( fsntfs_file_name_t ) )
413
9
  {
414
9
    libcerror_error_set(
415
9
     error,
416
9
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
417
9
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
418
9
     "%s: unsupported data size value too small.",
419
9
     function );
420
421
9
    return( -1 );
422
9
  }
423
#if defined( HAVE_DEBUG_OUTPUT )
424
  if( libcnotify_verbose != 0 )
425
  {
426
    libcnotify_printf(
427
     "%s: file name data:\n",
428
     function );
429
    libcnotify_print_data(
430
     data,
431
     data_size,
432
     0 );
433
  }
434
#endif
435
6.42k
  byte_stream_copy_to_uint64_little_endian(
436
6.42k
   ( (fsntfs_file_name_t *) data )->parent_file_reference,
437
6.42k
   file_name_values->parent_file_reference );
438
439
6.42k
  byte_stream_copy_to_uint64_little_endian(
440
6.42k
   ( (fsntfs_file_name_t *) data )->creation_time,
441
6.42k
   file_name_values->creation_time );
442
443
6.42k
  byte_stream_copy_to_uint64_little_endian(
444
6.42k
   ( (fsntfs_file_name_t *) data )->modification_time,
445
6.42k
   file_name_values->modification_time );
446
447
6.42k
  byte_stream_copy_to_uint64_little_endian(
448
6.42k
   ( (fsntfs_file_name_t *) data )->access_time,
449
6.42k
   file_name_values->access_time );
450
451
6.42k
  byte_stream_copy_to_uint64_little_endian(
452
6.42k
   ( (fsntfs_file_name_t *) data )->entry_modification_time,
453
6.42k
   file_name_values->entry_modification_time );
454
455
6.42k
  byte_stream_copy_to_uint64_little_endian(
456
6.42k
   ( (fsntfs_file_name_t *) data )->data_size,
457
6.42k
   file_name_values->size );
458
459
6.42k
  byte_stream_copy_to_uint32_little_endian(
460
6.42k
   ( (fsntfs_file_name_t *) data )->file_attribute_flags,
461
6.42k
   file_name_values->file_attribute_flags );
462
463
6.42k
  name_size = (uint16_t) ( (fsntfs_file_name_t *) data )->name_size;
464
465
6.42k
  file_name_values->name_space = ( (fsntfs_file_name_t *) data )->name_space;
466
467
#if defined( HAVE_DEBUG_OUTPUT )
468
  if( libcnotify_verbose != 0 )
469
  {
470
    libcnotify_printf(
471
     "%s: parent file reference\t\t: %" PRIu64 "-%" PRIu64 "\n",
472
     function,
473
     file_name_values->parent_file_reference & 0xffffffffffffUL,
474
     file_name_values->parent_file_reference >> 48 );
475
476
    if( libfsntfs_debug_print_filetime_value(
477
         function,
478
         "creation time\t\t\t",
479
         ( (fsntfs_file_name_t *) data )->creation_time,
480
         8,
481
         LIBFDATETIME_ENDIAN_LITTLE,
482
         LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
483
         error ) != 1 )
484
    {
485
      libcerror_error_set(
486
       error,
487
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
488
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
489
       "%s: unable to print FILETIME value.",
490
       function );
491
492
      goto on_error;
493
    }
494
    if( libfsntfs_debug_print_filetime_value(
495
         function,
496
         "modification time\t\t\t",
497
         ( (fsntfs_file_name_t *) data )->modification_time,
498
         8,
499
         LIBFDATETIME_ENDIAN_LITTLE,
500
         LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
501
         error ) != 1 )
502
    {
503
      libcerror_error_set(
504
       error,
505
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
506
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
507
       "%s: unable to print FILETIME value.",
508
       function );
509
510
      goto on_error;
511
    }
512
    if( libfsntfs_debug_print_filetime_value(
513
         function,
514
         "entry modification time\t\t",
515
         ( (fsntfs_file_name_t *) data )->entry_modification_time,
516
         8,
517
         LIBFDATETIME_ENDIAN_LITTLE,
518
         LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
519
         error ) != 1 )
520
    {
521
      libcerror_error_set(
522
       error,
523
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
524
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
525
       "%s: unable to print FILETIME value.",
526
       function );
527
528
      goto on_error;
529
    }
530
    if( libfsntfs_debug_print_filetime_value(
531
         function,
532
         "access time\t\t\t",
533
         ( (fsntfs_file_name_t *) data )->access_time,
534
         8,
535
         LIBFDATETIME_ENDIAN_LITTLE,
536
         LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
537
         error ) != 1 )
538
    {
539
      libcerror_error_set(
540
       error,
541
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
542
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
543
       "%s: unable to print FILETIME value.",
544
       function );
545
546
      goto on_error;
547
    }
548
    byte_stream_copy_to_uint64_little_endian(
549
     ( (fsntfs_file_name_t *) data )->allocated_data_size,
550
     value_64bit );
551
    libcnotify_printf(
552
     "%s: allocated data size\t\t: %" PRIu64 "\n",
553
     function,
554
     value_64bit );
555
556
    libcnotify_printf(
557
     "%s: data size\t\t\t\t: %" PRIu64 "\n",
558
     function,
559
     file_name_values->size );
560
561
    libcnotify_printf(
562
     "%s: file attribute flags\t\t: 0x%08" PRIx32 "\n",
563
     function,
564
     file_name_values->file_attribute_flags );
565
    libfsntfs_debug_print_file_attribute_flags(
566
     file_name_values->file_attribute_flags );
567
    libcnotify_printf(
568
     "\n" );
569
570
    byte_stream_copy_to_uint32_little_endian(
571
     ( (fsntfs_file_name_t *) data )->extended_data,
572
     value_32bit );
573
    libcnotify_printf(
574
     "%s: extended data\t\t\t: 0x%08" PRIx32 "\n",
575
     function,
576
     value_32bit );
577
578
    libcnotify_printf(
579
     "%s: name size\t\t\t\t: %" PRIu16 "\n",
580
     function,
581
     name_size );
582
583
    libcnotify_printf(
584
     "%s: name space\t\t\t: %" PRIu8 " (%s)\n",
585
     function,
586
     file_name_values->name_space,
587
     libfsntfs_debug_print_file_name_attribute_name_space(
588
      file_name_values->name_space ) );
589
  }
590
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
591
592
6.42k
  data_offset = sizeof( fsntfs_file_name_t );
593
594
6.42k
  if( name_size > 0 )
595
6.42k
  {
596
6.42k
    name_size *= 2;
597
598
6.42k
    if( (size_t) name_size > ( data_size - data_offset ) )
599
34
    {
600
34
      libcerror_error_set(
601
34
       error,
602
34
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
603
34
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
604
34
       "%s: invalid name size value out of bounds.",
605
34
       function );
606
607
34
      goto on_error;
608
34
    }
609
6.38k
    if( libfsntfs_file_name_values_set_name(
610
6.38k
         file_name_values,
611
6.38k
         &( data[ data_offset ] ),
612
6.38k
         (size_t) name_size,
613
6.38k
         error ) != 1 )
614
0
    {
615
0
      libcerror_error_set(
616
0
       error,
617
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
618
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
619
0
       "%s: unable to set name.",
620
0
       function );
621
622
0
      goto on_error;
623
0
    }
624
#if defined( HAVE_DEBUG_OUTPUT )
625
    if( libcnotify_verbose != 0 )
626
    {
627
      if( libfsntfs_debug_print_utf16_string_value(
628
           function,
629
           "name\t\t\t\t",
630
           file_name_values->name,
631
           file_name_values->name_size,
632
           LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
633
           error ) != 1 )
634
      {
635
        libcerror_error_set(
636
         error,
637
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
638
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
639
         "%s: unable to print UTF-16 string value.",
640
         function );
641
642
        goto on_error;
643
      }
644
      libcnotify_printf(
645
       "\n" );
646
    }
647
    data_offset += file_name_values->name_size;
648
649
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
650
651
/* TODO debug print alignment padding */
652
6.38k
  }
653
#if defined( HAVE_DEBUG_OUTPUT )
654
  if( libcnotify_verbose != 0 )
655
  {
656
    if( data_offset < data_size )
657
    {
658
      libcnotify_printf(
659
       "%s: trailing data:\n",
660
       function );
661
      libcnotify_print_data(
662
       &( data[ data_offset ] ),
663
       data_size - data_offset,
664
       0 );
665
    }
666
  }
667
#endif
668
6.39k
  return( 1 );
669
670
34
on_error:
671
34
  if( file_name_values->name != NULL )
672
0
  {
673
0
    memory_free(
674
0
     file_name_values->name );
675
676
0
    file_name_values->name = NULL;
677
0
  }
678
34
  file_name_values->name_size = 0;
679
680
34
  return( -1 );
681
6.42k
}
682
683
/* Reads the file name values from an MFT attribute
684
 * Returns 1 if successful or -1 on error
685
 */
686
int libfsntfs_file_name_values_read_from_mft_attribute(
687
     libfsntfs_file_name_values_t *file_name_values,
688
     libfsntfs_mft_attribute_t *mft_attribute,
689
     libcerror_error_t **error )
690
2.90k
{
691
2.90k
  uint8_t *data           = NULL;
692
2.90k
  static char *function   = "libfsntfs_file_name_values_read_from_mft_attribute";
693
2.90k
  size_t data_size        = 0;
694
2.90k
  uint32_t attribute_type = 0;
695
2.90k
  int result              = 0;
696
697
2.90k
  if( file_name_values == NULL )
698
0
  {
699
0
    libcerror_error_set(
700
0
     error,
701
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
702
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
703
0
     "%s: invalid file name values.",
704
0
     function );
705
706
0
    return( -1 );
707
0
  }
708
2.90k
  if( libfsntfs_mft_attribute_get_type(
709
2.90k
       mft_attribute,
710
2.90k
       &attribute_type,
711
2.90k
       error ) != 1 )
712
0
  {
713
0
    libcerror_error_set(
714
0
     error,
715
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
716
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
717
0
     "%s: unable to retrieve type from attribute.",
718
0
     function );
719
720
0
    return( -1 );
721
0
  }
722
2.90k
  if( attribute_type != LIBFSNTFS_ATTRIBUTE_TYPE_FILE_NAME )
723
0
  {
724
0
    libcerror_error_set(
725
0
     error,
726
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
727
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
728
0
     "%s: unsupported attribute type.",
729
0
     function );
730
731
0
    return( -1 );
732
0
  }
733
2.90k
  result = libfsntfs_mft_attribute_data_is_resident(
734
2.90k
            mft_attribute,
735
2.90k
            error );
736
737
2.90k
  if( result == -1 )
738
0
  {
739
0
    libcerror_error_set(
740
0
     error,
741
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
742
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
743
0
     "%s: unable to determine if attribute data is resident.",
744
0
     function );
745
746
0
    return( -1 );
747
0
  }
748
2.90k
  else if( result == 0 )
749
10
  {
750
10
    libcerror_error_set(
751
10
     error,
752
10
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
753
10
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
754
10
     "%s: unsupported non-resident attribute.",
755
10
     function );
756
757
10
    return( 1 );
758
10
  }
759
2.89k
  if( libfsntfs_mft_attribute_get_resident_data(
760
2.89k
       mft_attribute,
761
2.89k
       &data,
762
2.89k
       &data_size,
763
2.89k
       error ) != 1 )
764
0
  {
765
0
    libcerror_error_set(
766
0
     error,
767
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
768
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
769
0
     "%s: unable to retrieve resident data from attribute.",
770
0
     function );
771
772
0
    return( -1 );
773
0
  }
774
2.89k
  if( libfsntfs_file_name_values_read_data(
775
2.89k
       file_name_values,
776
2.89k
       data,
777
2.89k
       data_size,
778
2.89k
       error ) != 1 )
779
40
  {
780
40
    libcerror_error_set(
781
40
     error,
782
40
     LIBCERROR_ERROR_DOMAIN_IO,
783
40
     LIBCERROR_IO_ERROR_READ_FAILED,
784
40
     "%s: unable to read file name values.",
785
40
     function );
786
787
40
    return( -1 );
788
40
  }
789
2.85k
  return( 1 );
790
2.89k
}
791
792
/* Retrieves the parent file reference
793
 * Returns 1 if successful or -1 on error
794
 */
795
int libfsntfs_file_name_values_get_parent_file_reference(
796
     libfsntfs_file_name_values_t *file_name_values,
797
     uint64_t *parent_file_reference,
798
     libcerror_error_t **error )
799
0
{
800
0
  static char *function = "libfsntfs_file_name_values_get_parent_file_reference";
801
802
0
  if( file_name_values == NULL )
803
0
  {
804
0
    libcerror_error_set(
805
0
     error,
806
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
807
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
808
0
     "%s: invalid file name values.",
809
0
     function );
810
811
0
    return( -1 );
812
0
  }
813
0
  if( parent_file_reference == NULL )
814
0
  {
815
0
    libcerror_error_set(
816
0
     error,
817
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
818
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
819
0
     "%s: invalid parent file reference.",
820
0
     function );
821
822
0
    return( -1 );
823
0
  }
824
0
  *parent_file_reference = file_name_values->parent_file_reference;
825
826
0
  return( 1 );
827
0
}
828
829
/* Retrieves the creation date and time
830
 * Returns 1 if successful or -1 on error
831
 */
832
int libfsntfs_file_name_values_get_creation_time(
833
     libfsntfs_file_name_values_t *file_name_values,
834
     uint64_t *filetime,
835
     libcerror_error_t **error )
836
0
{
837
0
  static char *function = "libfsntfs_file_name_values_get_creation_time";
838
839
0
  if( file_name_values == NULL )
840
0
  {
841
0
    libcerror_error_set(
842
0
     error,
843
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
844
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
845
0
     "%s: invalid file name values.",
846
0
     function );
847
848
0
    return( -1 );
849
0
  }
850
0
  if( filetime == NULL )
851
0
  {
852
0
    libcerror_error_set(
853
0
     error,
854
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
855
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
856
0
     "%s: invalid FILETIME.",
857
0
     function );
858
859
0
    return( -1 );
860
0
  }
861
0
  *filetime = file_name_values->creation_time;
862
863
0
  return( 1 );
864
0
}
865
866
/* Retrieves the (file) modification (last written) date and time
867
 * Returns 1 if successful or -1 on error
868
 */
869
int libfsntfs_file_name_values_get_modification_time(
870
     libfsntfs_file_name_values_t *file_name_values,
871
     uint64_t *filetime,
872
     libcerror_error_t **error )
873
0
{
874
0
  static char *function = "libfsntfs_file_name_values_get_modification_time";
875
876
0
  if( file_name_values == NULL )
877
0
  {
878
0
    libcerror_error_set(
879
0
     error,
880
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
881
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
882
0
     "%s: invalid file name values.",
883
0
     function );
884
885
0
    return( -1 );
886
0
  }
887
0
  if( filetime == NULL )
888
0
  {
889
0
    libcerror_error_set(
890
0
     error,
891
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
892
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
893
0
     "%s: invalid FILETIME.",
894
0
     function );
895
896
0
    return( -1 );
897
0
  }
898
0
  *filetime = file_name_values->modification_time;
899
900
0
  return( 1 );
901
0
}
902
903
/* Retrieves the access date and time
904
 * Returns 1 if successful or -1 on error
905
 */
906
int libfsntfs_file_name_values_get_access_time(
907
     libfsntfs_file_name_values_t *file_name_values,
908
     uint64_t *filetime,
909
     libcerror_error_t **error )
910
0
{
911
0
  static char *function = "libfsntfs_file_name_values_get_access_time";
912
913
0
  if( file_name_values == NULL )
914
0
  {
915
0
    libcerror_error_set(
916
0
     error,
917
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
918
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
919
0
     "%s: invalid file name values.",
920
0
     function );
921
922
0
    return( -1 );
923
0
  }
924
0
  if( filetime == NULL )
925
0
  {
926
0
    libcerror_error_set(
927
0
     error,
928
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
929
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
930
0
     "%s: invalid FILETIME.",
931
0
     function );
932
933
0
    return( -1 );
934
0
  }
935
0
  *filetime = file_name_values->access_time;
936
937
0
  return( 1 );
938
0
}
939
940
/* Retrieves the (file system entry) modification date and time
941
 * Returns 1 if successful or -1 on error
942
 */
943
int libfsntfs_file_name_values_get_entry_modification_time(
944
     libfsntfs_file_name_values_t *file_name_values,
945
     uint64_t *filetime,
946
     libcerror_error_t **error )
947
0
{
948
0
  static char *function = "libfsntfs_file_name_values_get_entry_modification_time";
949
950
0
  if( file_name_values == NULL )
951
0
  {
952
0
    libcerror_error_set(
953
0
     error,
954
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
955
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
956
0
     "%s: invalid file name values.",
957
0
     function );
958
959
0
    return( -1 );
960
0
  }
961
0
  if( filetime == NULL )
962
0
  {
963
0
    libcerror_error_set(
964
0
     error,
965
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
966
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
967
0
     "%s: invalid FILETIME.",
968
0
     function );
969
970
0
    return( -1 );
971
0
  }
972
0
  *filetime = file_name_values->entry_modification_time;
973
974
0
  return( 1 );
975
0
}
976
977
/* Retrieves the size
978
 * Returns 1 if successful or -1 on error
979
 */
980
int libfsntfs_file_name_values_get_size(
981
     libfsntfs_file_name_values_t *file_name_values,
982
     uint64_t *size,
983
     libcerror_error_t **error )
984
0
{
985
0
  static char *function = "libfsntfs_file_name_values_get_size";
986
987
0
  if( file_name_values == NULL )
988
0
  {
989
0
    libcerror_error_set(
990
0
     error,
991
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
992
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
993
0
     "%s: invalid file name values.",
994
0
     function );
995
996
0
    return( -1 );
997
0
  }
998
0
  if( size == NULL )
999
0
  {
1000
0
    libcerror_error_set(
1001
0
     error,
1002
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1003
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1004
0
     "%s: invalid size.",
1005
0
     function );
1006
1007
0
    return( -1 );
1008
0
  }
1009
0
  *size = file_name_values->size;
1010
1011
0
  return( 1 );
1012
0
}
1013
1014
/* Retrieves the file attribute flags
1015
 * Returns 1 if successful or -1 on error
1016
 */
1017
int libfsntfs_file_name_values_get_file_attribute_flags(
1018
     libfsntfs_file_name_values_t *file_name_values,
1019
     uint32_t *file_attribute_flags,
1020
     libcerror_error_t **error )
1021
0
{
1022
0
  static char *function = "libfsntfs_file_name_values_get_file_attribute_flags";
1023
1024
0
  if( file_name_values == NULL )
1025
0
  {
1026
0
    libcerror_error_set(
1027
0
     error,
1028
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1029
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1030
0
     "%s: invalid file name values.",
1031
0
     function );
1032
1033
0
    return( -1 );
1034
0
  }
1035
0
  if( file_attribute_flags == NULL )
1036
0
  {
1037
0
    libcerror_error_set(
1038
0
     error,
1039
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1040
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1041
0
     "%s: invalid file attribute flags.",
1042
0
     function );
1043
1044
0
    return( -1 );
1045
0
  }
1046
0
  *file_attribute_flags = file_name_values->file_attribute_flags;
1047
1048
0
  return( 1 );
1049
0
}
1050
1051
/* Retrieves the name space
1052
 * Returns 1 if successful or -1 on error
1053
 */
1054
int libfsntfs_file_name_values_get_name_space(
1055
     libfsntfs_file_name_values_t *file_name_values,
1056
     uint8_t *name_space,
1057
     libcerror_error_t **error )
1058
0
{
1059
0
  static char *function = "libfsntfs_file_name_values_get_name_space";
1060
1061
0
  if( file_name_values == NULL )
1062
0
  {
1063
0
    libcerror_error_set(
1064
0
     error,
1065
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1066
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1067
0
     "%s: invalid file name values.",
1068
0
     function );
1069
1070
0
    return( -1 );
1071
0
  }
1072
0
  if( name_space == NULL )
1073
0
  {
1074
0
    libcerror_error_set(
1075
0
     error,
1076
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1077
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1078
0
     "%s: invalid name space.",
1079
0
     function );
1080
1081
0
    return( -1 );
1082
0
  }
1083
0
  *name_space = file_name_values->name_space;
1084
1085
0
  return( 1 );
1086
0
}
1087
1088
/* Retrieves the size of the UTF-8 encoded name
1089
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
1090
 * The returned size includes the end of string character
1091
 * Returns 1 if successful or -1 on error
1092
 */
1093
int libfsntfs_file_name_values_get_utf8_name_size(
1094
     libfsntfs_file_name_values_t *file_name_values,
1095
     size_t *utf8_string_size,
1096
     libcerror_error_t **error )
1097
0
{
1098
0
  static char *function = "libfsntfs_file_name_values_get_utf8_name_size";
1099
1100
0
  if( file_name_values == NULL )
1101
0
  {
1102
0
    libcerror_error_set(
1103
0
     error,
1104
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1105
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1106
0
     "%s: invalid file name values.",
1107
0
     function );
1108
1109
0
    return( -1 );
1110
0
  }
1111
0
  if( libuna_utf8_string_size_from_utf16_stream(
1112
0
       file_name_values->name,
1113
0
       (size_t) file_name_values->name_size,
1114
0
       LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
1115
0
       utf8_string_size,
1116
0
       error ) != 1 )
1117
0
  {
1118
0
    libcerror_error_set(
1119
0
     error,
1120
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1121
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1122
0
     "%s: unable to retrieve UTF-8 string size.",
1123
0
     function );
1124
1125
0
    return( -1 );
1126
0
  }
1127
0
  return( 1 );
1128
0
}
1129
1130
/* Retrieves the UTF-8 encoded name
1131
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
1132
 * The size should include the end of string character
1133
 * Returns 1 if successful or -1 on error
1134
 */
1135
int libfsntfs_file_name_values_get_utf8_name(
1136
     libfsntfs_file_name_values_t *file_name_values,
1137
     uint8_t *utf8_string,
1138
     size_t utf8_string_size,
1139
     libcerror_error_t **error )
1140
0
{
1141
0
  static char *function = "libfsntfs_file_name_values_get_utf8_name";
1142
1143
0
  if( file_name_values == NULL )
1144
0
  {
1145
0
    libcerror_error_set(
1146
0
     error,
1147
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1148
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1149
0
     "%s: invalid file name values.",
1150
0
     function );
1151
1152
0
    return( -1 );
1153
0
  }
1154
0
  if( libuna_utf8_string_copy_from_utf16_stream(
1155
0
       utf8_string,
1156
0
       utf8_string_size,
1157
0
       file_name_values->name,
1158
0
       (size_t) file_name_values->name_size,
1159
0
       LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
1160
0
       error ) != 1 )
1161
0
  {
1162
0
    libcerror_error_set(
1163
0
     error,
1164
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1165
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1166
0
     "%s: unable to retrieve UTF-8 string.",
1167
0
     function );
1168
1169
0
    return( -1 );
1170
0
  }
1171
#if defined( HAVE_DEBUG_OUTPUT )
1172
  if( libcnotify_verbose != 0 )
1173
  {
1174
    libcnotify_printf(
1175
     "%s: string data:\n",
1176
     function );
1177
    libcnotify_print_data(
1178
     utf8_string,
1179
     utf8_string_size,
1180
     0 );
1181
  }
1182
#endif
1183
0
  return( 1 );
1184
0
}
1185
1186
/* Retrieves the size of the UTF-16 encoded name
1187
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
1188
 * The returned size includes the end of string character
1189
 * Returns 1 if successful or -1 on error
1190
 */
1191
int libfsntfs_file_name_values_get_utf16_name_size(
1192
     libfsntfs_file_name_values_t *file_name_values,
1193
     size_t *utf16_string_size,
1194
     libcerror_error_t **error )
1195
0
{
1196
0
  static char *function = "libfsntfs_file_name_values_get_utf16_name_size";
1197
1198
0
  if( file_name_values == NULL )
1199
0
  {
1200
0
    libcerror_error_set(
1201
0
     error,
1202
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1203
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1204
0
     "%s: invalid file name values.",
1205
0
     function );
1206
1207
0
    return( -1 );
1208
0
  }
1209
0
  if( libuna_utf16_string_size_from_utf16_stream(
1210
0
       file_name_values->name,
1211
0
       (size_t) file_name_values->name_size,
1212
0
       LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
1213
0
       utf16_string_size,
1214
0
       error ) != 1 )
1215
0
  {
1216
0
    libcerror_error_set(
1217
0
     error,
1218
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1219
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1220
0
     "%s: unable to retrieve UTF-16 string size.",
1221
0
     function );
1222
1223
0
    return( -1 );
1224
0
  }
1225
0
  return( 1 );
1226
0
}
1227
1228
/* Retrieves the UTF-16 encoded name
1229
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
1230
 * The size should include the end of string character
1231
 * Returns 1 if successful or -1 on error
1232
 */
1233
int libfsntfs_file_name_values_get_utf16_name(
1234
     libfsntfs_file_name_values_t *file_name_values,
1235
     uint16_t *utf16_string,
1236
     size_t utf16_string_size,
1237
     libcerror_error_t **error )
1238
0
{
1239
0
  static char *function = "libfsntfs_file_name_values_get_utf16_name";
1240
1241
0
  if( file_name_values == NULL )
1242
0
  {
1243
0
    libcerror_error_set(
1244
0
     error,
1245
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1246
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1247
0
     "%s: invalid file name values.",
1248
0
     function );
1249
1250
0
    return( -1 );
1251
0
  }
1252
0
  if( libuna_utf16_string_copy_from_utf16_stream(
1253
0
       utf16_string,
1254
0
       utf16_string_size,
1255
0
       file_name_values->name,
1256
0
       (size_t) file_name_values->name_size,
1257
0
       LIBUNA_ENDIAN_LITTLE | LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE,
1258
0
       error ) != 1 )
1259
0
  {
1260
0
    libcerror_error_set(
1261
0
     error,
1262
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1263
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1264
0
     "%s: unable to retrieve UTF-16 string.",
1265
0
     function );
1266
1267
0
    return( -1 );
1268
0
  }
1269
0
  return( 1 );
1270
0
}
1271