Coverage Report

Created: 2025-10-14 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libfsfat/libfsfat/libfsfat_directory_entry.c
Line
Count
Source
1
/*
2
 * The directory entry functions
3
 *
4
 * Copyright (C) 2021-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 "libfsfat_date_time.h"
28
#include "libfsfat_debug.h"
29
#include "libfsfat_definitions.h"
30
#include "libfsfat_directory_entry.h"
31
#include "libfsfat_libbfio.h"
32
#include "libfsfat_libcdata.h"
33
#include "libfsfat_libcerror.h"
34
#include "libfsfat_libcnotify.h"
35
#include "libfsfat_libfdatetime.h"
36
#include "libfsfat_libuna.h"
37
#include "libfsfat_name.h"
38
39
#include "fsfat_directory_entry.h"
40
41
const uint8_t libfsfat_directory_entry_empty[ 32 ] = {
42
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
44
45
/* Creates a directory entry
46
 * Make sure the value directory_entry is referencing, is set to NULL
47
 * Returns 1 if successful or -1 on error
48
 */
49
int libfsfat_directory_entry_initialize(
50
     libfsfat_directory_entry_t **directory_entry,
51
     libcerror_error_t **error )
52
802k
{
53
802k
  static char *function = "libfsfat_directory_entry_initialize";
54
55
802k
  if( directory_entry == NULL )
56
0
  {
57
0
    libcerror_error_set(
58
0
     error,
59
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
60
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
61
0
     "%s: invalid directory entry.",
62
0
     function );
63
64
0
    return( -1 );
65
0
  }
66
802k
  if( *directory_entry != NULL )
67
0
  {
68
0
    libcerror_error_set(
69
0
     error,
70
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
71
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
72
0
     "%s: invalid directory entry value already set.",
73
0
     function );
74
75
0
    return( -1 );
76
0
  }
77
802k
  *directory_entry = memory_allocate_structure(
78
802k
                      libfsfat_directory_entry_t );
79
80
802k
  if( *directory_entry == NULL )
81
0
  {
82
0
    libcerror_error_set(
83
0
     error,
84
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
85
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
86
0
     "%s: unable to create directory entry.",
87
0
     function );
88
89
0
    goto on_error;
90
0
  }
91
802k
  if( memory_set(
92
802k
       *directory_entry,
93
802k
       0,
94
802k
       sizeof( libfsfat_directory_entry_t ) ) == NULL )
95
0
  {
96
0
    libcerror_error_set(
97
0
     error,
98
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
99
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
100
0
     "%s: unable to clear directory entry.",
101
0
     function );
102
103
0
    memory_free(
104
0
     *directory_entry );
105
106
0
    *directory_entry = NULL;
107
108
0
    return( -1 );
109
0
  }
110
802k
  ( *directory_entry )->entry_type = LIBFSFAT_DIRECTORY_ENTRY_TYPE_TERMINATOR;
111
112
802k
  return( 1 );
113
114
0
on_error:
115
0
  if( *directory_entry != NULL )
116
0
  {
117
0
    memory_free(
118
0
     *directory_entry );
119
120
0
    *directory_entry = NULL;
121
0
  }
122
0
  return( -1 );
123
802k
}
124
125
/* Frees a directory entry
126
 * Returns 1 if successful or -1 on error
127
 */
128
int libfsfat_directory_entry_free(
129
     libfsfat_directory_entry_t **directory_entry,
130
     libcerror_error_t **error )
131
802k
{
132
802k
  static char *function = "libfsfat_directory_entry_free";
133
802k
  int result            = 1;
134
135
802k
  if( directory_entry == NULL )
136
0
  {
137
0
    libcerror_error_set(
138
0
     error,
139
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
140
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
141
0
     "%s: invalid directory entry.",
142
0
     function );
143
144
0
    return( -1 );
145
0
  }
146
802k
  if( *directory_entry != NULL )
147
802k
  {
148
802k
    if( ( *directory_entry )->name_entries_array != NULL )
149
2.09k
    {
150
2.09k
      if( libcdata_array_free(
151
2.09k
           &( ( *directory_entry )->name_entries_array ),
152
2.09k
           NULL,
153
2.09k
           error ) != 1 )
154
0
      {
155
0
        libcerror_error_set(
156
0
         error,
157
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
158
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
159
0
         "%s: unable to free name entries array.",
160
0
         function );
161
162
0
        result = -1;
163
0
      }
164
2.09k
    }
165
802k
    if( ( *directory_entry )->name != NULL )
166
3.29k
    {
167
3.29k
      memory_free(
168
3.29k
       ( *directory_entry )->name );
169
3.29k
    }
170
802k
    memory_free(
171
802k
     *directory_entry );
172
173
802k
    *directory_entry = NULL;
174
802k
  }
175
802k
  return( result );
176
802k
}
177
178
/* Clones a directory entry
179
 * Returns 1 if successful or -1 on error
180
 */
181
int libfsfat_directory_entry_clone(
182
     libfsfat_directory_entry_t **destination_directory_entry,
183
     libfsfat_directory_entry_t *source_directory_entry,
184
     libcerror_error_t **error )
185
160
{
186
160
  static char *function = "libfsfat_directory_entry_clone";
187
188
160
  if( destination_directory_entry == NULL )
189
0
  {
190
0
    libcerror_error_set(
191
0
     error,
192
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
193
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
194
0
     "%s: invalid directory entry.",
195
0
     function );
196
197
0
    return( -1 );
198
0
  }
199
160
  if( *destination_directory_entry != NULL )
200
0
  {
201
0
    libcerror_error_set(
202
0
     error,
203
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
204
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
205
0
     "%s: invalid destination directory entry value already set.",
206
0
     function );
207
208
0
    return( -1 );
209
0
  }
210
160
  if( source_directory_entry == NULL )
211
0
  {
212
0
    *destination_directory_entry = source_directory_entry;
213
214
0
    return( 1 );
215
0
  }
216
160
  if( source_directory_entry->name == NULL )
217
159
  {
218
159
    if( libfsfat_directory_entry_get_name(
219
159
         source_directory_entry,
220
159
         error ) != 1 )
221
14
    {
222
14
      libcerror_error_set(
223
14
       error,
224
14
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
225
14
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
226
14
       "%s: unable to determine name of source directory entry.",
227
14
       function );
228
229
14
      return( -1 );
230
14
    }
231
159
  }
232
146
  *destination_directory_entry = memory_allocate_structure(
233
146
                                  libfsfat_directory_entry_t );
234
235
146
  if( *destination_directory_entry == NULL )
236
0
  {
237
0
    libcerror_error_set(
238
0
     error,
239
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
240
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
241
0
     "%s: unable to create destination directory entry.",
242
0
     function );
243
244
0
    goto on_error;
245
0
  }
246
146
  if( memory_copy(
247
146
       *destination_directory_entry,
248
146
       source_directory_entry,
249
146
       sizeof( libfsfat_directory_entry_t ) ) == NULL )
250
0
  {
251
0
    libcerror_error_set(
252
0
     error,
253
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
254
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
255
0
     "%s: unable to copy directory entry.",
256
0
     function );
257
258
0
    ( *destination_directory_entry )->name = NULL;
259
260
0
    goto on_error;
261
0
  }
262
146
  ( *destination_directory_entry )->name               = NULL;
263
146
  ( *destination_directory_entry )->name_entries_array = NULL;
264
265
146
  if( source_directory_entry->name != NULL )
266
146
  {
267
146
    ( *destination_directory_entry )->name = (uint8_t *) memory_allocate(
268
146
                                                          sizeof( uint8_t ) * source_directory_entry->name_size );
269
270
146
    if( ( *destination_directory_entry )->name == NULL )
271
0
    {
272
0
      libcerror_error_set(
273
0
       error,
274
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
275
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
276
0
       "%s: unable to create name.",
277
0
       function );
278
279
0
      goto on_error;
280
0
    }
281
146
    if( memory_copy(
282
146
         ( *destination_directory_entry )->name,
283
146
         source_directory_entry->name,
284
146
         source_directory_entry->name_size ) == NULL )
285
0
    {
286
0
      libcerror_error_set(
287
0
       error,
288
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
289
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
290
0
       "%s: unable to copy name.",
291
0
       function );
292
293
0
      goto on_error;
294
0
    }
295
146
  }
296
146
  return( 1 );
297
298
0
on_error:
299
0
  if( *destination_directory_entry != NULL )
300
0
  {
301
0
    if( ( *destination_directory_entry )->name != NULL )
302
0
    {
303
0
      memory_free(
304
0
       ( *destination_directory_entry )->name );
305
0
    }
306
0
    memory_free(
307
0
     *destination_directory_entry );
308
309
0
    *destination_directory_entry = NULL;
310
0
  }
311
0
  return( -1 );
312
146
}
313
314
/* Reads a directory entry
315
 * Returns 1 if successful, 0 if empty or -1 on error
316
 */
317
int libfsfat_directory_entry_read_data(
318
     libfsfat_directory_entry_t *directory_entry,
319
     const uint8_t *data,
320
     size_t data_size,
321
     uint8_t file_system_format,
322
     libcerror_error_t **error )
