Coverage Report

Created: 2026-01-13 07:09

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