323
801k
{
324
801k
  static char *function = "libfsfat_directory_entry_read_data";
325
326
#if defined( HAVE_DEBUG_OUTPUT )
327
  uint64_t value_64bit  = 0;
328
  uint32_t value_32bit  = 0;
329
  uint16_t value_16bit  = 0;
330
#endif
331
332
801k
  if( directory_entry == NULL )
333
0
  {
334
0
    libcerror_error_set(
335
0
     error,
336
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
337
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
338
0
     "%s: invalid directory entry.",
339
0
     function );
340
341
0
    return( -1 );
342
0
  }
343
801k
  if( data == NULL )
344
0
  {
345
0
    libcerror_error_set(
346
0
     error,
347
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
348
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
349
0
     "%s: invalid data.",
350
0
     function );
351
352
0
    return( -1 );
353
0
  }
354
801k
  if( data_size != sizeof( fsfat_directory_entry_t ) )
355
0
  {
356
0
    libcerror_error_set(
357
0
     error,
358
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
359
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
360
0
     "%s: invalid data size value out of bounds.",
361
0
     function );
362
363
0
    return( -1 );
364
0
  }
365
#if defined( HAVE_DEBUG_OUTPUT )
366
  if( libcnotify_verbose != 0 )
367
  {
368
    libcnotify_printf(
369
     "%s: directory entry data:\n",
370
     function );
371
    libcnotify_print_data(
372
     data,
373
     sizeof( fsfat_directory_entry_t ),
374
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
375
  }
376
#endif
377
801k
  if( file_system_format == LIBFSFAT_FILE_SYSTEM_FORMAT_EXFAT )
378
142k
  {
379
142k
    switch( data[ 0 ] )
380
142k
    {
381
104
      case 0:
382
104
        directory_entry->entry_type = LIBFSFAT_DIRECTORY_ENTRY_TYPE_TERMINATOR;
383
104
        break;
384
385
759
      case 0x81:
386
759
        directory_entry->entry_type = LIBFSFAT_DIRECTORY_ENTRY_TYPE_EXFAT_ALLOCATION_BITMAP;
387
759
        break;
388
389
1.87k
      case 0x82:
390
1.87k
        directory_entry->entry_type = LIBFSFAT_DIRECTORY_ENTRY_TYPE_EXFAT_UPCASE_TABLE;
391
1.87k
        break;
392
393
26
      case 0x83:
394
26
        directory_entry->entry_type = LIBFSFAT_DIRECTORY_ENTRY_TYPE_EXFAT_VOLUME_LABEL;
395
26
        break;
396
397
2.09k
      case 0x85:
398
2.09k
        directory_entry->entry_type = LIBFSFAT_DIRECTORY_ENTRY_TYPE_EXFAT_FILE_ENTRY;
399
2.09k
        break;
400
401
637
      case 0xc0:
402
637
        directory_entry->entry_type = LIBFSFAT_DIRECTORY_ENTRY_TYPE_EXFAT_DATA_STREAM;
403
637
        break;
404
405
2.83k
      case 0xc1:
406
2.83k
        directory_entry->entry_type = LIBFSFAT_DIRECTORY_ENTRY_TYPE_EXFAT_FILE_ENTRY_NAME;
407
2.83k
        break;
408
409
133k
      default:
410
133k
        directory_entry->entry_type = LIBFSFAT_DIRECTORY_ENTRY_TYPE_EXFAT_UNKNOWN;
411
133k
        break;
412
142k
    }
413
142k
  }
414
659k
  else if( memory_compare(
415
659k
            data,
416
659k
            libfsfat_directory_entry_empty,
417
659k
            sizeof( fsfat_directory_entry_t ) ) == 0 )
418
22
  {
419
22
    directory_entry->entry_type = LIBFSFAT_DIRECTORY_ENTRY_TYPE_TERMINATOR;
420
22
  }
421
659k
  else
422
659k
  {
423
659k
    directory_entry->entry_type = LIBFSFAT_DIRECTORY_ENTRY_TYPE_SHORT_NAME;
424
425
659k
    if( ( ( data[ 0 ] >= 0x01 )
426
647k
      &&  ( data[ 0 ] <= 0x13 ) )
427
640k
     || ( ( data[ 0 ] >= 0x41 )
428
594k
      &&  ( data[ 0 ] <= 0x54 ) ) )
429
298k
    {
430
298k
      if( ( data[ 11 ] == 0x0f )
431
18.2k
       && ( data[ 12 ] == 0x00 )
432
9.27k
       && ( data[ 26 ] == 0x00 )
433
8.38k
       && ( data[ 27 ] == 0x00 ) )
434
7.90k
      {
435
7.90k
        directory_entry->entry_type = LIBFSFAT_DIRECTORY_ENTRY_TYPE_VFAT_LONG_NAME;
436
7.90k
      }
437
298k
    }
438
361k
    else if( data[ 0 ] == 0xe5 )
439
3.39k
    {
440
3.39k
      directory_entry->entry_type = LIBFSFAT_DIRECTORY_ENTRY_TYPE_UNALLOCATED;
441
3.39k
    }
442
659k
  }
443
801k
  if( directory_entry->entry_type == LIBFSFAT_DIRECTORY_ENTRY_TYPE_TERMINATOR )
444
126
  {
445
126
    return( 0 );
446
126
  }
447
801k
  else if( directory_entry->entry_type == LIBFSFAT_DIRECTORY_ENTRY_TYPE_SHORT_NAME )
448
648k
  {
449
648k
    if( memory_copy(
450
648k
         directory_entry->name_data,
451
648k
         ( (fsfat_directory_entry_t *) data )->name,
452
648k
         8 ) == NULL )
453
0
    {
454
0
      libcerror_error_set(
455
0
       error,
456
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
457
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
458
0
       "%s: unable to copy name.",
459
0
       function );
460
461
0
      return( -1 );
462
0
    }
463
648k
    if( memory_copy(
464
648k
         &( directory_entry->name_data[ 8 ] ),
465
648k
         ( (fsfat_directory_entry_t *) data )->extension,
466
648k
         3 ) == NULL )
467
0
    {
468
0
      libcerror_error_set(
469
0
       error,
470
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
471
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
472
0
       "%s: unable to copy extension.",
473
0
       function );
474
475
0
      return( -1 );
476
0
    }
477
648k
    directory_entry->file_attribute_flags = ( (fsfat_directory_entry_t *) data )->file_attribute_flags;
478
479
648k
    directory_entry->creation_time_fraction = ( (fsfat_directory_entry_t *) data )->creation_time_fraction;
480
481
648k
    byte_stream_copy_to_uint16_little_endian(
482
648k
     ( (fsfat_directory_entry_t *) data )->creation_date,
483
648k
     directory_entry->creation_date );
484
485
648k
    byte_stream_copy_to_uint16_little_endian(
486
648k
     ( (fsfat_directory_entry_t *) data )->creation_time,
487
648k
     directory_entry->creation_time );
488
489
648k
    byte_stream_copy_to_uint16_little_endian(
490
648k
     ( (fsfat_directory_entry_t *) data )->access_date,
491
648k
     directory_entry->access_date );
492
493
648k
    byte_stream_copy_to_uint16_little_endian(
494
648k
     ( (fsfat_directory_entry_t *) data )->modification_date,
495
648k
     directory_entry->modification_date );
496
497
648k
    byte_stream_copy_to_uint16_little_endian(
498
648k
     ( (fsfat_directory_entry_t *) data )->modification_time,
499
648k
     directory_entry->modification_time );
500
501
648k
    byte_stream_copy_to_uint16_little_endian(
502
648k
     ( (fsfat_directory_entry_t *) data )->data_start_cluster,
503
648k
     directory_entry->data_start_cluster );
504
505
648k
    byte_stream_copy_to_uint32_little_endian(
506
648k
     ( (fsfat_directory_entry_t *) data )->data_size,
507
648k
     directory_entry->data_size );
508
509
#if defined( HAVE_DEBUG_OUTPUT )
510
    if( libcnotify_verbose != 0 )
511
    {
512
      libcnotify_printf(
513
       "%s: name\t\t\t\t: %c%c%c%c%c%c%c%c\n",
514
       function,
515
       ( (fsfat_directory_entry_t *) data )->name[ 0 ],
516
       ( (fsfat_directory_entry_t *) data )->name[ 1 ],
517
       ( (fsfat_directory_entry_t *) data )->name[ 2 ],
518
       ( (fsfat_directory_entry_t *) data )->name[ 3 ],
519
       ( (fsfat_directory_entry_t *) data )->name[ 4 ],
520
       ( (fsfat_directory_entry_t *) data )->name[ 5 ],
521
       ( (fsfat_directory_entry_t *) data )->name[ 6 ],
522
       ( (fsfat_directory_entry_t *) data )->name[ 7 ] );
523
524
      libcnotify_printf(
525
       "%s: extension\t\t\t\t: %c%c%c\n",
526
       function,
527
       ( (fsfat_directory_entry_t *) data )->extension[ 0 ],
528
       ( (fsfat_directory_entry_t *) data )->extension[ 1 ],
529
       ( (fsfat_directory_entry_t *) data )->extension[ 2 ] );
530
531
      libcnotify_printf(
532
       "%s: file attribute flags\t\t: 0x%02" PRIx16 "\n",
533
       function,
534
       directory_entry->file_attribute_flags );
535
      libfsfat_debug_print_file_attribute_flags(
536
       directory_entry->file_attribute_flags );
537
      libcnotify_printf(
538
       "\n" );
539
540
      libcnotify_printf(
541
       "%s: unknown1\t\t\t\t: 0x%02" PRIx8 "\n",
542
       function,
543
       ( (fsfat_directory_entry_t *) data )->unknown1 );
544
545
      if( libfsfat_debug_print_fat_date_time_value(
546
           function,
547
           "creation time\t\t\t",
548
           directory_entry->creation_date,
549
           directory_entry->creation_time,
550
           directory_entry->creation_time_fraction,
551
           0,
552
           LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME,
553
           error ) != 1 )
554
      {
555
        libcerror_error_set(
556
         error,
557
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
558
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
559
         "%s: unable to print FAT date time value.",
560
         function );
561
562
        return( -1 );
563
      }
564
      if( libfsfat_debug_print_fat_date_time_value(
565
           function,
566
           "access time\t\t\t\t",
567
           directory_entry->access_date,
568
           0,
569
           0,
570
           0,
571
           LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME,
572
           error ) != 1 )
573
      {
574
        libcerror_error_set(
575
         error,
576
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
577
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
578
         "%s: unable to print FAT date time value.",
579
         function );
580
581
        return( -1 );
582
      }
583
      byte_stream_copy_to_uint16_little_endian(
584
       ( (fsfat_directory_entry_t *) data )->unknown3,
585
       value_16bit );
586
      libcnotify_printf(
587
       "%s: unknown3\t\t\t\t: 0x%04" PRIx16 "\n",
588
       function,
589
       value_16bit );
590
591
      if( libfsfat_debug_print_fat_date_time_value(
592
           function,
593
           "modification time\t\t\t",
594
           directory_entry->modification_date,
595
           directory_entry->modification_time,
596
           0,
597
           0,
598
           LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME,
599
           error ) != 1 )
600
      {
601
        libcerror_error_set(
602
         error,
603
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
604
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
605
         "%s: unable to print FAT date time value.",
606
         function );
607
608
        return( -1 );
609
      }
610
      libcnotify_printf(
611
       "%s: data start cluster\t\t\t: %" PRIu32 "\n",
612
       function,
613
       directory_entry->data_start_cluster );
614
615
      libcnotify_printf(
616
       "%s: data size\t\t\t\t: %" PRIu64 "\n",
617
       function,
618
       directory_entry->data_size );
619
620
      libcnotify_printf(
621
       "\n" );
622
    }
623
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
624
648k
  }
625
153k
  else if( directory_entry->entry_type == LIBFSFAT_DIRECTORY_ENTRY_TYPE_VFAT_LONG_NAME )
626
7.90k
  {
627
7.90k
    directory_entry->vfat_sequence_number = ( (fsfat_directory_entry_vfat_t *) data )->sequence_number;
628
629
7.90k
    if( memory_copy(
630
7.90k
         directory_entry->name_data,
631
7.90k
         ( (fsfat_directory_entry_vfat_t *) data )->first_name_segment,
632
7.90k
         10 ) == NULL )
633
0
    {
634
0
      libcerror_error_set(
635
0
       error,
636
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
637
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
638
0
       "%s: unable to copy first name segment.",
639
0
       function );
640
641
0
      return( -1 );
642
0
    }
643
7.90k
    if( memory_copy(
644
7.90k
         &( directory_entry->name_data[ 10 ] ),
645
7.90k
         ( (fsfat_directory_entry_vfat_t *) data )->second_name_segment,
646
7.90k
         12 ) == NULL )
647
0
    {
648
0
      libcerror_error_set(
649
0
       error,
650
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
651
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
652
0
       "%s: unable to copy second name segment.",
653
0
       function );
654
655
0
      return( -1 );
656
0
    }
657
7.90k
    if( memory_copy(
658
7.90k
         &( directory_entry->name_data[ 10 + 12 ] ),
659
7.90k
         ( (fsfat_directory_entry_vfat_t *) data )->third_name_segment,
660
7.90k
         4 ) == NULL )
661
0
    {
662
0
      libcerror_error_set(
663
0
       error,
664
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
665
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
666
0
       "%s: unable to copy third name segment.",
667
0
       function );
668
669
0
      return( -1 );
670
0
    }
671
#if defined( HAVE_DEBUG_OUTPUT )
672
    if( libcnotify_verbose != 0 )
673
    {
674
      libcnotify_printf(
675
       "%s: VFAT sequence number\t\t: 0x%02" PRIx8 " (%" PRIu8 ")\n",
676
       function,
677
       ( (fsfat_directory_entry_vfat_t *) data )->sequence_number,
678
       ( (fsfat_directory_entry_vfat_t *) data )->sequence_number & 0x1f );
679
680
      libcnotify_printf(
681
       "%s: first name segment:\n",
682
       function );
683
      libcnotify_print_data(
684
       ( (fsfat_directory_entry_vfat_t *) data )->first_name_segment,
685
       10,
686
       0 );
687
688
      libcnotify_printf(
689
       "%s: unknown1\t\t\t\t: 0x%02" PRIx8 "\n",
690
       function,
691
       ( (fsfat_directory_entry_vfat_t *) data )->unknown1 );
692
693
      libcnotify_printf(
694
       "%s: unknown2\t\t\t\t: 0x%02" PRIx8 "\n",
695
       function,
696
       ( (fsfat_directory_entry_vfat_t *) data )->unknown2 );
697
698
      libcnotify_printf(
699
       "%s: name checksum\t\t\t: 0x%02" PRIx8 "\n",
700
       function,
701
       ( (fsfat_directory_entry_vfat_t *) data )->name_checksum );
702
703
      libcnotify_printf(
704
       "%s: second name segment:\n",
705
       function );
706
      libcnotify_print_data(
707
       ( (fsfat_directory_entry_vfat_t *) data )->second_name_segment,
708
       12,
709
       0 );
710
711
      byte_stream_copy_to_uint16_little_endian(
712
       ( (fsfat_directory_entry_vfat_t *) data )->unknown3,
713
       value_16bit );
714
      libcnotify_printf(
715
       "%s: unknown3\t\t\t\t: 0x%04" PRIx16 "\n",
716
       function,
717
       value_16bit );
718
719
      libcnotify_printf(
720
       "%s: third name segment:\n",
721
       function );
722
      libcnotify_print_data(
723
       ( (fsfat_directory_entry_vfat_t *) data )->third_name_segment,
724
       4,
725
       0 );
726
    }
727
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
728
7.90k
  }
729
145k
  else if( directory_entry->entry_type == LIBFSFAT_DIRECTORY_ENTRY_TYPE_EXFAT_ALLOCATION_BITMAP )
730
759
  {
731
#if defined( HAVE_DEBUG_OUTPUT )
732
    if( libcnotify_verbose != 0 )
733
    {
734
      libcnotify_printf(
735
       "%s: entry type\t\t\t\t: 0x%02" PRIx8 " (%s)\n",
736
       function,
737
       ( (fsfat_directory_entry_exfat_allocation_bitmap_t *) data )->entry_type,
738
       libfsfat_debug_print_exfat_directory_entry_type(
739
        ( (fsfat_directory_entry_exfat_allocation_bitmap_t *) data )->entry_type ) );
740
741
      libcnotify_printf(
742
       "%s: bitmap flags\t\t\t: 0x%02" PRIx8 "\n",
743
       function,
744
       ( (fsfat_directory_entry_exfat_allocation_bitmap_t *) data )->bitmap_flags );
745
746
      libcnotify_printf(
747
       "%s: unknown1:\n",
748
       function );
749
      libcnotify_print_data(
750
       ( (fsfat_directory_entry_exfat_allocation_bitmap_t *) data )->unknown1,
751
       18,
752
       0 );
753
754
      byte_stream_copy_to_uint32_little_endian(
755
       ( (fsfat_directory_entry_exfat_allocation_bitmap_t *) data )->data_start_cluster,
756
       value_32bit );
757
      libcnotify_printf(
758
       "%s: data start cluster\t\t\t: %" PRIu32 "\n",
759
       function,
760
       value_32bit );
761
762
      byte_stream_copy_to_uint64_little_endian(
763
       ( (fsfat_directory_entry_exfat_allocation_bitmap_t *) data )->data_size,
764
       value_64bit );
765
      libcnotify_printf(
766
       "%s: data size\t\t\t\t: %" PRIu64 "\n",
767
       function,
768
       value_64bit );
769
770
      libcnotify_printf(
771
       "\n" );
772
    }
773
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
774
759
  }
775
144k
  else if( directory_entry->entry_type == LIBFSFAT_DIRECTORY_ENTRY_TYPE_EXFAT_DATA_STREAM )
776
637
  {
777
637
    directory_entry->name_size = ( (fsfat_directory_entry_exfat_volume_label_t *) data )->name_size;
778
779
637
    byte_stream_copy_to_uint64_little_endian(
780
637
     ( (fsfat_directory_entry_exfat_data_stream_t *) data )->valid_data_size,
781
637
     directory_entry->valid_data_size );
782
783
637
    byte_stream_copy_to_uint32_little_endian(
784
637
     ( (fsfat_directory_entry_exfat_data_stream_t *) data )->data_start_cluster,
785
637
     directory_entry->data_start_cluster );
786
787
637
    byte_stream_copy_to_uint64_little_endian(
788
637
     ( (fsfat_directory_entry_exfat_data_stream_t *) data )->data_size,
789
637
     directory_entry->data_size );
790
791
#if defined( HAVE_DEBUG_OUTPUT )
792
    if( libcnotify_verbose != 0 )
793
    {
794
      libcnotify_printf(
795
       "%s: entry type\t\t\t\t: 0x%02" PRIx8 " (%s)\n",
796
       function,
797
       ( (fsfat_directory_entry_exfat_allocation_bitmap_t *) data )->entry_type,
798
       libfsfat_debug_print_exfat_directory_entry_type(
799
        ( (fsfat_directory_entry_exfat_allocation_bitmap_t *) data )->entry_type ) );
800
801
      libcnotify_printf(
802
       "%s: unknown1\t\t\t\t: 0x%02" PRIx8 "\n",
803
       function,
804
       ( (fsfat_directory_entry_exfat_data_stream_t *) data )->unknown1 );
805
806
      libcnotify_printf(
807
       "%s: unknown2\t\t\t\t: 0x%02" PRIx8 "\n",
808
       function,
809
       ( (fsfat_directory_entry_exfat_data_stream_t *) data )->unknown2 );
810
811
      libcnotify_printf(
812
       "%s: name size\t\t\t\t: %" PRIu16 " (%" PRIu8 " characters)\n",
813
       function,
814
       (uint16_t) ( (fsfat_directory_entry_exfat_data_stream_t *) data )->name_size * 2,
815
       ( (fsfat_directory_entry_exfat_data_stream_t *) data )->name_size );
816
817
      byte_stream_copy_to_uint16_little_endian(
818
       ( (fsfat_directory_entry_exfat_data_stream_t *) data )->name_hash,
819
       value_16bit );
820
      libcnotify_printf(
821
       "%s: name hash\t\t\t\t: 0x%04" PRIx16 "\n",
822
       function,
823
       value_16bit );
824
825
      byte_stream_copy_to_uint16_little_endian(
826
       ( (fsfat_directory_entry_exfat_data_stream_t *) data )->unknown3,
827
       value_16bit );
828
      libcnotify_printf(
829
       "%s: unknown3\t\t\t\t: 0x%04" PRIx16 "\n",
830
       function,
831
       value_16bit );
832
833
      byte_stream_copy_to_uint32_little_endian(
834
       ( (fsfat_directory_entry_exfat_data_stream_t *) data )->unknown4,
835
       value_32bit );
836
      libcnotify_printf(
837
       "%s: unknown4\t\t\t\t: 0x%08" PRIx32 "\n",
838
       function,
839
       value_32bit );
840
841
      libcnotify_printf(
842
       "%s: valid data size\t\t\t: %" PRIu64 "\n",
843
       function,
844
       directory_entry->valid_data_size );
845
846
      libcnotify_printf(
847
       "%s: data start cluster\t\t\t: %" PRIu32 "\n",
848
       function,
849
       directory_entry->data_start_cluster );
850
851
      libcnotify_printf(
852
       "%s: data size\t\t\t\t: %" PRIu64 "\n",
853
       function,
854
       directory_entry->data_size );
855
856
      libcnotify_printf(
857
       "\n" );
858
    }
859
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
860
861
637
    directory_entry->name_size *= 2;
862
637
  }
863
143k
  else if( directory_entry->entry_type == LIBFSFAT_DIRECTORY_ENTRY_TYPE_EXFAT_FILE_ENTRY )
864
2.09k
  {
865
2.09k
    byte_stream_copy_to_uint16_little_endian(
866
2.09k
     ( (fsfat_directory_entry_exfat_file_entry_t *) data )->file_attribute_flags,
867
2.09k
     directory_entry->file_attribute_flags );
868
869
2.09k
    byte_stream_copy_to_uint16_little_endian(
870
2.09k
     ( (fsfat_directory_entry_exfat_file_entry_t *) data )->creation_date,
871
2.09k
     directory_entry->creation_date );
872
873
2.09k
    byte_stream_copy_to_uint16_little_endian(
874
2.09k
     ( (fsfat_directory_entry_exfat_file_entry_t *) data )->creation_time,
875
2.09k
     directory_entry->creation_time );
876
877
2.09k
    byte_stream_copy_to_uint16_little_endian(
878
2.09k
     ( (fsfat_directory_entry_exfat_file_entry_t *) data )->modification_date,
879
2.09k
     directory_entry->modification_date );
880
881
2.09k
    byte_stream_copy_to_uint16_little_endian(
882
2.09k
     ( (fsfat_directory_entry_exfat_file_entry_t *) data )->modification_time,
883
2.09k
     directory_entry->modification_time );
884
885
2.09k
    byte_stream_copy_to_uint16_little_endian(
886
2.09k
     ( (fsfat_directory_entry_exfat_file_entry_t *) data )->access_date,
887
2.09k
     directory_entry->access_date );
888
889
2.09k
    byte_stream_copy_to_uint16_little_endian(
890
2.09k
     ( (fsfat_directory_entry_exfat_file_entry_t *) data )->access_time,
891
2.09k
     directory_entry->access_time );
892
893
2.09k
    directory_entry->creation_time_fraction = ( (fsfat_directory_entry_exfat_file_entry_t *) data )->creation_time_fraction;
894
895
2.09k
    directory_entry->modification_time_fraction = ( (fsfat_directory_entry_exfat_file_entry_t *) data )->modification_time_fraction;
896
897
2.09k
    directory_entry->creation_time_utc_offset = ( (fsfat_directory_entry_exfat_file_entry_t *) data )->creation_time_utc_offset;
898
899
2.09k
    directory_entry->access_time_utc_offset = ( (fsfat_directory_entry_exfat_file_entry_t *) data )->access_time_utc_offset;
900
901
2.09k
    directory_entry->modification_time_utc_offset = ( (fsfat_directory_entry_exfat_file_entry_t *) data )->modification_time_utc_offset;
902
903
#if defined( HAVE_DEBUG_OUTPUT )
904
    if( libcnotify_verbose != 0 )
905
    {
906
      libcnotify_printf(
907
       "%s: entry type\t\t\t\t: 0x%02" PRIx8 " (%s)\n",
908
       function,
909
       ( (fsfat_directory_entry_exfat_allocation_bitmap_t *) data )->entry_type,
910
       libfsfat_debug_print_exfat_directory_entry_type(
911
        ( (fsfat_directory_entry_exfat_allocation_bitmap_t *) data )->entry_type ) );
912
913
      libcnotify_printf(
914
       "%s: unknown1\t\t\t\t: 0x%02" PRIx8 "\n",
915
       function,
916
       ( (fsfat_directory_entry_exfat_file_entry_t *) data )->unknown1 );
917
918
      byte_stream_copy_to_uint16_little_endian(
919
       ( (fsfat_directory_entry_exfat_file_entry_t *) data )->unknown2,
920
       value_16bit );
921
      libcnotify_printf(
922
       "%s: unknown2\t\t\t\t: 0x%04" PRIx16 "\n",
923
       function,
924
       value_16bit );
925
926
      libcnotify_printf(
927
       "%s: file attribute flags\t\t: 0x%02" PRIx16 "\n",
928
       function,
929
       directory_entry->file_attribute_flags );
930
      libfsfat_debug_print_file_attribute_flags(
931
       directory_entry->file_attribute_flags );
932
      libcnotify_printf(
933
       "\n" );
934
935
      if( libfsfat_debug_print_fat_date_time_value(
936
           function,
937
           "creation time\t\t\t",
938
           directory_entry->creation_date,
939
           directory_entry->creation_time,
940
           directory_entry->creation_time_fraction,
941
           directory_entry->creation_time_utc_offset,
942
           LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME,
943
           error ) != 1 )
944
      {
945
        libcerror_error_set(
946
         error,
947
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
948
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
949
         "%s: unable to print FAT date time value.",
950
         function );
951
952
        return( -1 );
953
      }
954
      if( libfsfat_debug_print_fat_date_time_value(
955
           function,
956
           "modification time\t\t\t",
957
           directory_entry->modification_date,
958
           directory_entry->modification_time,
959
           directory_entry->modification_time_fraction,
960
           directory_entry->modification_time_utc_offset,
961
           LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME,
962
           error ) != 1 )
963
      {
964
        libcerror_error_set(
965
         error,
966
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
967
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
968
         "%s: unable to print FAT date time value.",
969
         function );
970
971
        return( -1 );
972
      }
973
      if( libfsfat_debug_print_fat_date_time_value(
974
           function,
975
           "access time\t\t\t\t",
976
           directory_entry->access_date,
977
           directory_entry->access_time,
978
           0,
979
           directory_entry->access_time_utc_offset,
980
           LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME,
981
           error ) != 1 )
982
      {
983
        libcerror_error_set(
984
         error,
985
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
986
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
987
         "%s: unable to print FAT date time value.",
988
         function );
989
990
        return( -1 );
991
      }
992
      libcnotify_printf(
993
       "%s: unknown4:\n",
994
       function );
995
      libcnotify_print_data(
996
       ( (fsfat_directory_entry_exfat_file_entry_t *) data )->unknown4,
997
       7,
998
       0 );
999
    }
1000
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1001
2.09k
  }
1002
141k
  else if( directory_entry->entry_type == LIBFSFAT_DIRECTORY_ENTRY_TYPE_EXFAT_FILE_ENTRY_NAME )
1003
2.83k
  {
1004
2.83k
    if( memory_copy(
1005
2.83k
         directory_entry->name_data,
1006
2.83k
         ( (fsfat_directory_entry_exfat_file_entry_name_t *) data )->name,
1007
2.83k
         30 ) == NULL )
1008
0
    {
1009
0
      libcerror_error_set(
1010
0
       error,
1011
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1012
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1013
0
       "%s: unable to copy exFAT file entry name.",
1014
0
       function );
1015
1016
0
      return( -1 );
1017
0
    }
1018
#if defined( HAVE_DEBUG_OUTPUT )
1019
    if( libcnotify_verbose != 0 )
1020
    {
1021
      libcnotify_printf(
1022
       "%s: entry type\t\t\t\t: 0x%02" PRIx8 " (%s)\n",
1023
       function,
1024
       ( (fsfat_directory_entry_exfat_allocation_bitmap_t *) data )->entry_type,
1025
       libfsfat_debug_print_exfat_directory_entry_type(
1026
        ( (fsfat_directory_entry_exfat_allocation_bitmap_t *) data )->entry_type ) );
1027
1028
      libcnotify_printf(
1029
       "%s: unknown1\t\t\t\t: 0x%02" PRIx8 "\n",
1030
       function,
1031
       ( (fsfat_directory_entry_exfat_file_entry_name_t *) data )->unknown1 );
1032
1033
      libcnotify_printf(
1034
       "%s: name data:\n",
1035
       function );
1036
      libcnotify_print_data(
1037
       ( (fsfat_directory_entry_exfat_file_entry_name_t *) data )->name,
1038
       30,
1039
       0 );
1040
    }
1041
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1042
2.83k
  }
1043
139k
  else if( directory_entry->entry_type == LIBFSFAT_DIRECTORY_ENTRY_TYPE_EXFAT_VOLUME_LABEL )
1044
26
  {
1045
26
    if( memory_copy(
1046
26
         directory_entry->name_data,
1047
26
         ( (fsfat_directory_entry_exfat_volume_label_t *) data )->name,
1048
26
         22 ) == NULL )
1049
0
    {
1050
0
      libcerror_error_set(
1051
0
       error,
1052
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1053
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1054
0
       "%s: unable to copy exFAT volume label name.",
1055
0
       function );
1056
1057
0
      return( -1 );
1058
0
    }
1059
26
    directory_entry->name_size = ( (fsfat_directory_entry_exfat_volume_label_t *) data )->name_size;
1060
1061
#if defined( HAVE_DEBUG_OUTPUT )
1062
    if( libcnotify_verbose != 0 )
1063
    {
1064
      libcnotify_printf(
1065
       "%s: entry type\t\t\t\t: 0x%02" PRIx8 " (%s)\n",
1066
       function,
1067
       ( (fsfat_directory_entry_exfat_allocation_bitmap_t *) data )->entry_type,
1068
       libfsfat_debug_print_exfat_directory_entry_type(
1069
        ( (fsfat_directory_entry_exfat_allocation_bitmap_t *) data )->entry_type ) );
1070
1071
      libcnotify_printf(
1072
       "%s: name size\t\t\t\t: %" PRIu16 " (%" PRIu8 " characters)\n",
1073
       function,
1074
       (uint16_t) ( (fsfat_directory_entry_exfat_volume_label_t *) data )->name_size * 2,
1075
       ( (fsfat_directory_entry_exfat_volume_label_t *) data )->name_size );
1076
1077
      libcnotify_printf(
1078
       "%s: name data:\n",
1079
       function );
1080
      libcnotify_print_data(
1081
       ( (fsfat_directory_entry_exfat_volume_label_t *) data )->name,
1082
       22,
1083
       0 );
1084
1085
      libcnotify_printf(
1086
       "%s: unknown1:\n",
1087
       function );
1088
      libcnotify_print_data(
1089
       ( (fsfat_directory_entry_exfat_volume_label_t *) data )->unknown1,
1090
       8,
1091
       0 );
1092
    }
1093
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1094
1095
26
    if( directory_entry->name_size > 11 )
1096
9
    {
1097
9
      libcerror_error_set(
1098
9
       error,
1099
9
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1100
9
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1101
9
       "%s: invalid exFAT volume label name size value out of bounds.",
1102
9
       function );
1103
1104
9
      return( -1 );
1105
9
    }
1106
17
    directory_entry->name_size *= 2;
1107
17
  }
1108
801k
  return( 1 );
1109
801k
}
1110
1111
/* Reads a directory entry
1112
 * Returns 1 if successful, 0 if empty or -1 on error
1113
 */
1114
int libfsfat_directory_entry_read_file_io_handle(
1115
     libfsfat_directory_entry_t *directory_entry,
1116
     libbfio_handle_t *file_io_handle,
1117
     off64_t file_offset,
1118
     uint8_t file_system_format,
1119
     libcerror_error_t **error )
1120
802k
{
1121
802k
  uint8_t directory_entry_data[ sizeof( fsfat_directory_entry_t ) ];
1122
1123
802k
  static char *function = "libfsfat_directory_entry_read_file_io_handle";
1124
802k
  ssize_t read_count    = 0;
1125
802k
  int result            = 0;
1126
1127
802k
  if( directory_entry == NULL )
1128
0
  {
1129
0
    libcerror_error_set(
1130
0
     error,
1131
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1132
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1133
0
     "%s: invalid directory entry.",
1134
0
     function );
1135
1136
0
    return( -1 );
1137
0
  }
1138
#if defined( HAVE_DEBUG_OUTPUT )
1139
  if( libcnotify_verbose != 0 )
1140
  {
1141
    libcnotify_printf(
1142
     "%s: reading directory entry at offset: %" PRIi64 " (0x%08" PRIx64 ").\n",
1143
     function,
1144
     file_offset,
1145
     file_offset );
1146
  }
1147
#endif
1148
802k
  read_count = libbfio_handle_read_buffer_at_offset(
1149
802k
                file_io_handle,
1150
802k
                directory_entry_data,
1151
802k
                sizeof( fsfat_directory_entry_t ),
1152
802k
                file_offset,
1153
802k
                error );
1154
1155
802k
  if( read_count != (ssize_t) sizeof( fsfat_directory_entry_t ) )
1156
684
  {
1157
684
    libcerror_error_set(
1158
684
     error,
1159
684
     LIBCERROR_ERROR_DOMAIN_IO,
1160
684
     LIBCERROR_IO_ERROR_READ_FAILED,
1161
684
     "%s: unable to read directory entry data at offset: %" PRIi64 " (0x%08" PRIx64 ").",
1162
684
     function,
1163
684
     file_offset,
1164
684
     file_offset );
1165
1166
684
    return( -1 );
1167
684
  }
1168
801k
  result = libfsfat_directory_entry_read_data(
1169
801k
            directory_entry,
1170
801k
            directory_entry_data,
1171
801k
            sizeof( fsfat_directory_entry_t ),
1172
801k
            file_system_format,
1173
801k
            error );
1174
1175
801k
  if( result == -1 )
1176
9
  {
1177
9
    libcerror_error_set(
1178
9
     error,
1179
9
     LIBCERROR_ERROR_DOMAIN_IO,
1180
9
     LIBCERROR_IO_ERROR_READ_FAILED,
1181
9
     "%s: unable to read directory entry.",
1182
9
     function );
1183
1184
9
    return( -1 );
1185
9
  }
1186
801k
  return( result );
1187
801k
}
1188
1189
/* Retrieves the identifier
1190
 * The identifier is the offset of the short name directory entry
1191
 * Returns 1 if successful or -1 on error
1192
 */
1193
int libfsfat_directory_entry_get_identifier(
1194
     libfsfat_directory_entry_t *directory_entry,
1195
     uint64_t *identifier,
1196
     libcerror_error_t **error )
1197
160
{
1198
160
  static char *function = "libfsfat_directory_entry_get_identifier";
1199
1200
160
  if( directory_entry == NULL )
1201
0
  {
1202
0
    libcerror_error_set(
1203
0
     error,
1204
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1205
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1206
0
     "%s: invalid directory entry.",
1207
0
     function );
1208
1209
0
    return( -1 );
1210
0
  }
1211
160
  if( identifier == NULL )
1212
0
  {
1213
0
    libcerror_error_set(
1214
0
     error,
1215
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1216
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1217
0
     "%s: invalid identifier.",
1218
0
     function );
1219
1220
0
    return( -1 );
1221
0
  }
1222
160
  *identifier = directory_entry->identifier;
1223
1224
160
  return( 1 );
1225
160
}
1226
1227
/* Retrieves the access date and time
1228
 * The timestamp is an unsigned 64-bit integer containing the 10 milli seconds intervals since January 1, 1980
1229
 * Returns 1 if successful or -1 on error
1230
 */
1231
int libfsfat_directory_entry_get_access_time(
1232
     libfsfat_directory_entry_t *directory_entry,
1233
     uint64_t *fat_timestamp,
1234
     libcerror_error_t **error )
1235
0
{
1236
0
  static char *function = "libfsfat_directory_entry_get_access_time";
1237
1238
0
  if( directory_entry == NULL )
1239
0
  {
1240
0
    libcerror_error_set(
1241
0
     error,
1242
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1243
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1244
0
     "%s: invalid directory entry.",
1245
0
     function );
1246
1247
0
    return( -1 );
1248
0
  }
1249
0
  if( libfsfat_date_time_get_timestamp(
1250
0
       directory_entry->access_date,
1251
0
       directory_entry->access_time,
1252
0
       0,
1253
0
       directory_entry->access_time_utc_offset,
1254
0
       fat_timestamp,
1255
0
       error ) != 1 )
1256
0
  {
1257
0
    libcerror_error_set(
1258
0
     error,
1259
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1260
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1261
0
     "%s: unable to retrieve access timestamp.",
1262
0
     function );
1263
1264
0
    return( -1 );
1265
0
  }
1266
0
  return( 1 );
1267
0
}
1268
1269
/* Retrieves the creation date and time
1270
 * The timestamp is an unsigned 64-bit integer containing the 10 milli seconds intervals since January 1, 1980
1271
 * Returns 1 if successful or -1 on error
1272
 */
1273
int libfsfat_directory_entry_get_creation_time(
1274
     libfsfat_directory_entry_t *directory_entry,
1275
     uint64_t *fat_timestamp,
1276
     libcerror_error_t **error )
1277
0
{
1278
0
  static char *function = "libfsfat_directory_entry_get_creation_time";
1279
1280
0
  if( directory_entry == NULL )
1281
0
  {
1282
0
    libcerror_error_set(
1283
0
     error,
1284
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1285
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1286
0
     "%s: invalid directory entry.",
1287
0
     function );
1288
1289
0
    return( -1 );
1290
0
  }
1291
0
  if( libfsfat_date_time_get_timestamp(
1292
0
       directory_entry->creation_date,
1293
0
       directory_entry->creation_time,
1294
0
       directory_entry->creation_time_fraction,
1295
0
       directory_entry->creation_time_utc_offset,
1296
0
       fat_timestamp,
1297
0
       error ) != 1 )
1298
0
  {
1299
0
    libcerror_error_set(
1300
0
     error,
1301
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1302
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1303
0
     "%s: unable to retrieve creation timestamp.",
1304
0
     function );
1305
1306
0
    return( -1 );
1307
0
  }
1308
0
  return( 1 );
1309
0
}
1310
1311
/* Retrieves the modification date and time
1312
 * The timestamp is an unsigned 64-bit integer containing the 10 milli seconds intervals since January 1, 1980
1313
 * Returns 1 if successful or -1 on error
1314
 */
1315
int libfsfat_directory_entry_get_modification_time(
1316
     libfsfat_directory_entry_t *directory_entry,
1317
     uint64_t *fat_timestamp,
1318
     libcerror_error_t **error )
1319
0
{
1320
0
  static char *function = "libfsfat_directory_entry_get_modification_time";
1321
1322
0
  if( directory_entry == NULL )
1323
0
  {
1324
0
    libcerror_error_set(
1325
0
     error,
1326
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1327
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1328
0
     "%s: invalid directory entry.",
1329
0
     function );
1330
1331
0
    return( -1 );
1332
0
  }
1333
0
  if( libfsfat_date_time_get_timestamp(
1334
0
       directory_entry->modification_date,
1335
0
       directory_entry->modification_time,
1336
0
       directory_entry->modification_time_fraction,
1337
0
       directory_entry->modification_time_utc_offset,
1338
0
       fat_timestamp,
1339
0
       error ) != 1 )
1340
0
  {
1341
0
    libcerror_error_set(
1342
0
     error,
1343
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1344
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1345
0
     "%s: unable to retrieve modification timestamp.",
1346
0
     function );
1347
1348
0
    return( -1 );
1349
0
  }
1350
0
  return( 1 );
1351
0
}
1352
1353
/* Retrieves the file attribute flags
1354
 * Returns 1 if successful or -1 on error
1355
 */
1356
int libfsfat_directory_entry_get_file_attribute_flags(
1357
     libfsfat_directory_entry_t *directory_entry,
1358
     uint16_t *file_attribute_flags,
1359
     libcerror_error_t **error )
1360
146
{
1361
146
  static char *function = "libfsfat_directory_entry_get_file_attribute_flags";
1362
1363
146
  if( directory_entry == NULL )
1364
0
  {
1365
0
    libcerror_error_set(
1366
0
     error,
1367
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1368
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1369
0
     "%s: invalid directory entry.",
1370
0
     function );
1371
1372
0
    return( -1 );
1373
0
  }
1374
146
  if( file_attribute_flags == NULL )
1375
0
  {
1376
0
    libcerror_error_set(
1377
0
     error,
1378
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1379
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1380
0
     "%s: invalid file attribute flags.",
1381
0
     function );
1382
1383
0
    return( -1 );
1384
0
  }
1385
146
  *file_attribute_flags = directory_entry->file_attribute_flags;
1386
1387
146
  return( 1 );
1388
146
}
1389
1390
/* Determines the name
1391
 * Returns 1 if successful or -1 on error
1392
 */
1393
int libfsfat_directory_entry_get_name(
1394
     libfsfat_directory_entry_t *directory_entry,
1395
     libcerror_error_t **error )
1396
159
{
1397
159
  static char *function   = "libfsfat_directory_entry_get_name";
1398
159
  size_t name_data_offset = 0;
1399
159
  size_t name_offset      = 0;
1400
159
  size_t name_size        = 0;
1401
1402
159
  if( directory_entry == NULL )
1403
0
  {
1404
0
    libcerror_error_set(
1405
0
     error,
1406
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1407
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1408
0
     "%s: invalid directory entry.",
1409
0
     function );
1410
1411
0
    return( -1 );
1412
0
  }
1413
159
  if( directory_entry->name != NULL )
1414
0
  {
1415
0
    libcerror_error_set(
1416
0
     error,
1417
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1418
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1419
0
     "%s: invalid directory entry - name value already set.",
1420
0
     function );
1421
1422
0
    return( -1 );
1423
0
  }
1424
159
  if( directory_entry->name_entries_array != NULL )
1425
97
  {
1426
97
    if( libfsfat_directory_entry_get_name_from_exfat_file_name_entries(
1427
97
         directory_entry,
1428
97
         directory_entry->name_entries_array,
1429
97
         error ) != 1 )
1430
14
    {
1431
14
      libcerror_error_set(
1432
14
       error,
1433
14
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1434
14
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1435
14
       "%s: unable to determine name from exFAT file name entries.",
1436
14
       function );
1437
1438
14
      goto on_error;
1439
14
    }
1440
97
  }
1441
62
  else if( directory_entry->entry_type == LIBFSFAT_DIRECTORY_ENTRY_TYPE_SHORT_NAME )
1442
62
  {
1443
62
    name_size = 8 + 3 + 1;
1444
1445
62
    if( ( directory_entry->file_attribute_flags & LIBFSFAT_FILE_ATTRIBUTE_FLAG_VOLUME_LABEL ) == 0 )
1446
61
    {
1447
61
      name_size += 1;
1448
61
    }
1449
62
    directory_entry->name = (uint8_t *) memory_allocate(
1450
62
                                         sizeof( uint8_t ) * name_size );
1451
1452
62
    if( directory_entry->name == NULL )
1453
0
    {
1454
0
      libcerror_error_set(
1455
0
       error,
1456
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1457
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1458
0
       "%s: unable to create name.",
1459
0
       function );
1460
1461
0
      goto on_error;
1462
0
    }
1463
62
    directory_entry->name_size = name_size;
1464
1465
62
    name_offset = 0;
1466
1467
62
    for( name_data_offset = 0;
1468
502
         name_data_offset < 8;
1469
440
         name_data_offset++ )
1470
452
    {
1471
452
      if( directory_entry->name_data[ name_data_offset ] == ' ' )
1472
12
      {
1473
12
        break;
1474
12
      }
1475
440
      directory_entry->name[ name_offset++ ] = directory_entry->name_data[ name_data_offset ];
1476
440
    }
1477
62
    for( name_data_offset = 8;
1478
239
         name_data_offset < 8 + 3;
1479
177
         name_data_offset++ )
1480
181
    {
1481
181
      if( directory_entry->name_data[ name_data_offset ] == ' ' )
1482
4
      {
1483
4
        break;
1484
4
      }
1485
177
      if( ( name_data_offset == 8 )
1486
60
       && ( ( directory_entry->file_attribute_flags & LIBFSFAT_FILE_ATTRIBUTE_FLAG_VOLUME_LABEL ) == 0 ) )
1487
59
      {
1488
59
        directory_entry->name[ name_offset++ ] = '.';
1489
59
      }
1490
177
      directory_entry->name[ name_offset++ ] = directory_entry->name_data[ name_data_offset ];
1491
177
    }
1492
62
    directory_entry->name[ name_offset++ ] = 0;
1493
62
    directory_entry->name_size             = name_offset;
1494
62
    directory_entry->is_unicode            = 0;
1495
1496
#if defined( HAVE_DEBUG_OUTPUT )
1497
    if( libcnotify_verbose != 0 )
1498
    {
1499
      libcnotify_printf(
1500
       "%s: name data:\n",
1501
       function );
1502
      libcnotify_print_data(
1503
       directory_entry->name,
1504
       directory_entry->name_size,
1505
       0 );
1506
    }
1507
#endif
1508
62
  }
1509
0
  else if( directory_entry->entry_type == LIBFSFAT_DIRECTORY_ENTRY_TYPE_EXFAT_VOLUME_LABEL )
1510
0
  {
1511
0
    name_offset = directory_entry->name_size;
1512
0
    name_size   = directory_entry->name_size + 2;
1513
1514
0
    directory_entry->name = (uint8_t *) memory_allocate(
1515
0
                                         sizeof( uint8_t ) * name_size );
1516
1517
0
    if( directory_entry->name == NULL )
1518
0
    {
1519
0
      libcerror_error_set(
1520
0
       error,
1521
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1522
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1523
0
       "%s: unable to create name.",
1524
0
       function );
1525
1526
0
      goto on_error;
1527
0
    }
1528
0
    if( memory_copy(
1529
0
         directory_entry->name,
1530
0
         directory_entry->name_data,
1531
0
         directory_entry->name_size ) == NULL )
1532
0
    {
1533
0
      libcerror_error_set(
1534
0
       error,
1535
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1536
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1537
0
       "%s: unable to volume label name: %d.",
1538
0
       function );
1539
1540
0
      goto on_error;
1541
0
    }
1542
0
    directory_entry->name[ name_offset ]     = 0;
1543
0
    directory_entry->name[ name_offset + 1 ] = 0;
1544
0
    directory_entry->name_size               = name_size;
1545
0
    directory_entry->is_unicode              = 1;
1546
1547
#if defined( HAVE_DEBUG_OUTPUT )
1548
    if( libcnotify_verbose != 0 )
1549
    {
1550
      libcnotify_printf(
1551
       "%s: name data:\n",
1552
       function );
1553
      libcnotify_print_data(
1554
       directory_entry->name,
1555
       directory_entry->name_size,
1556
       0 );
1557
    }
1558
#endif
1559
0
  }
1560
145
  return( 1 );
1561
1562
14
on_error:
1563
14
  if( directory_entry->name != NULL )
1564
0
  {
1565
0
    memory_free(
1566
0
     directory_entry->name );
1567
1568
0
    directory_entry->name = NULL;
1569
0
  }
1570
14
  directory_entry->name_size = 0;
1571
1572
14
  return( -1 );
1573
159
}
1574
1575
/* Determines the name from exFAT file name entries
1576
 * Returns 1 if successful or -1 on error
1577
 */
1578
int libfsfat_directory_entry_get_name_from_exfat_file_name_entries(
1579
     libfsfat_directory_entry_t *directory_entry,
1580
     libcdata_array_t *name_entries_array,
1581
     libcerror_error_t **error )
1582
97
{
1583
97
  libfsfat_directory_entry_t *name_directory_entry = NULL;
1584
97
  static char *function                            = "libfsfat_directory_entry_get_name_from_exfat_file_name_entries";
1585
97
  size_t name_offset                               = 0;
1586
97
  size_t name_size                                 = 0;
1587
97
  int entry_index                                  = 0;
1588
97
  int number_of_entries                            = 0;
1589
1590
97
  if( directory_entry == NULL )
1591
0
  {
1592
0
    libcerror_error_set(
1593
0
     error,
1594
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1595
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1596
0
     "%s: invalid directory entry.",
1597
0
     function );
1598
1599
0
    return( -1 );
1600
0
  }
1601
97
  if( directory_entry->name != NULL )
1602
0
  {
1603
0
    libcerror_error_set(
1604
0
     error,
1605
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1606
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1607
0
     "%s: invalid directory entry - name value already set.",
1608
0
     function );
1609
1610
0
    return( -1 );
1611
0
  }
1612
97
  if( libcdata_array_get_number_of_entries(
1613
97
       name_entries_array,
1614
97
       &number_of_entries,
1615
97
       error ) != 1 )
1616
0
  {
1617
0
    libcerror_error_set(
1618
0
     error,
1619
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1620
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1621
0
     "%s: unable to retrieve number of name entries.",
1622
0
     function );
1623
1624
0
    goto on_error;
1625
0
  }
1626
97
  if( ( number_of_entries == 0 )
1627
96
   || ( number_of_entries > 9 ) )
1628
14
  {
1629
14
    libcerror_error_set(
1630
14
     error,
1631
14
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1632
14
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1633
14
     "%s: invalid number of name entries value out of bounds.",
1634
14
     function );
1635
1636
14
    goto on_error;
1637
14
  }
1638
83
  name_size = ( (size_t) 30 * number_of_entries ) + 2;
1639
1640
83
  directory_entry->name = (uint8_t *) memory_allocate(
1641
83
                                       sizeof( uint8_t ) * name_size );
1642
1643
83
  if( directory_entry->name == NULL )
1644
0
  {
1645
0
    libcerror_error_set(
1646
0
     error,
1647
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1648
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1649
0
     "%s: unable to create name.",
1650
0
     function );
1651
1652
0
    goto on_error;
1653
0
  }
1654
83
  directory_entry->name_size = name_size;
1655
1656
83
  for( entry_index = 0;
1657
264
       entry_index < number_of_entries;
1658
181
       entry_index++ )
1659
181
  {
1660
181
    if( libcdata_array_get_entry_by_index(
1661
181
         name_entries_array,
1662
181
         entry_index,
1663
181
         (intptr_t **) &name_directory_entry,
1664
181
         error ) != 1 )
1665
0
    {
1666
0
      libcerror_error_set(
1667
0
       error,
1668
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1669
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1670
0
       "%s: unable to retrieve directory entry: %d from name entries array.",
1671
0
       function,
1672
0
       entry_index );
1673
1674
0
      goto on_error;
1675
0
    }
1676
181
    if( name_directory_entry == NULL )
1677
0
    {
1678
0
      libcerror_error_set(
1679
0
       error,
1680
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1681
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1682
0
       "%s: invalid name directory entry: %d.",
1683
0
       function,
1684
0
       entry_index );
1685
1686
0
      goto on_error;
1687
0
    }
1688
181
    if( memory_copy(
1689
181
         &( directory_entry->name[ name_offset ] ),
1690
181
         name_directory_entry->name_data,
1691
181
         30 ) == NULL )
1692
0
    {
1693
0
      libcerror_error_set(
1694
0
       error,
1695
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1696
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1697
0
       "%s: unable to copy name segment: %d.",
1698
0
       function );
1699
1700
0
      goto on_error;
1701
0
    }
1702
181
    name_offset += 30;
1703
181
  }
1704
83
  directory_entry->name[ name_offset++ ] = 0;
1705
83
  directory_entry->name[ name_offset++ ] = 0;
1706
1707
83
  for( name_offset = 0;
1708
1.82k
       ( name_offset + 1 ) < directory_entry->name_size;
1709
1.74k
       name_offset += 2 )
1710
1.82k
  {
1711
1.82k
    if( ( directory_entry->name[ name_offset ] == 0 )
1712
246
     && ( directory_entry->name[ name_offset + 1 ] == 0 ) )
1713
83
    {
1714
83
      name_offset += 2;
1715
83
      break;
1716
83
    }
1717
1.82k
  }
1718
83
  directory_entry->name_size  = name_offset;
1719
83
  directory_entry->is_unicode = 1;
1720
1721
#if defined( HAVE_DEBUG_OUTPUT )
1722
  if( libcnotify_verbose != 0 )
1723
  {
1724
    libcnotify_printf(
1725
     "%s: name data:\n",
1726
     function );
1727
    libcnotify_print_data(
1728
     directory_entry->name,
1729
     directory_entry->name_size,
1730
     0 );
1731
  }
1732
#endif
1733
83
  return( 1 );
1734
1735
14
on_error:
1736
14
  if( directory_entry->name != NULL )
1737
0
  {
1738
0
    memory_free(
1739
0
     directory_entry->name );
1740
1741
0
    directory_entry->name = NULL;
1742
0
  }
1743
14
  directory_entry->name_size = 0;
1744
1745
14
  return( -1 );
1746
83
}
1747
1748
/* Determines the name from VFAT long file name entries
1749
 * Returns 1 if successful or -1 on error
1750
 */
1751
int libfsfat_directory_entry_get_name_from_vfat_long_file_name_entries(
1752
     libfsfat_directory_entry_t *directory_entry,
1753
     libcdata_array_t *name_entries_array,
1754
     libcerror_error_t **error )
1755
2.99k
{
1756
2.99k
  libfsfat_directory_entry_t *name_directory_entry = NULL;
1757
2.99k
  static char *function                            = "libfsfat_directory_entry_get_name_from_vfat_long_file_name_entries";
1758
2.99k
  size_t name_offset                               = 0;
1759
2.99k
  size_t name_size                                 = 0;
1760
2.99k
  int entry_index                                  = 0;
1761
2.99k
  int number_of_entries                            = 0;
1762
1763
2.99k
  if( directory_entry == NULL )
1764
0
  {
1765
0
    libcerror_error_set(
1766
0
     error,
1767
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1768
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1769
0
     "%s: invalid directory entry.",
1770
0
     function );
1771
1772
0
    return( -1 );
1773
0
  }
1774
2.99k
  if( directory_entry->name != NULL )
1775
0
  {
1776
0
    libcerror_error_set(
1777
0
     error,
1778
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1779
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1780
0
     "%s: invalid directory entry - name value already set.",
1781
0
     function );
1782
1783
0
    return( -1 );
1784
0
  }
1785
2.99k
  if( libcdata_array_get_number_of_entries(
1786
2.99k
       name_entries_array,
1787
2.99k
       &number_of_entries,
1788
2.99k
       error ) != 1 )
1789
0
  {
1790
0
    libcerror_error_set(
1791
0
     error,
1792
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1793
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1794
0
     "%s: unable to retrieve number of long file name entries.",
1795
0
     function );
1796
1797
0
    goto on_error;
1798
0
  }
1799
2.99k
  if( ( number_of_entries == 0 )
1800
2.99k
   || ( number_of_entries > 10 ) )
1801
0
  {
1802
0
    libcerror_error_set(
1803
0
     error,
1804
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1805
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1806
0
     "%s: invalid number of long file name entries value out of bounds.",
1807
0
     function );
1808
1809
0
    goto on_error;
1810
0
  }
1811
2.99k
  name_size = ( (size_t) ( 10 + 12 + 4 ) * number_of_entries ) + 2;
1812
1813
2.99k
  directory_entry->name = (uint8_t *) memory_allocate(
1814
2.99k
                                       sizeof( uint8_t ) * name_size );
1815
1816
2.99k
  if( directory_entry->name == NULL )
1817
0
  {
1818
0
    libcerror_error_set(
1819
0
     error,
1820
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1821
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
1822
0
     "%s: unable to create name.",
1823
0
     function );
1824
1825
0
    goto on_error;
1826
0
  }
1827
2.99k
  directory_entry->name_size = name_size;
1828
1829
2.99k
  for( entry_index = number_of_entries - 1;
1830
7.13k
       entry_index >= 0;
1831
4.14k
       entry_index-- )
1832
4.14k
  {
1833
4.14k
    if( libcdata_array_get_entry_by_index(
1834
4.14k
         name_entries_array,
1835
4.14k
         entry_index,
1836
4.14k
         (intptr_t **) &name_directory_entry,
1837
4.14k
         error ) != 1 )
1838
0
    {
1839
0
      libcerror_error_set(
1840
0
       error,
1841
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1842
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1843
0
       "%s: unable to retrieve directory entry: %d from long file name entries array.",
1844
0
       function,
1845
0
       entry_index );
1846
1847
0
      goto on_error;
1848
0
    }
1849
4.14k
    if( name_directory_entry == NULL )
1850
0
    {
1851
0
      libcerror_error_set(
1852
0
       error,
1853
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1854
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1855
0
       "%s: invalid long file name directory entry: %d.",
1856
0
       function,
1857
0
       entry_index );
1858
1859
0
      goto on_error;
1860
0
    }
1861
4.14k
    if( memory_copy(
1862
4.14k
         &( directory_entry->name[ name_offset ] ),
1863
4.14k
         name_directory_entry->name_data,
1864
4.14k
         10 + 12 + 4 ) == NULL )
1865
0
    {
1866
0
      libcerror_error_set(
1867
0
       error,
1868
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1869
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1870
0
       "%s: unable to copy long file name segment: %d.",
1871
0
       function );
1872
1873
0
      goto on_error;
1874
0
    }
1875
4.14k
    name_offset += 10 + 12 + 4;
1876
4.14k
  }
1877
2.99k
  directory_entry->name[ name_offset++ ] = 0;
1878
2.99k
  directory_entry->name[ name_offset++ ] = 0;
1879
1880
/* TODO determine if name is UCS-2 or ASCII */
1881
1882
2.99k
  for( name_offset = 0;
1883
16.4k
       ( name_offset + 1 ) < directory_entry->name_size;
1884
13.4k
       name_offset += 2 )
1885
16.4k
  {
1886
16.4k
    if( ( directory_entry->name[ name_offset ] == 0 )
1887
6.85k
     && ( directory_entry->name[ name_offset + 1 ] == 0 ) )
1888
2.99k
    {
1889
2.99k
      name_offset += 2;
1890
2.99k
      break;
1891
2.99k
    }
1892
16.4k
  }
1893
2.99k
  directory_entry->name_size  = name_offset;
1894
2.99k
  directory_entry->is_unicode = 1;
1895
1896
#if defined( HAVE_DEBUG_OUTPUT )
1897
  if( libcnotify_verbose != 0 )
1898
  {
1899
    libcnotify_printf(
1900
     "%s: name data:\n",
1901
     function );
1902
    libcnotify_print_data(
1903
     directory_entry->name,
1904
     directory_entry->name_size,
1905
     0 );
1906
  }
1907
#endif
1908
2.99k
  return( 1 );
1909
1910
0
on_error:
1911
0
  if( directory_entry->name != NULL )
1912
0
  {
1913
0
    memory_free(
1914
0
     directory_entry->name );
1915
1916
0
    directory_entry->name = NULL;
1917
0
  }
1918
0
  directory_entry->name_size = 0;
1919
1920
0
  return( -1 );
1921
2.99k
}
1922
1923
/* Retrieves the size of the UTF-8 encoded name
1924
 * The returned size includes the end of string character
1925
 * Returns 1 if successful, 0 if not available or -1 on error
1926
 */
1927
int libfsfat_directory_entry_get_utf8_name_size(
1928
     libfsfat_directory_entry_t *directory_entry,
1929
     size_t *utf8_string_size,
1930
     libcerror_error_t **error )
1931
0
{
1932
0
  static char *function = "libfsfat_directory_entry_get_utf8_name_size";
1933
0
  int result            = 0;
1934
1935
0
  if( directory_entry == NULL )
1936
0
  {
1937
0
    libcerror_error_set(
1938
0
     error,
1939
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1940
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1941
0
     "%s: invalid directory entry.",
1942
0
     function );
1943
1944
0
    return( -1 );
1945
0
  }
1946
0
  if( directory_entry->name == NULL )
1947
0
  {
1948
0
    if( libfsfat_directory_entry_get_name(
1949
0
         directory_entry,
1950
0
         error ) != 1 )
1951
0
    {
1952
0
      libcerror_error_set(
1953
0
       error,
1954
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1955
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1956
0
       "%s: unable to determine name.",
1957
0
       function );
1958
1959
0
      return( -1 );
1960
0
    }
1961
0
  }
1962
0
  if( directory_entry->is_unicode != 0 )
1963
0
  {
1964
0
    result = libuna_utf8_string_size_from_utf16_stream(
1965
0
              directory_entry->name,
1966
0
              directory_entry->name_size,
1967
0
              LIBUNA_ENDIAN_LITTLE,
1968
0
              utf8_string_size,
1969
0
              error );
1970
0
  }
1971
0
  else
1972
0
  {
1973
/* TODO add codepage support */
1974
0
    result = libuna_utf8_string_size_from_byte_stream(
1975
0
              directory_entry->name,
1976
0
              directory_entry->name_size,
1977
0
              LIBUNA_CODEPAGE_ASCII,
1978
0
              utf8_string_size,
1979
0
              error );
1980
0
  }
1981
0
  if( result != 1 )
1982
0
  {
1983
0
    libcerror_error_set(
1984
0
     error,
1985
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1986
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1987
0
     "%s: unable to retrieve UTF-8 string size.",
1988
0
     function );
1989
1990
0
    return( -1 );
1991
0
  }
1992
0
  return( 1 );
1993
0
}
1994
1995
/* Retrieves the UTF-8 encoded name
1996
 * The size should include the end of string character
1997
 * Returns 1 if successful, 0 if not available or -1 on error
1998
 */
1999
int libfsfat_directory_entry_get_utf8_name(
2000
     libfsfat_directory_entry_t *directory_entry,
2001
     uint8_t *utf8_string,
2002
     size_t utf8_string_size,
2003
     libcerror_error_t **error )
2004
0
{
2005
0
  static char *function = "libfsfat_directory_entry_get_utf8_name";
2006
0
  int result            = 0;
2007
2008
0
  if( directory_entry == NULL )
2009
0
  {
2010
0
    libcerror_error_set(
2011
0
     error,
2012
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2013
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2014
0
     "%s: invalid directory entry.",
2015
0
     function );
2016
2017
0
    return( -1 );
2018
0
  }
2019
0
  if( directory_entry->name == NULL )
2020
0
  {
2021
0
    if( libfsfat_directory_entry_get_name(
2022
0
         directory_entry,
2023
0
         error ) != 1 )
2024
0
    {
2025
0
      libcerror_error_set(
2026
0
       error,
2027
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2028
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2029
0
       "%s: unable to determine name.",
2030
0
       function );
2031
2032
0
      return( -1 );
2033
0
    }
2034
0
  }
2035
0
  if( directory_entry->is_unicode != 0 )
2036
0
  {
2037
0
    result = libuna_utf8_string_copy_from_utf16_stream(
2038
0
              utf8_string,
2039
0
              utf8_string_size,
2040
0
              directory_entry->name,
2041
0
              directory_entry->name_size,
2042
0
              LIBUNA_ENDIAN_LITTLE,
2043
0
              error );
2044
0
  }
2045
0
  else
2046
0
  {
2047
/* TODO add codepage support */
2048
0
    result = libuna_utf8_string_copy_from_byte_stream(
2049
0
              utf8_string,
2050
0
              utf8_string_size,
2051
0
              directory_entry->name,
2052
0
              directory_entry->name_size,
2053
0
              LIBUNA_CODEPAGE_ASCII,
2054
0
              error );
2055
0
  }
2056
0
  if( result != 1 )
2057
0
  {
2058
0
    libcerror_error_set(
2059
0
     error,
2060
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2061
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2062
0
     "%s: unable to retrieve UTF-8 string.",
2063
0
     function );
2064
2065
0
    return( -1 );
2066
0
  }
2067
0
  return( 1 );
2068
0
}
2069
2070
/* Compares an UTF-8 string with the name of the directory entry
2071
 * Returns LIBUNA_COMPARE_LESS, LIBUNA_COMPARE_EQUAL, LIBUNA_COMPARE_GREATER if successful or -1 on error
2072
 */
2073
int libfsfat_directory_entry_compare_with_utf8_string(
2074
     libfsfat_directory_entry_t *directory_entry,
2075
     const uint8_t *utf8_string,
2076
     size_t utf8_string_length,
2077
     libcerror_error_t **error )
2078
0
{
2079
0
  static char *function = "libfsfat_directory_entry_compare_with_utf8_string";
2080
0
  int result            = 0;
2081
2082
0
  if( directory_entry == NULL )
2083
0
  {
2084
0
    libcerror_error_set(
2085
0
     error,
2086
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2087
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2088
0
     "%s: invalid directory entry.",
2089
0
     function );
2090
2091
0
    return( -1 );
2092
0
  }
2093
0
  if( directory_entry->name == NULL )
2094
0
  {
2095
0
    if( libfsfat_directory_entry_get_name(
2096
0
         directory_entry,
2097
0
         error ) != 1 )
2098
0
    {
2099
0
      libcerror_error_set(
2100
0
       error,
2101
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2102
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2103
0
       "%s: unable to determine name.",
2104
0
       function );
2105
2106
0
      return( -1 );
2107
0
    }
2108
0
  }
2109
/* TODO add compare of both long and short name */
2110
/* TODO add codepage support */
2111
0
  result = libfsfat_name_compare_with_utf8_string(
2112
0
            directory_entry->name,
2113
0
            directory_entry->name_size,
2114
0
            directory_entry->is_unicode,
2115
0
            utf8_string,
2116
0
            utf8_string_length,
2117
0
            1,
2118
0
            error );
2119
2120
0
  if( result == -1 )
2121
0
  {
2122
0
    libcerror_error_set(
2123
0
     error,
2124
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2125
0
     LIBCERROR_RUNTIME_ERROR_GENERIC,
2126
0
     "%s: unable to compare UTF-8 string with directory entry name.",
2127
0
     function );
2128
2129
0
    return( -1 );
2130
0
  }
2131
0
  return( result );
2132
0
}
2133
2134
/* Retrieves the size of the UTF-16 encoded name
2135
 * The returned size includes the end of string character
2136
 * Returns 1 if successful, 0 if not available or -1 on error
2137
 */
2138
int libfsfat_directory_entry_get_utf16_name_size(
2139
     libfsfat_directory_entry_t *directory_entry,
2140
     size_t *utf16_string_size,
2141
     libcerror_error_t **error )
2142
0
{
2143
0
  static char *function = "libfsfat_directory_entry_get_utf16_name_size";
2144
0
  int result            = 0;
2145
2146
0
  if( directory_entry == NULL )
2147
0
  {
2148
0
    libcerror_error_set(
2149
0
     error,
2150
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2151
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2152
0
     "%s: invalid directory entry.",
2153
0
     function );
2154
2155
0
    return( -1 );
2156
0
  }
2157
0
  if( directory_entry->name == NULL )
2158
0
  {
2159
0
    if( libfsfat_directory_entry_get_name(
2160
0
         directory_entry,
2161
0
         error ) != 1 )
2162
0
    {
2163
0
      libcerror_error_set(
2164
0
       error,
2165
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2166
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2167
0
       "%s: unable to determine name.",
2168
0
       function );
2169
2170
0
      return( -1 );
2171
0
    }
2172
0
  }
2173
0
  if( directory_entry->is_unicode != 0 )
2174
0
  {
2175
0
    result = libuna_utf16_string_size_from_utf16_stream(
2176
0
              directory_entry->name,
2177
0
              directory_entry->name_size,
2178
0
              LIBUNA_ENDIAN_LITTLE,
2179
0
              utf16_string_size,
2180
0
              error );
2181
0
  }
2182
0
  else
2183
0
  {
2184
/* TODO add codepage support */
2185
0
    result = libuna_utf16_string_size_from_byte_stream(
2186
0
              directory_entry->name,
2187
0
              directory_entry->name_size,
2188
0
              LIBUNA_CODEPAGE_ASCII,
2189
0
              utf16_string_size,
2190
0
              error );
2191
0
  }
2192
0
  if( result != 1 )
2193
0
  {
2194
0
    libcerror_error_set(
2195
0
     error,
2196
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2197
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2198
0
     "%s: unable to retrieve UTF-16 string size.",
2199
0
     function );
2200
2201
0
    return( -1 );
2202
0
  }
2203
0
  return( 1 );
2204
0
}
2205
2206
/* Retrieves the UTF-16 encoded name
2207
 * The size should include the end of string character
2208
 * Returns 1 if successful, 0 if not available or -1 on error
2209
 */
2210
int libfsfat_directory_entry_get_utf16_name(
2211
     libfsfat_directory_entry_t *directory_entry,
2212
     uint16_t *utf16_string,
2213
     size_t utf16_string_size,
2214
     libcerror_error_t **error )
2215
0
{
2216
0
  static char *function = "libfsfat_directory_entry_get_utf16_name";
2217
0
  int result            = 0;
2218
2219
0
  if( directory_entry == NULL )
2220
0
  {
2221
0
    libcerror_error_set(
2222
0
     error,
2223
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2224
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2225
0
     "%s: invalid directory entry.",
2226
0
     function );
2227
2228
0
    return( -1 );
2229
0
  }
2230
0
  if( directory_entry->name == NULL )
2231
0
  {
2232
0
    if( libfsfat_directory_entry_get_name(
2233
0
         directory_entry,
2234
0
         error ) != 1 )
2235
0
    {
2236
0
      libcerror_error_set(
2237
0
       error,
2238
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2239
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2240
0
       "%s: unable to determine name.",
2241
0
       function );
2242
2243
0
      return( -1 );
2244
0
    }
2245
0
  }
2246
0
  if( directory_entry->is_unicode != 0 )
2247
0
  {
2248
0
    result = libuna_utf16_string_copy_from_utf16_stream(
2249
0
              utf16_string,
2250
0
              utf16_string_size,
2251
0
              directory_entry->name,
2252
0
              directory_entry->name_size,
2253
0
              LIBUNA_ENDIAN_LITTLE,
2254
0
              error );
2255
0
  }
2256
0
  else
2257
0
  {
2258
/* TODO add codepage support */
2259
0
    result = libuna_utf16_string_copy_from_byte_stream(
2260
0
              utf16_string,
2261
0
              utf16_string_size,
2262
0
              directory_entry->name,
2263
0
              directory_entry->name_size,
2264
0
              LIBUNA_CODEPAGE_ASCII,
2265
0
              error );
2266
0
  }
2267
0
  if( result != 1 )
2268
0
  {
2269
0
    libcerror_error_set(
2270
0
     error,
2271
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2272
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2273
0
     "%s: unable to retrieve UTF-16 string.",
2274
0
     function );
2275
2276
0
    return( -1 );
2277
0
  }
2278
0
  return( 1 );
2279
0
}
2280
2281
/* Compares an UTF-16 string with the name of the directory entry
2282
 * Returns LIBUNA_COMPARE_LESS, LIBUNA_COMPARE_EQUAL, LIBUNA_COMPARE_GREATER if successful or -1 on error
2283
 */
2284
int libfsfat_directory_entry_compare_with_utf16_string(
2285
     libfsfat_directory_entry_t *directory_entry,
2286
     const uint16_t *utf16_string,
2287
     size_t utf16_string_length,
2288
     libcerror_error_t **error )
2289
0
{
2290
0
  static char *function = "libfsfat_directory_entry_compare_with_utf16_string";
2291
0
  int result            = 0;
2292
2293
0
  if( directory_entry == NULL )
2294
0
  {
2295
0
    libcerror_error_set(
2296
0
     error,
2297
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2298
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2299
0
     "%s: invalid directory entry.",
2300
0
     function );
2301
2302
0
    return( -1 );
2303
0
  }
2304
0
  if( directory_entry->name == NULL )
2305
0
  {
2306
0
    if( libfsfat_directory_entry_get_name(
2307
0
         directory_entry,
2308
0
         error ) != 1 )
2309
0
    {
2310
0
      libcerror_error_set(
2311
0
       error,
2312
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2313
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2314
0
       "%s: unable to determine name.",
2315
0
       function );
2316
2317
0
      return( -1 );
2318
0
    }
2319
0
  }
2320
/* TODO add compare of both long and short name */
2321
/* TODO add codepage support */
2322
0
  result = libfsfat_name_compare_with_utf16_string(
2323
0
            directory_entry->name,
2324
0
            directory_entry->name_size,
2325
0
            directory_entry->is_unicode,
2326
0
            utf16_string,
2327
0
            utf16_string_length,
2328
0
            1,
2329
0
            error );
2330
2331
0
  if( result == -1 )
2332
0
  {
2333
0
    libcerror_error_set(
2334
0
     error,
2335
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2336
0
     LIBCERROR_RUNTIME_ERROR_GENERIC,
2337
0
     "%s: unable to compare UTF-16 string with directory entry name.",
2338
0
     function );
2339
2340
0
    return( -1 );
2341
0
  }
2342
0
  return( result );
2343
0
}
2344
2345
/* Retrieves the data start cluster
2346
 * Returns 1 if successful or -1 on error
2347
 */
2348
int libfsfat_directory_entry_get_data_start_cluster(
2349
     libfsfat_directory_entry_t *directory_entry,
2350
     uint32_t *data_start_cluster,
2351
     libcerror_error_t **error )
2352
146
{
2353
146
  static char *function = "libfsfat_directory_entry_get_data_start_cluster";
2354
2355
146
  if( directory_entry == NULL )
2356
0
  {
2357
0
    libcerror_error_set(
2358
0
     error,
2359
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2360
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2361
0
     "%s: invalid directory entry.",
2362
0
     function );
2363
2364
0
    return( -1 );
2365
0
  }
2366
146
  if( data_start_cluster == NULL )
2367
0
  {
2368
0
    libcerror_error_set(
2369
0
     error,
2370
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2371
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2372
0
     "%s: invalid data start cluster.",
2373
0
     function );
2374
2375
0
    return( -1 );
2376
0
  }
2377
146
  *data_start_cluster = directory_entry->data_start_cluster;
2378
2379
146
  return( 1 );
2380
146
}
2381
2382
/* Retrieves the data size
2383
 * Returns 1 if successful or -1 on error
2384
 */
2385
int libfsfat_directory_entry_get_data_size(
2386
     libfsfat_directory_entry_t *directory_entry,
2387
     uint64_t *data_size,
2388
     libcerror_error_t **error )
2389
146
{
2390
146
  static char *function = "libfsfat_directory_entry_get_data_size";
2391
2392
146
  if( directory_entry == NULL )
2393
0
  {
2394
0
    libcerror_error_set(
2395
0
     error,
2396
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2397
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2398
0
     "%s: invalid directory entry.",
2399
0
     function );
2400
2401
0
    return( -1 );
2402
0
  }
2403
146
  if( data_size == NULL )
2404
0
  {
2405
0
    libcerror_error_set(
2406
0
     error,
2407
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2408
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2409
0
     "%s: invalid data size.",
2410
0
     function );
2411
2412
0
    return( -1 );
2413
0
  }
2414
146
  *data_size = directory_entry->data_size;
2415
2416
146
  return( 1 );
2417
146
}
2418
2419
/* Retrieves the valid data size
2420
 * Returns 1 if successful or -1 on error
2421
 */
2422
int libfsfat_directory_entry_get_valid_data_size(
2423
     libfsfat_directory_entry_t *directory_entry,
2424
     uint64_t *valid_data_size,
2425
     libcerror_error_t **error )
2426
146
{
2427
146
  static char *function = "libfsfat_directory_entry_get_valid_data_size";
2428
2429
146
  if( directory_entry == NULL )
2430
0
  {
2431
0
    libcerror_error_set(
2432
0
     error,
2433
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2434
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2435
0
     "%s: invalid directory entry.",
2436
0
     function );
2437
2438
0
    return( -1 );
2439
0
  }
2440
146
  if( valid_data_size == NULL )
2441
0
  {
2442
0
    libcerror_error_set(
2443
0
     error,
2444
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2445
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2446
0
     "%s: invalid valid data size.",
2447
0
     function );
2448
2449
0
    return( -1 );
2450
0
  }
2451
146
  *valid_data_size = directory_entry->valid_data_size;
2452
2453
146
  return( 1 );
2454
146
}
2455