Coverage Report

Created: 2026-05-30 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libfsntfs/libfsntfs/libfsntfs_file_entry.c
Line
Count
Source
1
/*
2
 * File entry functions
3
 *
4
 * Copyright (C) 2010-2026, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <types.h>
25
26
#include "libfsntfs_attribute.h"
27
#include "libfsntfs_cluster_block_stream.h"
28
#include "libfsntfs_data_stream.h"
29
#include "libfsntfs_definitions.h"
30
#include "libfsntfs_directory_entries_tree.h"
31
#include "libfsntfs_directory_entry.h"
32
#include "libfsntfs_extent.h"
33
#include "libfsntfs_file_entry.h"
34
#include "libfsntfs_file_name_attribute.h"
35
#include "libfsntfs_file_name_values.h"
36
#include "libfsntfs_libbfio.h"
37
#include "libfsntfs_libcdata.h"
38
#include "libfsntfs_libcerror.h"
39
#include "libfsntfs_libcnotify.h"
40
#include "libfsntfs_libcthreads.h"
41
#include "libfsntfs_libfdata.h"
42
#include "libfsntfs_mft_entry.h"
43
#include "libfsntfs_path_hint.h"
44
#include "libfsntfs_reparse_point_attribute.h"
45
#include "libfsntfs_security_descriptor_values.h"
46
#include "libfsntfs_standard_information_values.h"
47
#include "libfsntfs_types.h"
48
49
/* Creates a file entry
50
 * Make sure the value file_entry is referencing, is set to NULL
51
 * Returns 1 if successful or -1 on error
52
 */
53
int libfsntfs_file_entry_initialize(
54
     libfsntfs_file_entry_t **file_entry,
55
     libfsntfs_io_handle_t *io_handle,
56
     libbfio_handle_t *file_io_handle,
57
     libfsntfs_file_system_t *file_system,
58
     uint64_t mft_entry_index,
59
     libfsntfs_directory_entry_t *directory_entry,
60
     uint8_t flags,
61
     libcerror_error_t **error )
62
2.12k
{
63
2.12k
  libfsntfs_attribute_t *reparse_point_attribute           = NULL;
64
2.12k
  libfsntfs_internal_file_entry_t *internal_file_entry     = NULL;
65
2.12k
  libfsntfs_mft_attribute_t *data_extents_attribute        = NULL;
66
2.12k
  libfsntfs_mft_attribute_t *wof_compressed_data_attribute = NULL;
67
2.12k
  libfsntfs_mft_entry_t *mft_entry                         = NULL;
68
2.12k
  static char *function                                    = "libfsntfs_file_entry_initialize";
69
2.12k
  uint64_t base_record_file_reference                      = 0;
70
2.12k
  uint32_t compression_method                              = 0;
71
2.12k
  int result                                               = 0;
72
73
2.12k
  if( file_entry == NULL )
74
0
  {
75
0
    libcerror_error_set(
76
0
     error,
77
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
78
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
79
0
     "%s: invalid file entry.",
80
0
     function );
81
82
0
    return( -1 );
83
0
  }
84
2.12k
  if( *file_entry != NULL )
85
0
  {
86
0
    libcerror_error_set(
87
0
     error,
88
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
89
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
90
0
     "%s: invalid file entry value already set.",
91
0
     function );
92
93
0
    return( -1 );
94
0
  }
95
2.12k
  if( io_handle == NULL )
96
0
  {
97
0
    libcerror_error_set(
98
0
     error,
99
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
100
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
101
0
     "%s: invalid IO handle.",
102
0
     function );
103
104
0
    return( -1 );
105
0
  }
106
2.12k
  if( file_system == NULL )
107
0
  {
108
0
    libcerror_error_set(
109
0
     error,
110
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
111
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
112
0
     "%s: invalid file system.",
113
0
     function );
114
115
0
    return( -1 );
116
0
  }
117
2.12k
  internal_file_entry = memory_allocate_structure(
118
2.12k
                         libfsntfs_internal_file_entry_t );
119
120
2.12k
  if( internal_file_entry == NULL )
121
0
  {
122
0
    libcerror_error_set(
123
0
     error,
124
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
125
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
126
0
     "%s: unable to create file entry.",
127
0
     function );
128
129
0
    goto on_error;
130
0
  }
131
2.12k
  if( memory_set(
132
2.12k
       internal_file_entry,
133
2.12k
       0,
134
2.12k
       sizeof( libfsntfs_internal_file_entry_t ) ) == NULL )
135
0
  {
136
0
    libcerror_error_set(
137
0
     error,
138
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
139
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
140
0
     "%s: unable to clear file entry.",
141
0
     function );
142
143
0
    memory_free(
144
0
     internal_file_entry );
145
146
0
    return( -1 );
147
0
  }
148
2.12k
  if( libfsntfs_file_system_get_mft_entry_by_index_no_cache(
149
2.12k
       file_system,
150
2.12k
       file_io_handle,
151
2.12k
       mft_entry_index,
152
2.12k
       &mft_entry,
153
2.12k
       error ) != 1 )
154
32
  {
155
32
    libcerror_error_set(
156
32
     error,
157
32
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
158
32
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
159
32
     "%s: unable to retrieve MFT entry: %" PRIu64 ".",
160
32
     function,
161
32
     mft_entry_index );
162
163
32
    goto on_error;
164
32
  }
165
2.09k
  if( mft_entry == NULL )
166
0
  {
167
0
    libcerror_error_set(
168
0
     error,
169
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
170
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
171
0
     "%s: missing MFT entry: %" PRIu64 ".",
172
0
     function,
173
0
     mft_entry_index );
174
175
0
    return( -1 );
176
0
  }
177
2.09k
  if( ( flags & LIBFSNTFS_FILE_ENTRY_FLAGS_MFT_ONLY ) == 0 )
178
2.09k
  {
179
2.09k
    result = libfsntfs_mft_entry_get_base_record_file_reference(
180
2.09k
              mft_entry,
181
2.09k
              &base_record_file_reference,
182
2.09k
              error );
183
184
2.09k
    if( result == -1 )
185
0
    {
186
0
      libcerror_error_set(
187
0
       error,
188
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
189
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
190
0
       "%s: unable to retrieve base record file reference.",
191
0
       function );
192
193
0
      goto on_error;
194
0
    }
195
2.09k
    if( ( result == 1 )
196
2.08k
     && ( base_record_file_reference == 0 ) )
197
1.99k
    {
198
1.99k
      if( mft_entry->has_i30_index != 0 )
199
1.59k
      {
200
1.59k
        if( libfsntfs_directory_entries_tree_initialize(
201
1.59k
             &( internal_file_entry->directory_entries_tree ),
202
1.59k
             error ) != 1 )
203
0
        {
204
0
          libcerror_error_set(
205
0
           error,
206
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
207
0
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
208
0
           "%s: unable to create directory entries tree.",
209
0
           function );
210
211
0
          goto on_error;
212
0
        }
213
1.59k
        if( libfsntfs_directory_entries_tree_read_from_i30_index(
214
1.59k
             internal_file_entry->directory_entries_tree,
215
1.59k
             io_handle,
216
1.59k
             file_io_handle,
217
1.59k
             mft_entry,
218
1.59k
             flags,
219
1.59k
             error ) != 1 )
220
1.41k
        {
221
1.41k
          libcerror_error_set(
222
1.41k
           error,
223
1.41k
           LIBCERROR_ERROR_DOMAIN_IO,
224
1.41k
           LIBCERROR_IO_ERROR_READ_FAILED,
225
1.41k
           "%s: unable to read MFT entry: %" PRIu32 " directory entries tree.",
226
1.41k
           function,
227
1.41k
           mft_entry->index );
228
229
1.41k
          goto on_error;
230
1.41k
        }
231
1.59k
      }
232
576
      if( mft_entry->data_attribute != NULL )
233
404
      {
234
404
        if( mft_entry->wof_compressed_data_attribute != NULL )
235
0
        {
236
0
          result = libfsntfs_internal_file_entry_get_reparse_point_attribute(
237
0
              internal_file_entry,
238
0
              mft_entry,
239
0
              &reparse_point_attribute,
240
0
              error );
241
242
0
          if( result == -1 )
243
0
          {
244
0
            libcerror_error_set(
245
0
             error,
246
0
             LIBCERROR_ERROR_DOMAIN_RUNTIME,
247
0
             LIBCERROR_RUNTIME_ERROR_GET_FAILED,
248
0
             "%s: unable to retrieve reparse point attribute.",
249
0
             function );
250
251
0
            goto on_error;
252
0
          }
253
0
          else if( result != 0 )
254
0
          {
255
0
            if( libfsntfs_reparse_point_attribute_get_compression_method(
256
0
                 reparse_point_attribute,
257
0
                 &compression_method,
258
0
                 error ) != 1 )
259
0
            {
260
0
              libcerror_error_set(
261
0
               error,
262
0
               LIBCERROR_ERROR_DOMAIN_RUNTIME,
263
0
               LIBCERROR_RUNTIME_ERROR_GET_FAILED,
264
0
               "%s: unable to retrieve compression method from $REPARSE_POINT attribute.",
265
0
               function );
266
267
0
              goto on_error;
268
0
            }
269
0
            wof_compressed_data_attribute = mft_entry->wof_compressed_data_attribute;
270
0
          }
271
0
        }
272
404
        if( wof_compressed_data_attribute == NULL )
273
404
        {
274
404
          data_extents_attribute = mft_entry->data_attribute;
275
404
        }
276
0
        else
277
0
        {
278
0
          data_extents_attribute = wof_compressed_data_attribute;
279
0
        }
280
404
        if( libfsntfs_mft_attribute_get_data_extents_array(
281
404
             data_extents_attribute,
282
404
             io_handle,
283
404
             &( internal_file_entry->extents_array ),
284
404
             error ) != 1 )
285
374
        {
286
374
          libcerror_error_set(
287
374
           error,
288
374
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
289
374
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
290
374
           "%s: unable to create extents array.",
291
374
           function );
292
293
374
          goto on_error;
294
374
        }
295
30
        if( libfsntfs_cluster_block_stream_initialize(
296
30
             &( internal_file_entry->data_cluster_block_stream ),
297
30
             io_handle,
298
30
             mft_entry->data_attribute,
299
30
             wof_compressed_data_attribute,
300
30
             compression_method,
301
30
             error ) != 1 )
302
6
        {
303
6
          libcerror_error_set(
304
6
           error,
305
6
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
306
6
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
307
6
           "%s: unable to create data cluster block stream.",
308
6
           function );
309
310
6
          goto on_error;
311
6
        }
312
30
      }
313
576
    }
314
2.09k
  }
315
296
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
316
296
  if( libcthreads_read_write_lock_initialize(
317
296
       &( internal_file_entry->read_write_lock ),
318
296
       error ) != 1 )
319
0
  {
320
0
    libcerror_error_set(
321
0
     error,
322
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
323
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
324
0
     "%s: unable to initialize read/write lock.",
325
0
     function );
326
327
0
    goto on_error;
328
0
  }
329
296
#endif
330
296
  internal_file_entry->io_handle       = io_handle;
331
296
  internal_file_entry->file_io_handle  = file_io_handle;
332
296
  internal_file_entry->file_system     = file_system;
333
296
  internal_file_entry->mft_entry       = mft_entry;
334
296
  internal_file_entry->directory_entry = directory_entry;
335
296
  internal_file_entry->data_attribute  = mft_entry->data_attribute;
336
296
  internal_file_entry->flags           = flags;
337
338
296
  *file_entry = (libfsntfs_file_entry_t *) internal_file_entry;
339
340
296
  return( 1 );
341
342
1.82k
on_error:
343
1.82k
  if( mft_entry != NULL )
344
1.79k
  {
345
1.79k
    libfsntfs_mft_entry_free(
346
1.79k
     &mft_entry,
347
1.79k
     NULL );
348
1.79k
  }
349
1.82k
  if( internal_file_entry != NULL )
350
1.82k
  {
351
1.82k
    if( internal_file_entry->data_cluster_block_stream != NULL )
352
0
    {
353
0
      libfdata_stream_free(
354
0
       &( internal_file_entry->data_cluster_block_stream ),
355
0
       NULL );
356
0
    }
357
1.82k
    if( internal_file_entry->directory_entries_tree != NULL )
358
1.41k
    {
359
1.41k
      libfsntfs_directory_entries_tree_free(
360
1.41k
       &( internal_file_entry->directory_entries_tree ),
361
1.41k
       NULL );
362
1.41k
    }
363
1.82k
    if( internal_file_entry->extents_array != NULL )
364
6
    {
365
6
      libcdata_array_free(
366
6
       &( internal_file_entry->extents_array ),
367
6
       (int (*)(intptr_t **, libcerror_error_t **)) &libfsntfs_extent_free,
368
6
       NULL );
369
6
    }
370
1.82k
    memory_free(
371
1.82k
     internal_file_entry );
372
1.82k
  }
373
1.82k
  return( -1 );
374
296
}
375
376
/* Frees a file entry
377
 * Returns 1 if successful or -1 on error
378
 */
379
int libfsntfs_file_entry_free(
380
     libfsntfs_file_entry_t **file_entry,
381
     libcerror_error_t **error )
382
296
{
383
296
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
384
296
  static char *function                                = "libfsntfs_file_entry_free";
385
296
  int result                                           = 1;
386
387
296
  if( file_entry == NULL )
388
0
  {
389
0
    libcerror_error_set(
390
0
     error,
391
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
392
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
393
0
     "%s: invalid file entry.",
394
0
     function );
395
396
0
    return( -1 );
397
0
  }
398
296
  if( *file_entry != NULL )
399
296
  {
400
296
    internal_file_entry = (libfsntfs_internal_file_entry_t *) *file_entry;
401
296
    *file_entry         = NULL;
402
403
296
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
404
296
    if( libcthreads_read_write_lock_free(
405
296
         &( internal_file_entry->read_write_lock ),
406
296
         error ) != 1 )
407
0
    {
408
0
      libcerror_error_set(
409
0
       error,
410
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
411
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
412
0
       "%s: unable to free read/write lock.",
413
0
       function );
414
415
0
      result = -1;
416
0
    }
417
296
#endif
418
    /* The file_io_handle, io_handle and file_system references are freed elsewhere
419
     */
420
296
    if( internal_file_entry->data_cluster_block_stream != NULL )
421
24
    {
422
24
      if( libfdata_stream_free(
423
24
           &( internal_file_entry->data_cluster_block_stream ),
424
24
           error ) != 1 )
425
0
      {
426
0
        libcerror_error_set(
427
0
         error,
428
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
429
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
430
0
         "%s: unable to free data cluster block stream.",
431
0
         function );
432
433
0
        result = -1;
434
0
      }
435
24
    }
436
    /* The reparse_point_attribute, security_descriptor_attribute and standard_information_attribute references are managed by the attributes_array
437
     */
438
296
    if( internal_file_entry->attributes_array != NULL )
439
0
    {
440
0
      if( libcdata_array_free(
441
0
           &( internal_file_entry->attributes_array ),
442
0
           (int (*)(intptr_t **, libcerror_error_t **)) &libfsntfs_internal_attribute_free,
443
0
           error ) != 1 )
444
0
      {
445
0
        libcerror_error_set(
446
0
         error,
447
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
448
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
449
0
         "%s: unable to free attributes array.",
450
0
         function );
451
452
0
        result = -1;
453
0
      }
454
0
    }
455
296
    if( libcdata_array_free(
456
296
         &( internal_file_entry->extents_array ),
457
296
         (int (*)(intptr_t **, libcerror_error_t **)) &libfsntfs_extent_free,
458
296
         error ) != 1 )
459
0
    {
460
0
      libcerror_error_set(
461
0
       error,
462
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
463
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
464
0
       "%s: unable to free extents array.",
465
0
       function );
466
467
0
      result = -1;
468
0
    }
469
296
    if( internal_file_entry->security_descriptor_values != NULL )
470
0
    {
471
0
      if( libfsntfs_security_descriptor_values_free(
472
0
           &( internal_file_entry->security_descriptor_values ),
473
0
           error ) != 1 )
474
0
      {
475
0
        libcerror_error_set(
476
0
         error,
477
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
478
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
479
0
         "%s: unable to free security descriptor values.",
480
0
         function );
481
482
0
        result = -1;
483
0
      }
484
0
    }
485
296
    if( internal_file_entry->directory_entries_tree != NULL )
486
179
    {
487
179
      if( libfsntfs_directory_entries_tree_free(
488
179
           &( internal_file_entry->directory_entries_tree ),
489
179
           error ) != 1 )
490
0
      {
491
0
        libcerror_error_set(
492
0
         error,
493
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
494
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
495
0
         "%s: unable to free directory entries tree.",
496
0
         function );
497
498
0
        result = -1;
499
0
      }
500
179
    }
501
296
    if( internal_file_entry->directory_entry != NULL )
502
23
    {
503
23
      if( libfsntfs_directory_entry_free(
504
23
           &( internal_file_entry->directory_entry ),
505
23
           error ) != 1 )
506
0
      {
507
0
        libcerror_error_set(
508
0
         error,
509
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
510
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
511
0
         "%s: unable to free directory entry.",
512
0
         function );
513
514
0
        result = -1;
515
0
      }
516
23
    }
517
296
    if( internal_file_entry->mft_entry != NULL )
518
296
    {
519
296
      if( libfsntfs_mft_entry_free(
520
296
           &( internal_file_entry->mft_entry ),
521
296
           error ) != 1 )
522
0
      {
523
0
        libcerror_error_set(
524
0
         error,
525
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
526
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
527
0
         "%s: unable to free MFT entry.",
528
0
         function );
529
530
0
        result = -1;
531
0
      }
532
296
    }
533
296
    memory_free(
534
296
     internal_file_entry );
535
296
  }
536
296
  return( result );
537
296
}
538
539
/* Determines if the file entry is empty
540
 * Returns 1 if empty, 0 if not or -1 on error
541
 */
542
int libfsntfs_file_entry_is_empty(
543
     libfsntfs_file_entry_t *file_entry,
544
     libcerror_error_t **error )
545
0
{
546
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
547
0
  static char *function                                = "libfsntfs_file_entry_is_empty";
548
0
  int result                                           = 0;
549
550
0
  if( file_entry == NULL )
551
0
  {
552
0
    libcerror_error_set(
553
0
     error,
554
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
555
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
556
0
     "%s: invalid file entry.",
557
0
     function );
558
559
0
    return( -1 );
560
0
  }
561
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
562
563
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
564
0
  if( libcthreads_read_write_lock_grab_for_read(
565
0
       internal_file_entry->read_write_lock,
566
0
       error ) != 1 )
567
0
  {
568
0
    libcerror_error_set(
569
0
     error,
570
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
571
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
572
0
     "%s: unable to grab read/write lock for reading.",
573
0
     function );
574
575
0
    return( -1 );
576
0
  }
577
0
#endif
578
0
  result = libfsntfs_mft_entry_is_empty(
579
0
            internal_file_entry->mft_entry,
580
0
            error );
581
582
0
  if( result == -1 )
583
0
  {
584
0
    libcerror_error_set(
585
0
     error,
586
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
587
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
588
0
     "%s: unable to determine if MFT entry is empty.",
589
0
     function );
590
591
0
    result = -1;
592
0
  }
593
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
594
0
  if( libcthreads_read_write_lock_release_for_read(
595
0
       internal_file_entry->read_write_lock,
596
0
       error ) != 1 )
597
0
  {
598
0
    libcerror_error_set(
599
0
     error,
600
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
601
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
602
0
     "%s: unable to release read/write lock for reading.",
603
0
     function );
604
605
0
    return( -1 );
606
0
  }
607
0
#endif
608
0
  return( result );
609
0
}
610
611
/* Determines if the file entry is allocated (MFT entry in use flag is set)
612
 * Returns 1 if allocated, 0 if not or -1 on error
613
 */
614
int libfsntfs_file_entry_is_allocated(
615
     libfsntfs_file_entry_t *file_entry,
616
     libcerror_error_t **error )
617
0
{
618
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
619
0
  static char *function                                = "libfsntfs_file_entry_is_allocated";
620
0
  int result                                           = 0;
621
622
0
  if( file_entry == NULL )
623
0
  {
624
0
    libcerror_error_set(
625
0
     error,
626
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
627
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
628
0
     "%s: invalid file entry.",
629
0
     function );
630
631
0
    return( -1 );
632
0
  }
633
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
634
635
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
636
0
  if( libcthreads_read_write_lock_grab_for_read(
637
0
       internal_file_entry->read_write_lock,
638
0
       error ) != 1 )
639
0
  {
640
0
    libcerror_error_set(
641
0
     error,
642
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
643
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
644
0
     "%s: unable to grab read/write lock for reading.",
645
0
     function );
646
647
0
    return( -1 );
648
0
  }
649
0
#endif
650
0
  result = libfsntfs_mft_entry_is_allocated(
651
0
            internal_file_entry->mft_entry,
652
0
            error );
653
654
0
  if( result == -1 )
655
0
  {
656
0
    libcerror_error_set(
657
0
     error,
658
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
659
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
660
0
     "%s: unable to determine if MFT entry is allocated.",
661
0
     function );
662
663
0
    result = -1;
664
0
  }
665
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
666
0
  if( libcthreads_read_write_lock_release_for_read(
667
0
       internal_file_entry->read_write_lock,
668
0
       error ) != 1 )
669
0
  {
670
0
    libcerror_error_set(
671
0
     error,
672
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
673
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
674
0
     "%s: unable to release read/write lock for reading.",
675
0
     function );
676
677
0
    return( -1 );
678
0
  }
679
0
#endif
680
0
  return( result );
681
0
}
682
683
/* Determines if the file entry is corrupted
684
 * Returns 1 if corrupted, 0 if not or -1 on error
685
 */
686
int libfsntfs_file_entry_is_corrupted(
687
     libfsntfs_file_entry_t *file_entry,
688
     libcerror_error_t **error )
689
0
{
690
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
691
0
  static char *function                                = "libfsntfs_file_entry_is_corrupted";
692
0
  int result                                           = 0;
693
694
0
  if( file_entry == NULL )
695
0
  {
696
0
    libcerror_error_set(
697
0
     error,
698
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
699
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
700
0
     "%s: invalid file entry.",
701
0
     function );
702
703
0
    return( -1 );
704
0
  }
705
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
706
707
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
708
0
  if( libcthreads_read_write_lock_grab_for_read(
709
0
       internal_file_entry->read_write_lock,
710
0
       error ) != 1 )
711
0
  {
712
0
    libcerror_error_set(
713
0
     error,
714
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
715
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
716
0
     "%s: unable to grab read/write lock for reading.",
717
0
     function );
718
719
0
    return( -1 );
720
0
  }
721
0
#endif
722
0
  result = libfsntfs_mft_entry_is_corrupted(
723
0
            internal_file_entry->mft_entry,
724
0
            error );
725
726
0
  if( result == -1 )
727
0
  {
728
0
    libcerror_error_set(
729
0
     error,
730
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
731
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
732
0
     "%s: unable to determine if MFT entry is corrupted.",
733
0
     function );
734
735
0
    result = -1;
736
0
  }
737
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
738
0
  if( libcthreads_read_write_lock_release_for_read(
739
0
       internal_file_entry->read_write_lock,
740
0
       error ) != 1 )
741
0
  {
742
0
    libcerror_error_set(
743
0
     error,
744
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
745
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
746
0
     "%s: unable to release read/write lock for reading.",
747
0
     function );
748
749
0
    return( -1 );
750
0
  }
751
0
#endif
752
0
  return( result );
753
0
}
754
755
/* Retrieves a specific attribute
756
 * Returns 1 if successful or -1 on error
757
 */
758
int libfsntfs_internal_file_entry_get_attribute_by_index(
759
     libfsntfs_internal_file_entry_t *internal_file_entry,
760
     libfsntfs_mft_entry_t *mft_entry,
761
     int attribute_index,
762
     libfsntfs_attribute_t **attribute,
763
     libcerror_error_t **error )
764
0
{
765
0
  libfsntfs_attribute_t *safe_attribute    = NULL;
766
0
  libfsntfs_mft_attribute_t *mft_attribute = NULL;
767
0
  static char *function                    = "libfsntfs_internal_file_entry_get_attribute_by_index";
768
0
  uint32_t attribute_type                  = 0;
769
0
  int number_of_attributes                 = 0;
770
771
0
  if( internal_file_entry == NULL )
772
0
  {
773
0
    libcerror_error_set(
774
0
     error,
775
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
776
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
777
0
     "%s: invalid file entry.",
778
0
     function );
779
780
0
    return( -1 );
781
0
  }
782
0
  if( attribute == NULL )
783
0
  {
784
0
    libcerror_error_set(
785
0
     error,
786
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
787
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
788
0
     "%s: invalid attribute.",
789
0
     function );
790
791
0
    return( -1 );
792
0
  }
793
0
  if( internal_file_entry->attributes_array == NULL )
794
0
  {
795
0
    if( libfsntfs_mft_entry_get_number_of_attributes(
796
0
         mft_entry,
797
0
         &number_of_attributes,
798
0
         error ) != 1 )
799
0
    {
800
0
      libcerror_error_set(
801
0
       error,
802
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
803
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
804
0
       "%s: unable to retrieve number of attributes.",
805
0
       function );
806
807
0
      goto on_error;
808
0
    }
809
0
    if( libcdata_array_initialize(
810
0
         &( internal_file_entry->attributes_array ),
811
0
         number_of_attributes,
812
0
         error ) != 1 )
813
0
    {
814
0
      libcerror_error_set(
815
0
       error,
816
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
817
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
818
0
       "%s: unable to create attributes array.",
819
0
       function );
820
821
0
      goto on_error;
822
0
    }
823
0
  }
824
0
  if( libcdata_array_get_entry_by_index(
825
0
       internal_file_entry->attributes_array,
826
0
       attribute_index,
827
0
       (intptr_t **) attribute,
828
0
       error ) != 1 )
829
0
  {
830
0
    libcerror_error_set(
831
0
     error,
832
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
833
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
834
0
     "%s: unable to retrieve attribute: %d from array.",
835
0
     function,
836
0
     attribute_index );
837
838
0
    goto on_error;
839
0
  }
840
0
  if( *attribute == NULL )
841
0
  {
842
0
    if( libfsntfs_mft_entry_get_attribute_by_index(
843
0
         mft_entry,
844
0
         attribute_index,
845
0
         &mft_attribute,
846
0
         error ) != 1 )
847
0
    {
848
0
      libcerror_error_set(
849
0
       error,
850
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
851
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
852
0
       "%s: unable to retrieve attribute: %d from MFT entry.",
853
0
       function,
854
0
       attribute_index );
855
856
0
      goto on_error;
857
0
    }
858
0
    if( libfsntfs_mft_attribute_get_type(
859
0
         mft_attribute,
860
0
         &attribute_type,
861
0
         error ) != 1 )
862
0
    {
863
0
      libcerror_error_set(
864
0
       error,
865
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
866
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
867
0
       "%s: unable to retrieve attribute: %d type.",
868
0
       function,
869
0
       attribute_index );
870
871
0
      goto on_error;
872
0
    }
873
0
    if( libfsntfs_attribute_initialize(
874
0
         &safe_attribute,
875
0
         mft_attribute,
876
0
         error ) != 1 )
877
0
    {
878
0
      libcerror_error_set(
879
0
       error,
880
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
881
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
882
0
       "%s: unable to create attribute: %d.",
883
0
       function,
884
0
       attribute_index );
885
886
0
      goto on_error;
887
0
    }
888
0
    if( attribute_type == LIBFSNTFS_ATTRIBUTE_TYPE_ATTRIBUTE_LIST )
889
0
    {
890
0
      ( (libfsntfs_internal_attribute_t *) safe_attribute )->value = (intptr_t *) mft_entry->attribute_list;
891
0
    }
892
0
    else
893
0
    {
894
0
      if( libfsntfs_internal_attribute_read_value(
895
0
           (libfsntfs_internal_attribute_t *) safe_attribute,
896
0
           internal_file_entry->io_handle,
897
0
           internal_file_entry->file_io_handle,
898
0
           internal_file_entry->flags,
899
0
           error ) != 1 )
900
0
      {
901
0
        libcerror_error_set(
902
0
         error,
903
0
         LIBCERROR_ERROR_DOMAIN_IO,
904
0
         LIBCERROR_IO_ERROR_READ_FAILED,
905
0
         "%s: unable to read value of attribute: %d.",
906
0
         function,
907
0
         attribute_index );
908
909
0
        goto on_error;
910
0
      }
911
0
    }
912
0
    if( libcdata_array_set_entry_by_index(
913
0
         internal_file_entry->attributes_array,
914
0
         attribute_index,
915
0
         (intptr_t *) safe_attribute,
916
0
         error ) != 1 )
917
0
    {
918
0
      libcerror_error_set(
919
0
       error,
920
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
921
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
922
0
       "%s: unable to set atribute: %d in array.",
923
0
       function,
924
0
       attribute_index );
925
926
0
      goto on_error;
927
0
    }
928
0
    *attribute = safe_attribute;
929
0
  }
930
0
  return( 1 );
931
932
0
on_error:
933
0
  if( safe_attribute != NULL )
934
0
  {
935
0
    libfsntfs_internal_attribute_free(
936
0
     (libfsntfs_internal_attribute_t **) &safe_attribute,
937
0
     NULL );
938
0
  }
939
0
  return( -1 );
940
0
}
941
942
/* Retrieves the $REPARSE_POINT attribute
943
 * Returns 1 if successful, 0 if not available or -1 on error
944
 */
945
int libfsntfs_internal_file_entry_get_reparse_point_attribute(
946
     libfsntfs_internal_file_entry_t *internal_file_entry,
947
     libfsntfs_mft_entry_t *mft_entry,
948
     libfsntfs_attribute_t **attribute,
949
     libcerror_error_t **error )
950
0
{
951
0
  static char *function = "libfsntfs_internal_file_entry_get_reparse_point_attribute";
952
953
0
  if( internal_file_entry == NULL )
954
0
  {
955
0
    libcerror_error_set(
956
0
     error,
957
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
958
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
959
0
     "%s: invalid file entry.",
960
0
     function );
961
962
0
    return( -1 );
963
0
  }
964
0
  if( mft_entry == NULL )
965
0
  {
966
0
    libcerror_error_set(
967
0
     error,
968
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
969
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
970
0
     "%s: missing MFT entry.",
971
0
     function );
972
973
0
    return( -1 );
974
0
  }
975
0
  if( attribute == NULL )
976
0
  {
977
0
    libcerror_error_set(
978
0
     error,
979
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
980
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
981
0
     "%s: invalid attribute.",
982
0
     function );
983
984
0
    return( -1 );
985
0
  }
986
0
  if( mft_entry->reparse_point_attribute_index == -1 )
987
0
  {
988
0
    return( 0 );
989
0
  }
990
0
  if( internal_file_entry->reparse_point_attribute == NULL )
991
0
  {
992
0
    if( libfsntfs_internal_file_entry_get_attribute_by_index(
993
0
         internal_file_entry,
994
0
         mft_entry,
995
0
         mft_entry->reparse_point_attribute_index,
996
0
         &( internal_file_entry->reparse_point_attribute ),
997
0
         error ) != 1 )
998
0
    {
999
0
      libcerror_error_set(
1000
0
       error,
1001
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1002
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1003
0
       "%s: unable to retrieve attribute: %d.",
1004
0
       function,
1005
0
       mft_entry->reparse_point_attribute_index );
1006
1007
0
      return( -1 );
1008
0
    }
1009
0
  }
1010
0
  *attribute = internal_file_entry->reparse_point_attribute;
1011
1012
0
  return( 1 );
1013
0
}
1014
1015
/* Retrieves the $SECURITY_DESCRIPTOR attribute
1016
 * Returns 1 if successful, 0 if not available or -1 on error
1017
 */
1018
int libfsntfs_internal_file_entry_get_security_descriptor_attribute(
1019
     libfsntfs_internal_file_entry_t *internal_file_entry,
1020
     libfsntfs_attribute_t **attribute,
1021
     libcerror_error_t **error )
1022
0
{
1023
0
  static char *function = "libfsntfs_internal_file_entry_get_security_descriptor_attribute";
1024
1025
0
  if( internal_file_entry == NULL )
1026
0
  {
1027
0
    libcerror_error_set(
1028
0
     error,
1029
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1030
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1031
0
     "%s: invalid file entry.",
1032
0
     function );
1033
1034
0
    return( -1 );
1035
0
  }
1036
0
  if( internal_file_entry->mft_entry == NULL )
1037
0
  {
1038
0
    libcerror_error_set(
1039
0
     error,
1040
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1041
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1042
0
     "%s: invalid file entry - missing MFT entry.",
1043
0
     function );
1044
1045
0
    return( -1 );
1046
0
  }
1047
0
  if( attribute == NULL )
1048
0
  {
1049
0
    libcerror_error_set(
1050
0
     error,
1051
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1052
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1053
0
     "%s: invalid attribute.",
1054
0
     function );
1055
1056
0
    return( -1 );
1057
0
  }
1058
0
  if( internal_file_entry->mft_entry->security_descriptor_attribute_index == -1 )
1059
0
  {
1060
0
    return( 0 );
1061
0
  }
1062
0
  if( internal_file_entry->security_descriptor_attribute == NULL )
1063
0
  {
1064
0
    if( libfsntfs_internal_file_entry_get_attribute_by_index(
1065
0
         internal_file_entry,
1066
0
         internal_file_entry->mft_entry,
1067
0
         internal_file_entry->mft_entry->security_descriptor_attribute_index,
1068
0
         &( internal_file_entry->security_descriptor_attribute ),
1069
0
         error ) != 1 )
1070
0
    {
1071
0
      libcerror_error_set(
1072
0
       error,
1073
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1074
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1075
0
       "%s: unable to retrieve attribute: %d.",
1076
0
       function,
1077
0
       internal_file_entry->mft_entry->security_descriptor_attribute_index );
1078
1079
0
      return( -1 );
1080
0
    }
1081
0
  }
1082
0
  *attribute = internal_file_entry->security_descriptor_attribute;
1083
1084
0
  return( 1 );
1085
0
}
1086
1087
/* Retrieves the $STANDARD_INFORMATION attribute
1088
 * Returns 1 if successful, 0 if not available or -1 on error
1089
 */
1090
int libfsntfs_internal_file_entry_get_standard_information_attribute(
1091
     libfsntfs_internal_file_entry_t *internal_file_entry,
1092
     libfsntfs_attribute_t **attribute,
1093
     libcerror_error_t **error )
1094
0
{
1095
0
  static char *function = "libfsntfs_internal_file_entry_get_standard_information_attribute";
1096
1097
0
  if( internal_file_entry == NULL )
1098
0
  {
1099
0
    libcerror_error_set(
1100
0
     error,
1101
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1102
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1103
0
     "%s: invalid file entry.",
1104
0
     function );
1105
1106
0
    return( -1 );
1107
0
  }
1108
0
  if( internal_file_entry->mft_entry == NULL )
1109
0
  {
1110
0
    libcerror_error_set(
1111
0
     error,
1112
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1113
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1114
0
     "%s: invalid file entry - missing MFT entry.",
1115
0
     function );
1116
1117
0
    return( -1 );
1118
0
  }
1119
0
  if( attribute == NULL )
1120
0
  {
1121
0
    libcerror_error_set(
1122
0
     error,
1123
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1124
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1125
0
     "%s: invalid attribute.",
1126
0
     function );
1127
1128
0
    return( -1 );
1129
0
  }
1130
0
  if( internal_file_entry->mft_entry->standard_information_attribute_index == -1 )
1131
0
  {
1132
0
    return( 0 );
1133
0
  }
1134
0
  if( internal_file_entry->standard_information_attribute == NULL )
1135
0
  {
1136
0
    if( libfsntfs_internal_file_entry_get_attribute_by_index(
1137
0
         internal_file_entry,
1138
0
         internal_file_entry->mft_entry,
1139
0
         internal_file_entry->mft_entry->standard_information_attribute_index,
1140
0
         &( internal_file_entry->standard_information_attribute ),
1141
0
         error ) != 1 )
1142
0
    {
1143
0
      libcerror_error_set(
1144
0
       error,
1145
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1146
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1147
0
       "%s: unable to retrieve attribute: %d.",
1148
0
       function,
1149
0
       internal_file_entry->mft_entry->standard_information_attribute_index );
1150
1151
0
      return( -1 );
1152
0
    }
1153
0
  }
1154
0
  *attribute = internal_file_entry->standard_information_attribute;
1155
1156
0
  return( 1 );
1157
0
}
1158
1159
/* Retrieves the file reference
1160
 * This value is retrieved from the MFT entry
1161
 * Returns 1 if successful or -1 on error
1162
 */
1163
int libfsntfs_file_entry_get_file_reference(
1164
     libfsntfs_file_entry_t *file_entry,
1165
     uint64_t *file_reference,
1166
     libcerror_error_t **error )
1167
0
{
1168
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
1169
0
  static char *function                                = "libfsntfs_file_entry_get_file_reference";
1170
0
  int result                                           = 1;
1171
1172
0
  if( file_entry == NULL )
1173
0
  {
1174
0
    libcerror_error_set(
1175
0
     error,
1176
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1177
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1178
0
     "%s: invalid file entry.",
1179
0
     function );
1180
1181
0
    return( -1 );
1182
0
  }
1183
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1184
1185
0
  if( file_reference == NULL )
1186
0
  {
1187
0
    libcerror_error_set(
1188
0
     error,
1189
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1190
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1191
0
     "%s: invalid file reference.",
1192
0
     function );
1193
1194
0
    return( -1 );
1195
0
  }
1196
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1197
0
  if( libcthreads_read_write_lock_grab_for_read(
1198
0
       internal_file_entry->read_write_lock,
1199
0
       error ) != 1 )
1200
0
  {
1201
0
    libcerror_error_set(
1202
0
     error,
1203
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1204
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1205
0
     "%s: unable to grab read/write lock for reading.",
1206
0
     function );
1207
1208
0
    return( -1 );
1209
0
  }
1210
0
#endif
1211
0
  if( libfsntfs_mft_entry_get_file_reference(
1212
0
       internal_file_entry->mft_entry,
1213
0
       file_reference,
1214
0
       error ) != 1 )
1215
0
  {
1216
0
    libcerror_error_set(
1217
0
     error,
1218
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1219
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1220
0
     "%s: unable to retrieve file reference from MFT entry.",
1221
0
     function );
1222
1223
0
    result = -1;
1224
0
  }
1225
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1226
0
  if( libcthreads_read_write_lock_release_for_read(
1227
0
       internal_file_entry->read_write_lock,
1228
0
       error ) != 1 )
1229
0
  {
1230
0
    libcerror_error_set(
1231
0
     error,
1232
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1233
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1234
0
     "%s: unable to release read/write lock for reading.",
1235
0
     function );
1236
1237
0
    return( -1 );
1238
0
  }
1239
0
#endif
1240
0
  return( result );
1241
0
}
1242
1243
/* Retrieves the base record file reference
1244
 * Returns 1 if successful, 0 if not available or -1 on error
1245
 */
1246
int libfsntfs_file_entry_get_base_record_file_reference(
1247
     libfsntfs_file_entry_t *file_entry,
1248
     uint64_t *file_reference,
1249
     libcerror_error_t **error )
1250
0
{
1251
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
1252
0
  static char *function                                = "libfsntfs_file_entry_get_base_record_file_reference";
1253
0
  int result                                           = 1;
1254
1255
0
  if( file_entry == NULL )
1256
0
  {
1257
0
    libcerror_error_set(
1258
0
     error,
1259
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1260
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1261
0
     "%s: invalid file entry.",
1262
0
     function );
1263
1264
0
    return( -1 );
1265
0
  }
1266
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1267
1268
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1269
0
  if( libcthreads_read_write_lock_grab_for_read(
1270
0
       internal_file_entry->read_write_lock,
1271
0
       error ) != 1 )
1272
0
  {
1273
0
    libcerror_error_set(
1274
0
     error,
1275
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1276
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1277
0
     "%s: unable to grab read/write lock for reading.",
1278
0
     function );
1279
1280
0
    return( -1 );
1281
0
  }
1282
0
#endif
1283
0
  result = libfsntfs_mft_entry_get_base_record_file_reference(
1284
0
            internal_file_entry->mft_entry,
1285
0
            file_reference,
1286
0
            error );
1287
1288
0
  if( result == -1 )
1289
0
  {
1290
0
    libcerror_error_set(
1291
0
     error,
1292
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1293
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1294
0
     "%s: unable to retrieve base record file reference from MFT entry.",
1295
0
     function );
1296
1297
0
    result = -1;
1298
0
  }
1299
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1300
0
  if( libcthreads_read_write_lock_release_for_read(
1301
0
       internal_file_entry->read_write_lock,
1302
0
       error ) != 1 )
1303
0
  {
1304
0
    libcerror_error_set(
1305
0
     error,
1306
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1307
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1308
0
     "%s: unable to release read/write lock for reading.",
1309
0
     function );
1310
1311
0
    return( -1 );
1312
0
  }
1313
0
#endif
1314
0
  return( result );
1315
0
}
1316
1317
/* Retrieves the parent file reference
1318
 * This value is retrieved from the directory entry $FILE_NAME attribute
1319
 * Returns 1 if successful, 0 if not available or -1 on error
1320
 */
1321
int libfsntfs_file_entry_get_parent_file_reference(
1322
     libfsntfs_file_entry_t *file_entry,
1323
     uint64_t *parent_file_reference,
1324
     libcerror_error_t **error )
1325
0
{
1326
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
1327
0
  static char *function                                = "libfsntfs_file_entry_get_parent_file_reference";
1328
0
  int result                                           = 0;
1329
1330
0
  if( file_entry == NULL )
1331
0
  {
1332
0
    libcerror_error_set(
1333
0
     error,
1334
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1335
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1336
0
     "%s: invalid file entry.",
1337
0
     function );
1338
1339
0
    return( -1 );
1340
0
  }
1341
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1342
1343
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1344
0
  if( libcthreads_read_write_lock_grab_for_read(
1345
0
       internal_file_entry->read_write_lock,
1346
0
       error ) != 1 )
1347
0
  {
1348
0
    libcerror_error_set(
1349
0
     error,
1350
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1351
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1352
0
     "%s: unable to grab read/write lock for reading.",
1353
0
     function );
1354
1355
0
    return( -1 );
1356
0
  }
1357
0
#endif
1358
0
  if( internal_file_entry->directory_entry != NULL )
1359
0
  {
1360
0
    result = libfsntfs_directory_entry_get_parent_file_reference(
1361
0
              internal_file_entry->directory_entry,
1362
0
              parent_file_reference,
1363
0
              error );
1364
1365
0
    if( result != 1 )
1366
0
    {
1367
0
      libcerror_error_set(
1368
0
       error,
1369
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1370
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1371
0
       "%s: unable to retrieve parent reference from directory entry.",
1372
0
       function );
1373
1374
0
      result = -1;
1375
0
    }
1376
0
  }
1377
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1378
0
  if( libcthreads_read_write_lock_release_for_read(
1379
0
       internal_file_entry->read_write_lock,
1380
0
       error ) != 1 )
1381
0
  {
1382
0
    libcerror_error_set(
1383
0
     error,
1384
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1385
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1386
0
     "%s: unable to release read/write lock for reading.",
1387
0
     function );
1388
1389
0
    return( -1 );
1390
0
  }
1391
0
#endif
1392
0
  return( result );
1393
0
}
1394
1395
/* Retrieves the parent file reference for a specific $FILE_NAME attribute
1396
 * Returns 1 if successful or -1 on error
1397
 */
1398
int libfsntfs_file_entry_get_parent_file_reference_by_attribute_index(
1399
     libfsntfs_file_entry_t *file_entry,
1400
     int attribute_index,
1401
     uint64_t *parent_file_reference,
1402
     libcerror_error_t **error )
1403
0
{
1404
0
  libfsntfs_attribute_t *attribute                     = NULL;
1405
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
1406
0
  static char *function                                = "libfsntfs_file_entry_get_parent_file_reference_by_attribute_index";
1407
0
  int result                                           = 1;
1408
1409
0
  if( file_entry == NULL )
1410
0
  {
1411
0
    libcerror_error_set(
1412
0
     error,
1413
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1414
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1415
0
     "%s: invalid file entry.",
1416
0
     function );
1417
1418
0
    return( -1 );
1419
0
  }
1420
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1421
1422
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1423
0
  if( libcthreads_read_write_lock_grab_for_read(
1424
0
       internal_file_entry->read_write_lock,
1425
0
       error ) != 1 )
1426
0
  {
1427
0
    libcerror_error_set(
1428
0
     error,
1429
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1430
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1431
0
     "%s: unable to grab read/write lock for reading.",
1432
0
     function );
1433
1434
0
    return( -1 );
1435
0
  }
1436
0
#endif
1437
0
  if( libfsntfs_internal_file_entry_get_attribute_by_index(
1438
0
       internal_file_entry,
1439
0
       internal_file_entry->mft_entry,
1440
0
       attribute_index,
1441
0
       &attribute,
1442
0
       error ) != 1 )
1443
0
  {
1444
0
    libcerror_error_set(
1445
0
     error,
1446
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1447
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1448
0
     "%s: unable to retrieve attribute: %d.",
1449
0
     function,
1450
0
     attribute_index );
1451
1452
0
    result = -1;
1453
0
  }
1454
0
  else if( libfsntfs_file_name_attribute_get_parent_file_reference(
1455
0
            attribute,
1456
0
            parent_file_reference,
1457
0
            error ) != 1 )
1458
0
  {
1459
0
    libcerror_error_set(
1460
0
     error,
1461
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1462
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1463
0
     "%s: unable to retrieve parent reference from $FILE_NAME attribute.",
1464
0
     function );
1465
1466
0
    result = -1;
1467
0
  }
1468
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1469
0
  if( libcthreads_read_write_lock_release_for_read(
1470
0
       internal_file_entry->read_write_lock,
1471
0
       error ) != 1 )
1472
0
  {
1473
0
    libcerror_error_set(
1474
0
     error,
1475
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1476
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1477
0
     "%s: unable to release read/write lock for reading.",
1478
0
     function );
1479
1480
0
    return( -1 );
1481
0
  }
1482
0
#endif
1483
0
  return( result );
1484
0
}
1485
1486
/* Retrieves the journal sequence number
1487
 * Returns 1 if successful or -1 on error
1488
 */
1489
int libfsntfs_file_entry_get_journal_sequence_number(
1490
     libfsntfs_file_entry_t *file_entry,
1491
     uint64_t *journal_sequence_number,
1492
     libcerror_error_t **error )
1493
0
{
1494
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
1495
0
  static char *function                                = "libfsntfs_file_entry_get_journal_sequence_number";
1496
0
  int result                                           = 1;
1497
1498
0
  if( file_entry == NULL )
1499
0
  {
1500
0
    libcerror_error_set(
1501
0
     error,
1502
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1503
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1504
0
     "%s: invalid file entry.",
1505
0
     function );
1506
1507
0
    return( -1 );
1508
0
  }
1509
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1510
1511
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1512
0
  if( libcthreads_read_write_lock_grab_for_read(
1513
0
       internal_file_entry->read_write_lock,
1514
0
       error ) != 1 )
1515
0
  {
1516
0
    libcerror_error_set(
1517
0
     error,
1518
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1519
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1520
0
     "%s: unable to grab read/write lock for reading.",
1521
0
     function );
1522
1523
0
    return( -1 );
1524
0
  }
1525
0
#endif
1526
0
  if( libfsntfs_mft_entry_get_journal_sequence_number(
1527
0
       internal_file_entry->mft_entry,
1528
0
       journal_sequence_number,
1529
0
       error ) != 1 )
1530
0
  {
1531
0
    libcerror_error_set(
1532
0
     error,
1533
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1534
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1535
0
     "%s: unable to retrieve journal sequence number from MFT entry.",
1536
0
     function );
1537
1538
0
    result = -1;
1539
0
  }
1540
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1541
0
  if( libcthreads_read_write_lock_release_for_read(
1542
0
       internal_file_entry->read_write_lock,
1543
0
       error ) != 1 )
1544
0
  {
1545
0
    libcerror_error_set(
1546
0
     error,
1547
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1548
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1549
0
     "%s: unable to release read/write lock for reading.",
1550
0
     function );
1551
1552
0
    return( -1 );
1553
0
  }
1554
0
#endif
1555
0
  return( result );
1556
0
}
1557
1558
/* Retrieves the creation date and time
1559
 * This value is retrieved from the $STANDARD_INFORMATION attribute
1560
 * Returns 1 if successful, 0 if not available or -1 on error
1561
 */
1562
int libfsntfs_file_entry_get_creation_time(
1563
     libfsntfs_file_entry_t *file_entry,
1564
     uint64_t *filetime,
1565
     libcerror_error_t **error )
1566
0
{
1567
0
  libfsntfs_attribute_t *standard_information_attribute                = NULL;
1568
0
  libfsntfs_internal_file_entry_t *internal_file_entry                 = NULL;
1569
0
  libfsntfs_standard_information_values_t *standard_information_values = NULL;
1570
0
  static char *function                                                = "libfsntfs_file_entry_get_creation_time";
1571
0
  int result                                                           = 0;
1572
1573
0
  if( file_entry == NULL )
1574
0
  {
1575
0
    libcerror_error_set(
1576
0
     error,
1577
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1578
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1579
0
     "%s: invalid file entry.",
1580
0
     function );
1581
1582
0
    return( -1 );
1583
0
  }
1584
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1585
1586
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1587
0
  if( libcthreads_read_write_lock_grab_for_read(
1588
0
       internal_file_entry->read_write_lock,
1589
0
       error ) != 1 )
1590
0
  {
1591
0
    libcerror_error_set(
1592
0
     error,
1593
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1594
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1595
0
     "%s: unable to grab read/write lock for reading.",
1596
0
     function );
1597
1598
0
    return( -1 );
1599
0
  }
1600
0
#endif
1601
0
  result = libfsntfs_internal_file_entry_get_standard_information_attribute(
1602
0
            internal_file_entry,
1603
0
            &standard_information_attribute,
1604
0
            error );
1605
1606
0
  if( result == -1 )
1607
0
  {
1608
0
    libcerror_error_set(
1609
0
     error,
1610
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1611
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1612
0
     "%s: unable to retrieve standard information attribute.",
1613
0
     function );
1614
1615
0
    result = -1;
1616
0
  }
1617
0
  else if( result != 0 )
1618
0
  {
1619
0
    if( libfsntfs_internal_attribute_get_value(
1620
0
         (libfsntfs_internal_attribute_t *) standard_information_attribute,
1621
0
         (intptr_t **) &standard_information_values,
1622
0
         error ) != 1 )
1623
0
    {
1624
0
      libcerror_error_set(
1625
0
       error,
1626
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1627
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1628
0
       "%s: unable to retrieve value from standard information attribute.",
1629
0
       function );
1630
1631
0
      result = -1;
1632
0
    }
1633
0
    else if( libfsntfs_standard_information_values_get_creation_time(
1634
0
              standard_information_values,
1635
0
              filetime,
1636
0
              error ) != 1 )
1637
0
    {
1638
0
      libcerror_error_set(
1639
0
       error,
1640
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1641
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1642
0
       "%s: unable to retrieve creation time from standard information attribute.",
1643
0
       function );
1644
1645
0
      result = -1;
1646
0
    }
1647
0
  }
1648
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1649
0
  if( libcthreads_read_write_lock_release_for_read(
1650
0
       internal_file_entry->read_write_lock,
1651
0
       error ) != 1 )
1652
0
  {
1653
0
    libcerror_error_set(
1654
0
     error,
1655
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1656
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1657
0
     "%s: unable to release read/write lock for reading.",
1658
0
     function );
1659
1660
0
    return( -1 );
1661
0
  }
1662
0
#endif
1663
0
  return( result );
1664
0
}
1665
1666
/* Retrieves the (file) modification (last written) date and time
1667
 * This value is retrieved from the $STANDARD_INFORMATION attribute
1668
 * Returns 1 if successful, 0 if not available or -1 on error
1669
 */
1670
int libfsntfs_file_entry_get_modification_time(
1671
     libfsntfs_file_entry_t *file_entry,
1672
     uint64_t *filetime,
1673
     libcerror_error_t **error )
1674
0
{
1675
0
  libfsntfs_attribute_t *standard_information_attribute                = NULL;
1676
0
  libfsntfs_internal_file_entry_t *internal_file_entry                 = NULL;
1677
0
  libfsntfs_standard_information_values_t *standard_information_values = NULL;
1678
0
  static char *function                                                = "libfsntfs_file_entry_get_modification_time";
1679
0
  int result                                                           = 0;
1680
1681
0
  if( file_entry == NULL )
1682
0
  {
1683
0
    libcerror_error_set(
1684
0
     error,
1685
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1686
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1687
0
     "%s: invalid file entry.",
1688
0
     function );
1689
1690
0
    return( -1 );
1691
0
  }
1692
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1693
1694
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1695
0
  if( libcthreads_read_write_lock_grab_for_read(
1696
0
       internal_file_entry->read_write_lock,
1697
0
       error ) != 1 )
1698
0
  {
1699
0
    libcerror_error_set(
1700
0
     error,
1701
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1702
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1703
0
     "%s: unable to grab read/write lock for reading.",
1704
0
     function );
1705
1706
0
    return( -1 );
1707
0
  }
1708
0
#endif
1709
0
  result = libfsntfs_internal_file_entry_get_standard_information_attribute(
1710
0
            internal_file_entry,
1711
0
            &standard_information_attribute,
1712
0
            error );
1713
1714
0
  if( result == -1 )
1715
0
  {
1716
0
    libcerror_error_set(
1717
0
     error,
1718
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1719
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1720
0
     "%s: unable to retrieve standard information attribute.",
1721
0
     function );
1722
1723
0
    result = -1;
1724
0
  }
1725
0
  else if( result != 0 )
1726
0
  {
1727
0
    if( libfsntfs_internal_attribute_get_value(
1728
0
         (libfsntfs_internal_attribute_t *) standard_information_attribute,
1729
0
         (intptr_t **) &standard_information_values,
1730
0
         error ) != 1 )
1731
0
    {
1732
0
      libcerror_error_set(
1733
0
       error,
1734
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1735
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1736
0
       "%s: unable to retrieve standard information attribute value.",
1737
0
       function );
1738
1739
0
      result = -1;
1740
0
    }
1741
0
    else if( libfsntfs_standard_information_values_get_modification_time(
1742
0
              standard_information_values,
1743
0
              filetime,
1744
0
              error ) != 1 )
1745
0
    {
1746
0
      libcerror_error_set(
1747
0
       error,
1748
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1749
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1750
0
       "%s: unable to retrieve modification time from standard information attribute.",
1751
0
       function );
1752
1753
0
      result = -1;
1754
0
    }
1755
0
  }
1756
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1757
0
  if( libcthreads_read_write_lock_release_for_read(
1758
0
       internal_file_entry->read_write_lock,
1759
0
       error ) != 1 )
1760
0
  {
1761
0
    libcerror_error_set(
1762
0
     error,
1763
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1764
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1765
0
     "%s: unable to release read/write lock for reading.",
1766
0
     function );
1767
1768
0
    return( -1 );
1769
0
  }
1770
0
#endif
1771
0
  return( result );
1772
0
}
1773
1774
/* Retrieves the access date and time
1775
 * This value is retrieved from the $STANDARD_INFORMATION attribute
1776
 * Returns 1 if successful, 0 if not available or -1 on error
1777
 */
1778
int libfsntfs_file_entry_get_access_time(
1779
     libfsntfs_file_entry_t *file_entry,
1780
     uint64_t *filetime,
1781
     libcerror_error_t **error )
1782
0
{
1783
0
  libfsntfs_attribute_t *standard_information_attribute                = NULL;
1784
0
  libfsntfs_internal_file_entry_t *internal_file_entry                 = NULL;
1785
0
  libfsntfs_standard_information_values_t *standard_information_values = NULL;
1786
0
  static char *function                                                = "libfsntfs_file_entry_get_access_time";
1787
0
  int result                                                           = 0;
1788
1789
0
  if( file_entry == NULL )
1790
0
  {
1791
0
    libcerror_error_set(
1792
0
     error,
1793
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1794
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1795
0
     "%s: invalid file entry.",
1796
0
     function );
1797
1798
0
    return( -1 );
1799
0
  }
1800
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1801
1802
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1803
0
  if( libcthreads_read_write_lock_grab_for_read(
1804
0
       internal_file_entry->read_write_lock,
1805
0
       error ) != 1 )
1806
0
  {
1807
0
    libcerror_error_set(
1808
0
     error,
1809
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1810
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1811
0
     "%s: unable to grab read/write lock for reading.",
1812
0
     function );
1813
1814
0
    return( -1 );
1815
0
  }
1816
0
#endif
1817
0
  result = libfsntfs_internal_file_entry_get_standard_information_attribute(
1818
0
            internal_file_entry,
1819
0
            &standard_information_attribute,
1820
0
            error );
1821
1822
0
  if( result == -1 )
1823
0
  {
1824
0
    libcerror_error_set(
1825
0
     error,
1826
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1827
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1828
0
     "%s: unable to retrieve standard information attribute.",
1829
0
     function );
1830
1831
0
    result = -1;
1832
0
  }
1833
0
  else if( result != 0 )
1834
0
  {
1835
0
    if( libfsntfs_internal_attribute_get_value(
1836
0
         (libfsntfs_internal_attribute_t *) standard_information_attribute,
1837
0
         (intptr_t **) &standard_information_values,
1838
0
         error ) != 1 )
1839
0
    {
1840
0
      libcerror_error_set(
1841
0
       error,
1842
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1843
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1844
0
       "%s: unable to retrieve standard information attribute value.",
1845
0
       function );
1846
1847
0
      result = -1;
1848
0
    }
1849
0
    else if( libfsntfs_standard_information_values_get_access_time(
1850
0
              standard_information_values,
1851
0
              filetime,
1852
0
              error ) != 1 )
1853
0
    {
1854
0
      libcerror_error_set(
1855
0
       error,
1856
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1857
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1858
0
       "%s: unable to retrieve access time from standard information attribute.",
1859
0
       function );
1860
1861
0
      result = -1;
1862
0
    }
1863
0
  }
1864
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1865
0
  if( libcthreads_read_write_lock_release_for_read(
1866
0
       internal_file_entry->read_write_lock,
1867
0
       error ) != 1 )
1868
0
  {
1869
0
    libcerror_error_set(
1870
0
     error,
1871
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1872
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1873
0
     "%s: unable to release read/write lock for reading.",
1874
0
     function );
1875
1876
0
    return( -1 );
1877
0
  }
1878
0
#endif
1879
0
  return( result );
1880
0
}
1881
1882
/* Retrieves the (file system entry) modification date and time
1883
 * This value is retrieved from the $STANDARD_INFORMATION attribute
1884
 * Returns 1 if successful, 0 if not available or -1 on error
1885
 */
1886
int libfsntfs_file_entry_get_entry_modification_time(
1887
     libfsntfs_file_entry_t *file_entry,
1888
     uint64_t *filetime,
1889
     libcerror_error_t **error )
1890
0
{
1891
0
  libfsntfs_attribute_t *standard_information_attribute                = NULL;
1892
0
  libfsntfs_internal_file_entry_t *internal_file_entry                 = NULL;
1893
0
  libfsntfs_standard_information_values_t *standard_information_values = NULL;
1894
0
  static char *function                                                = "libfsntfs_file_entry_get_entry_modification_time";
1895
0
  int result                                                           = 0;
1896
1897
0
  if( file_entry == NULL )
1898
0
  {
1899
0
    libcerror_error_set(
1900
0
     error,
1901
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1902
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1903
0
     "%s: invalid file entry.",
1904
0
     function );
1905
1906
0
    return( -1 );
1907
0
  }
1908
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1909
1910
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1911
0
  if( libcthreads_read_write_lock_grab_for_read(
1912
0
       internal_file_entry->read_write_lock,
1913
0
       error ) != 1 )
1914
0
  {
1915
0
    libcerror_error_set(
1916
0
     error,
1917
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1918
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1919
0
     "%s: unable to grab read/write lock for reading.",
1920
0
     function );
1921
1922
0
    return( -1 );
1923
0
  }
1924
0
#endif
1925
0
  result = libfsntfs_internal_file_entry_get_standard_information_attribute(
1926
0
            internal_file_entry,
1927
0
            &standard_information_attribute,
1928
0
            error );
1929
1930
0
  if( result == -1 )
1931
0
  {
1932
0
    libcerror_error_set(
1933
0
     error,
1934
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1935
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1936
0
     "%s: unable to retrieve standard information attribute.",
1937
0
     function );
1938
1939
0
    result = -1;
1940
0
  }
1941
0
  else if( result != 0 )
1942
0
  {
1943
0
    if( libfsntfs_internal_attribute_get_value(
1944
0
         (libfsntfs_internal_attribute_t *) standard_information_attribute,
1945
0
         (intptr_t **) &standard_information_values,
1946
0
         error ) != 1 )
1947
0
    {
1948
0
      libcerror_error_set(
1949
0
       error,
1950
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1951
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1952
0
       "%s: unable to retrieve standard information attribute value.",
1953
0
       function );
1954
1955
0
      result = -1;
1956
0
    }
1957
0
    else if( libfsntfs_standard_information_values_get_entry_modification_time(
1958
0
              standard_information_values,
1959
0
              filetime,
1960
0
              error ) != 1 )
1961
0
    {
1962
0
      libcerror_error_set(
1963
0
       error,
1964
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1965
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1966
0
       "%s: unable to retrieve entry modification time from standard information attribute.",
1967
0
       function );
1968
1969
0
      result = -1;
1970
0
    }
1971
0
  }
1972
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1973
0
  if( libcthreads_read_write_lock_release_for_read(
1974
0
       internal_file_entry->read_write_lock,
1975
0
       error ) != 1 )
1976
0
  {
1977
0
    libcerror_error_set(
1978
0
     error,
1979
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1980
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1981
0
     "%s: unable to release read/write lock for reading.",
1982
0
     function );
1983
1984
0
    return( -1 );
1985
0
  }
1986
0
#endif
1987
0
  return( result );
1988
0
}
1989
1990
/* Retrieves the file attribute flags
1991
 * This value is retrieved from the $STANDARD_INFORMATION attribute
1992
 * Returns 1 if successful, 0 if not available or -1 on error
1993
 */
1994
int libfsntfs_file_entry_get_file_attribute_flags(
1995
     libfsntfs_file_entry_t *file_entry,
1996
     uint32_t *file_attribute_flags,
1997
     libcerror_error_t **error )
1998
0
{
1999
0
  libfsntfs_attribute_t *standard_information_attribute                = NULL;
2000
0
  libfsntfs_internal_file_entry_t *internal_file_entry                 = NULL;
2001
0
  libfsntfs_standard_information_values_t *standard_information_values = NULL;
2002
0
  static char *function                                                = "libfsntfs_file_entry_get_file_attribute_flags";
2003
0
  int result                                                           = 0;
2004
2005
0
  if( file_entry == NULL )
2006
0
  {
2007
0
    libcerror_error_set(
2008
0
     error,
2009
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2010
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2011
0
     "%s: invalid file entry.",
2012
0
     function );
2013
2014
0
    return( -1 );
2015
0
  }
2016
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2017
2018
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2019
0
  if( libcthreads_read_write_lock_grab_for_read(
2020
0
       internal_file_entry->read_write_lock,
2021
0
       error ) != 1 )
2022
0
  {
2023
0
    libcerror_error_set(
2024
0
     error,
2025
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2026
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2027
0
     "%s: unable to grab read/write lock for reading.",
2028
0
     function );
2029
2030
0
    return( -1 );
2031
0
  }
2032
0
#endif
2033
0
  result = libfsntfs_internal_file_entry_get_standard_information_attribute(
2034
0
            internal_file_entry,
2035
0
            &standard_information_attribute,
2036
0
            error );
2037
2038
0
  if( result == -1 )
2039
0
  {
2040
0
    libcerror_error_set(
2041
0
     error,
2042
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2043
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2044
0
     "%s: unable to retrieve standard information attribute.",
2045
0
     function );
2046
2047
0
    result = -1;
2048
0
  }
2049
0
  else if( result != 0 )
2050
0
  {
2051
0
    if( libfsntfs_internal_attribute_get_value(
2052
0
         (libfsntfs_internal_attribute_t *) standard_information_attribute,
2053
0
         (intptr_t **) &standard_information_values,
2054
0
         error ) != 1 )
2055
0
    {
2056
0
      libcerror_error_set(
2057
0
       error,
2058
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2059
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2060
0
       "%s: unable to retrieve standard information attribute value.",
2061
0
       function );
2062
2063
0
      result = -1;
2064
0
    }
2065
0
    else if( libfsntfs_standard_information_values_get_file_attribute_flags(
2066
0
              standard_information_values,
2067
0
              file_attribute_flags,
2068
0
              error ) != 1 )
2069
0
    {
2070
0
      libcerror_error_set(
2071
0
       error,
2072
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2073
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2074
0
       "%s: unable to retrieve file attribute flags from standard information attribute.",
2075
0
       function );
2076
2077
0
      result = -1;
2078
0
    }
2079
0
  }
2080
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2081
0
  if( libcthreads_read_write_lock_release_for_read(
2082
0
       internal_file_entry->read_write_lock,
2083
0
       error ) != 1 )
2084
0
  {
2085
0
    libcerror_error_set(
2086
0
     error,
2087
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2088
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2089
0
     "%s: unable to release read/write lock for reading.",
2090
0
     function );
2091
2092
0
    return( -1 );
2093
0
  }
2094
0
#endif
2095
0
  return( result );
2096
0
}
2097
2098
/* Retrieves the file reference
2099
 * This value is retrieved from the $I30 $FILE_NAME directory entry
2100
 * Returns 1 if successful, 0 if not available or -1 on error
2101
 */
2102
int libfsntfs_file_entry_get_i30_file_reference(
2103
     libfsntfs_file_entry_t *file_entry,
2104
     uint64_t *file_reference,
2105
     libcerror_error_t **error )
2106
0
{
2107
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2108
0
  static char *function                                = "libfsntfs_file_entry_get_i30_file_reference";
2109
0
  int result                                           = 0;
2110
2111
0
  if( file_entry == NULL )
2112
0
  {
2113
0
    libcerror_error_set(
2114
0
     error,
2115
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2116
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2117
0
     "%s: invalid file entry.",
2118
0
     function );
2119
2120
0
    return( -1 );
2121
0
  }
2122
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2123
2124
0
  if( file_reference == NULL )
2125
0
  {
2126
0
    libcerror_error_set(
2127
0
     error,
2128
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2129
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2130
0
     "%s: invalid file reference.",
2131
0
     function );
2132
2133
0
    return( -1 );
2134
0
  }
2135
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2136
0
  if( libcthreads_read_write_lock_grab_for_read(
2137
0
       internal_file_entry->read_write_lock,
2138
0
       error ) != 1 )
2139
0
  {
2140
0
    libcerror_error_set(
2141
0
     error,
2142
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2143
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2144
0
     "%s: unable to grab read/write lock for reading.",
2145
0
     function );
2146
2147
0
    return( -1 );
2148
0
  }
2149
0
#endif
2150
0
  if( internal_file_entry->directory_entry != NULL )
2151
0
  {
2152
0
    result = libfsntfs_directory_entry_get_file_reference(
2153
0
              internal_file_entry->directory_entry,
2154
0
              file_reference,
2155
0
              error );
2156
2157
0
    if( result != 1 )
2158
0
    {
2159
0
      libcerror_error_set(
2160
0
       error,
2161
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2162
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2163
0
       "%s: unable to retrieve file reference from directory entry.",
2164
0
       function );
2165
2166
0
      result = -1;
2167
0
    }
2168
0
  }
2169
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2170
0
  if( libcthreads_read_write_lock_release_for_read(
2171
0
       internal_file_entry->read_write_lock,
2172
0
       error ) != 1 )
2173
0
  {
2174
0
    libcerror_error_set(
2175
0
     error,
2176
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2177
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2178
0
     "%s: unable to release read/write lock for reading.",
2179
0
     function );
2180
2181
0
    return( -1 );
2182
0
  }
2183
0
#endif
2184
0
  return( result );
2185
0
}
2186
2187
/* Retrieves the creation date and time
2188
 * This value is retrieved from the $I30 $FILE_NAME directory entry
2189
 * Returns 1 if successful, 0 if not available or -1 on error
2190
 */
2191
int libfsntfs_file_entry_get_i30_creation_time(
2192
     libfsntfs_file_entry_t *file_entry,
2193
     uint64_t *filetime,
2194
     libcerror_error_t **error )
2195
0
{
2196
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2197
0
  static char *function                                = "libfsntfs_file_entry_get_i30_creation_time";
2198
0
  int result                                           = 0;
2199
2200
0
  if( file_entry == NULL )
2201
0
  {
2202
0
    libcerror_error_set(
2203
0
     error,
2204
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2205
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2206
0
     "%s: invalid file entry.",
2207
0
     function );
2208
2209
0
    return( -1 );
2210
0
  }
2211
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2212
2213
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2214
0
  if( libcthreads_read_write_lock_grab_for_read(
2215
0
       internal_file_entry->read_write_lock,
2216
0
       error ) != 1 )
2217
0
  {
2218
0
    libcerror_error_set(
2219
0
     error,
2220
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2221
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2222
0
     "%s: unable to grab read/write lock for reading.",
2223
0
     function );
2224
2225
0
    return( -1 );
2226
0
  }
2227
0
#endif
2228
0
  if( internal_file_entry->directory_entry != NULL )
2229
0
  {
2230
0
    result = libfsntfs_directory_entry_get_creation_time(
2231
0
              internal_file_entry->directory_entry,
2232
0
              filetime,
2233
0
              error );
2234
2235
0
    if( result != 1 )
2236
0
    {
2237
0
      libcerror_error_set(
2238
0
       error,
2239
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2240
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2241
0
       "%s: unable to retrieve creation time from directory entry.",
2242
0
       function );
2243
2244
0
      result = -1;
2245
0
    }
2246
0
  }
2247
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2248
0
  if( libcthreads_read_write_lock_release_for_read(
2249
0
       internal_file_entry->read_write_lock,
2250
0
       error ) != 1 )
2251
0
  {
2252
0
    libcerror_error_set(
2253
0
     error,
2254
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2255
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2256
0
     "%s: unable to release read/write lock for reading.",
2257
0
     function );
2258
2259
0
    return( -1 );
2260
0
  }
2261
0
#endif
2262
0
  return( result );
2263
0
}
2264
2265
/* Retrieves the modification date and time
2266
 * This value is retrieved from the $I30 $FILE_NAME directory entry
2267
 * Returns 1 if successful, 0 if not available or -1 on error
2268
 */
2269
int libfsntfs_file_entry_get_i30_modification_time(
2270
     libfsntfs_file_entry_t *file_entry,
2271
     uint64_t *filetime,
2272
     libcerror_error_t **error )
2273
0
{
2274
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2275
0
  static char *function                                = "libfsntfs_file_entry_get_i30_modification_time";
2276
0
  int result                                           = 0;
2277
2278
0
  if( file_entry == NULL )
2279
0
  {
2280
0
    libcerror_error_set(
2281
0
     error,
2282
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2283
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2284
0
     "%s: invalid file entry.",
2285
0
     function );
2286
2287
0
    return( -1 );
2288
0
  }
2289
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2290
2291
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2292
0
  if( libcthreads_read_write_lock_grab_for_read(
2293
0
       internal_file_entry->read_write_lock,
2294
0
       error ) != 1 )
2295
0
  {
2296
0
    libcerror_error_set(
2297
0
     error,
2298
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2299
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2300
0
     "%s: unable to grab read/write lock for reading.",
2301
0
     function );
2302
2303
0
    return( -1 );
2304
0
  }
2305
0
#endif
2306
0
  if( internal_file_entry->directory_entry != NULL )
2307
0
  {
2308
0
    result = libfsntfs_directory_entry_get_modification_time(
2309
0
              internal_file_entry->directory_entry,
2310
0
              filetime,
2311
0
              error );
2312
2313
0
    if( result != 1 )
2314
0
    {
2315
0
      libcerror_error_set(
2316
0
       error,
2317
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2318
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2319
0
       "%s: unable to retrieve modification time from directory entry.",
2320
0
       function );
2321
2322
0
      result = -1;
2323
0
    }
2324
0
  }
2325
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2326
0
  if( libcthreads_read_write_lock_release_for_read(
2327
0
       internal_file_entry->read_write_lock,
2328
0
       error ) != 1 )
2329
0
  {
2330
0
    libcerror_error_set(
2331
0
     error,
2332
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2333
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2334
0
     "%s: unable to release read/write lock for reading.",
2335
0
     function );
2336
2337
0
    return( -1 );
2338
0
  }
2339
0
#endif
2340
0
  return( result );
2341
0
}
2342
2343
/* Retrieves the access date and time
2344
 * This value is retrieved from the $I30 $FILE_NAME directory entry
2345
 * Returns 1 if successful, 0 if not available or -1 on error
2346
 */
2347
int libfsntfs_file_entry_get_i30_access_time(
2348
     libfsntfs_file_entry_t *file_entry,
2349
     uint64_t *filetime,
2350
     libcerror_error_t **error )
2351
0
{
2352
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2353
0
  static char *function                                = "libfsntfs_file_entry_get_i30_access_time";
2354
0
  int result                                           = 0;
2355
2356
0
  if( file_entry == NULL )
2357
0
  {
2358
0
    libcerror_error_set(
2359
0
     error,
2360
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2361
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2362
0
     "%s: invalid file entry.",
2363
0
     function );
2364
2365
0
    return( -1 );
2366
0
  }
2367
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2368
2369
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2370
0
  if( libcthreads_read_write_lock_grab_for_read(
2371
0
       internal_file_entry->read_write_lock,
2372
0
       error ) != 1 )
2373
0
  {
2374
0
    libcerror_error_set(
2375
0
     error,
2376
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2377
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2378
0
     "%s: unable to grab read/write lock for reading.",
2379
0
     function );
2380
2381
0
    return( -1 );
2382
0
  }
2383
0
#endif
2384
0
  if( internal_file_entry->directory_entry != NULL )
2385
0
  {
2386
0
    result = libfsntfs_directory_entry_get_access_time(
2387
0
              internal_file_entry->directory_entry,
2388
0
              filetime,
2389
0
              error );
2390
2391
0
    if( result != 1 )
2392
0
    {
2393
0
      libcerror_error_set(
2394
0
       error,
2395
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2396
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2397
0
       "%s: unable to retrieve access time from directory entry.",
2398
0
       function );
2399
2400
0
      result = -1;
2401
0
    }
2402
0
  }
2403
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2404
0
  if( libcthreads_read_write_lock_release_for_read(
2405
0
       internal_file_entry->read_write_lock,
2406
0
       error ) != 1 )
2407
0
  {
2408
0
    libcerror_error_set(
2409
0
     error,
2410
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2411
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2412
0
     "%s: unable to release read/write lock for reading.",
2413
0
     function );
2414
2415
0
    return( -1 );
2416
0
  }
2417
0
#endif
2418
0
  return( result );
2419
0
}
2420
2421
/* Retrieves the entry modification date and time
2422
 * This value is retrieved from the $I30 $FILE_NAME directory entry
2423
 * Returns 1 if successful, 0 if not available or -1 on error
2424
 */
2425
int libfsntfs_file_entry_get_i30_entry_modification_time(
2426
     libfsntfs_file_entry_t *file_entry,
2427
     uint64_t *filetime,
2428
     libcerror_error_t **error )
2429
0
{
2430
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2431
0
  static char *function                                = "libfsntfs_file_entry_get_i30_entry_modification_time";
2432
0
  int result                                           = 0;
2433
2434
0
  if( file_entry == NULL )
2435
0
  {
2436
0
    libcerror_error_set(
2437
0
     error,
2438
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2439
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2440
0
     "%s: invalid file entry.",
2441
0
     function );
2442
2443
0
    return( -1 );
2444
0
  }
2445
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2446
2447
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2448
0
  if( libcthreads_read_write_lock_grab_for_read(
2449
0
       internal_file_entry->read_write_lock,
2450
0
       error ) != 1 )
2451
0
  {
2452
0
    libcerror_error_set(
2453
0
     error,
2454
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2455
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2456
0
     "%s: unable to grab read/write lock for reading.",
2457
0
     function );
2458
2459
0
    return( -1 );
2460
0
  }
2461
0
#endif
2462
0
  if( internal_file_entry->directory_entry != NULL )
2463
0
  {
2464
0
    result = libfsntfs_directory_entry_get_entry_modification_time(
2465
0
              internal_file_entry->directory_entry,
2466
0
              filetime,
2467
0
              error );
2468
2469
0
    if( result != 1 )
2470
0
    {
2471
0
      libcerror_error_set(
2472
0
       error,
2473
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2474
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2475
0
       "%s: unable to retrieve entry modification time from directory entry.",
2476
0
       function );
2477
2478
0
      result = -1;
2479
0
    }
2480
0
  }
2481
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2482
0
  if( libcthreads_read_write_lock_release_for_read(
2483
0
       internal_file_entry->read_write_lock,
2484
0
       error ) != 1 )
2485
0
  {
2486
0
    libcerror_error_set(
2487
0
     error,
2488
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2489
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2490
0
     "%s: unable to release read/write lock for reading.",
2491
0
     function );
2492
2493
0
    return( -1 );
2494
0
  }
2495
0
#endif
2496
0
  return( result );
2497
0
}
2498
2499
/* Retrieves the size
2500
 * This value is retrieved from the $I30 $FILE_NAME directory entry
2501
 * Returns 1 if successful, 0 if not available or -1 on error
2502
 */
2503
int libfsntfs_file_entry_get_i30_size(
2504
     libfsntfs_file_entry_t *file_entry,
2505
     uint64_t *size,
2506
     libcerror_error_t **error )
2507
0
{
2508
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2509
0
  static char *function                                = "libfsntfs_file_entry_get_i30_size";
2510
0
  int result                                           = 0;
2511
2512
0
  if( file_entry == NULL )
2513
0
  {
2514
0
    libcerror_error_set(
2515
0
     error,
2516
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2517
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2518
0
     "%s: invalid file entry.",
2519
0
     function );
2520
2521
0
    return( -1 );
2522
0
  }
2523
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2524
2525
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2526
0
  if( libcthreads_read_write_lock_grab_for_read(
2527
0
       internal_file_entry->read_write_lock,
2528
0
       error ) != 1 )
2529
0
  {
2530
0
    libcerror_error_set(
2531
0
     error,
2532
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2533
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2534
0
     "%s: unable to grab read/write lock for reading.",
2535
0
     function );
2536
2537
0
    return( -1 );
2538
0
  }
2539
0
#endif
2540
0
  if( internal_file_entry->directory_entry != NULL )
2541
0
  {
2542
0
    result = libfsntfs_directory_entry_get_size(
2543
0
              internal_file_entry->directory_entry,
2544
0
              size,
2545
0
              error );
2546
2547
0
    if( result != 1 )
2548
0
    {
2549
0
      libcerror_error_set(
2550
0
       error,
2551
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2552
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2553
0
       "%s: unable to retrieve size from directory entry.",
2554
0
       function );
2555
2556
0
      result = -1;
2557
0
    }
2558
0
  }
2559
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2560
0
  if( libcthreads_read_write_lock_release_for_read(
2561
0
       internal_file_entry->read_write_lock,
2562
0
       error ) != 1 )
2563
0
  {
2564
0
    libcerror_error_set(
2565
0
     error,
2566
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2567
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2568
0
     "%s: unable to release read/write lock for reading.",
2569
0
     function );
2570
2571
0
    return( -1 );
2572
0
  }
2573
0
#endif
2574
0
  return( result );
2575
0
}
2576
2577
/* Retrieves the file attribute flags
2578
 * This value is retrieved from the $I30 $FILE_NAME directory entry
2579
 * Returns 1 if successful, 0 if not available or -1 on error
2580
 */
2581
int libfsntfs_file_entry_get_i30_file_attribute_flags(
2582
     libfsntfs_file_entry_t *file_entry,
2583
     uint32_t *file_attribute_flags,
2584
     libcerror_error_t **error )
2585
0
{
2586
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2587
0
  static char *function                                = "libfsntfs_file_entry_get_i30_file_attribute_flags";
2588
0
  int result                                           = 0;
2589
2590
0
  if( file_entry == NULL )
2591
0
  {
2592
0
    libcerror_error_set(
2593
0
     error,
2594
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2595
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2596
0
     "%s: invalid file entry.",
2597
0
     function );
2598
2599
0
    return( -1 );
2600
0
  }
2601
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2602
2603
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2604
0
  if( libcthreads_read_write_lock_grab_for_read(
2605
0
       internal_file_entry->read_write_lock,
2606
0
       error ) != 1 )
2607
0
  {
2608
0
    libcerror_error_set(
2609
0
     error,
2610
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2611
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2612
0
     "%s: unable to grab read/write lock for reading.",
2613
0
     function );
2614
2615
0
    return( -1 );
2616
0
  }
2617
0
#endif
2618
0
  if( internal_file_entry->directory_entry != NULL )
2619
0
  {
2620
0
    result = libfsntfs_directory_entry_get_file_attribute_flags(
2621
0
              internal_file_entry->directory_entry,
2622
0
              file_attribute_flags,
2623
0
              error );
2624
2625
0
    if( result != 1 )
2626
0
    {
2627
0
      libcerror_error_set(
2628
0
       error,
2629
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2630
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2631
0
       "%s: unable to retrieve file attribute flags from directory entry.",
2632
0
       function );
2633
2634
0
      result = -1;
2635
0
    }
2636
0
  }
2637
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2638
0
  if( libcthreads_read_write_lock_release_for_read(
2639
0
       internal_file_entry->read_write_lock,
2640
0
       error ) != 1 )
2641
0
  {
2642
0
    libcerror_error_set(
2643
0
     error,
2644
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2645
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2646
0
     "%s: unable to release read/write lock for reading.",
2647
0
     function );
2648
2649
0
    return( -1 );
2650
0
  }
2651
0
#endif
2652
0
  return( result );
2653
0
}
2654
2655
/* Retrieves the size of the UTF-8 encoded name
2656
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
2657
 * The returned size includes the end of string character
2658
 * This value is retrieved from the directory entry $FILE_NAME attribute
2659
 * Returns 1 if successful, 0 if not available or -1 on error
2660
 */
2661
int libfsntfs_file_entry_get_utf8_name_size(
2662
     libfsntfs_file_entry_t *file_entry,
2663
     size_t *utf8_string_size,
2664
     libcerror_error_t **error )
2665
0
{
2666
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2667
0
  static char *function                                = "libfsntfs_file_entry_get_utf8_name_size";
2668
0
  int result                                           = 0;
2669
2670
0
  if( file_entry == NULL )
2671
0
  {
2672
0
    libcerror_error_set(
2673
0
     error,
2674
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2675
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2676
0
     "%s: invalid file entry.",
2677
0
     function );
2678
2679
0
    return( -1 );
2680
0
  }
2681
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2682
2683
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2684
0
  if( libcthreads_read_write_lock_grab_for_read(
2685
0
       internal_file_entry->read_write_lock,
2686
0
       error ) != 1 )
2687
0
  {
2688
0
    libcerror_error_set(
2689
0
     error,
2690
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2691
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2692
0
     "%s: unable to grab read/write lock for reading.",
2693
0
     function );
2694
2695
0
    return( -1 );
2696
0
  }
2697
0
#endif
2698
0
  if( internal_file_entry->directory_entry != NULL )
2699
0
  {
2700
0
    result = libfsntfs_directory_entry_get_utf8_name_size(
2701
0
              internal_file_entry->directory_entry,
2702
0
              utf8_string_size,
2703
0
              error );
2704
2705
0
    if( result != 1 )
2706
0
    {
2707
0
      libcerror_error_set(
2708
0
       error,
2709
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2710
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2711
0
       "%s: unable to retrieve size of UTF-8 name from directory entry.",
2712
0
       function );
2713
2714
0
      result = -1;
2715
0
    }
2716
0
  }
2717
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2718
0
  if( libcthreads_read_write_lock_release_for_read(
2719
0
       internal_file_entry->read_write_lock,
2720
0
       error ) != 1 )
2721
0
  {
2722
0
    libcerror_error_set(
2723
0
     error,
2724
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2725
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2726
0
     "%s: unable to release read/write lock for reading.",
2727
0
     function );
2728
2729
0
    return( -1 );
2730
0
  }
2731
0
#endif
2732
0
  return( result );
2733
0
}
2734
2735
/* Retrieves the UTF-8 encoded name
2736
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
2737
 * The size should include the end of string character
2738
 * This value is retrieved from the directory entry $FILE_NAME attribute
2739
 * Returns 1 if successful, 0 if not available or -1 on error
2740
 */
2741
int libfsntfs_file_entry_get_utf8_name(
2742
     libfsntfs_file_entry_t *file_entry,
2743
     uint8_t *utf8_string,
2744
     size_t utf8_string_size,
2745
     libcerror_error_t **error )
2746
0
{
2747
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2748
0
  static char *function                                = "libfsntfs_file_entry_get_utf8_name";
2749
0
  int result                                           = 0;
2750
2751
0
  if( file_entry == NULL )
2752
0
  {
2753
0
    libcerror_error_set(
2754
0
     error,
2755
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2756
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2757
0
     "%s: invalid file entry.",
2758
0
     function );
2759
2760
0
    return( -1 );
2761
0
  }
2762
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2763
2764
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2765
0
  if( libcthreads_read_write_lock_grab_for_read(
2766
0
       internal_file_entry->read_write_lock,
2767
0
       error ) != 1 )
2768
0
  {
2769
0
    libcerror_error_set(
2770
0
     error,
2771
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2772
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2773
0
     "%s: unable to grab read/write lock for reading.",
2774
0
     function );
2775
2776
0
    return( -1 );
2777
0
  }
2778
0
#endif
2779
0
  if( internal_file_entry->directory_entry != NULL )
2780
0
  {
2781
0
    result = libfsntfs_directory_entry_get_utf8_name(
2782
0
              internal_file_entry->directory_entry,
2783
0
              utf8_string,
2784
0
              utf8_string_size,
2785
0
              error );
2786
2787
0
    if( result != 1 )
2788
0
    {
2789
0
      libcerror_error_set(
2790
0
       error,
2791
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2792
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2793
0
       "%s: unable to retrieve UTF-8 name from directory entry.",
2794
0
       function );
2795
2796
0
      result = -1;
2797
0
    }
2798
0
  }
2799
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2800
0
  if( libcthreads_read_write_lock_release_for_read(
2801
0
       internal_file_entry->read_write_lock,
2802
0
       error ) != 1 )
2803
0
  {
2804
0
    libcerror_error_set(
2805
0
     error,
2806
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2807
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2808
0
     "%s: unable to release read/write lock for reading.",
2809
0
     function );
2810
2811
0
    return( -1 );
2812
0
  }
2813
0
#endif
2814
0
  return( result );
2815
0
}
2816
2817
/* Retrieves the size of the UTF-16 encoded name
2818
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
2819
 * The returned size includes the end of string character
2820
 * This value is retrieved from the directory entry $FILE_NAME attribute
2821
 * Returns 1 if successful, 0 if not available or -1 on error
2822
 */
2823
int libfsntfs_file_entry_get_utf16_name_size(
2824
     libfsntfs_file_entry_t *file_entry,
2825
     size_t *utf16_string_size,
2826
     libcerror_error_t **error )
2827
0
{
2828
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2829
0
  static char *function                                = "libfsntfs_file_entry_get_utf16_name_size";
2830
0
  int result                                           = 0;
2831
2832
0
  if( file_entry == NULL )
2833
0
  {
2834
0
    libcerror_error_set(
2835
0
     error,
2836
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2837
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2838
0
     "%s: invalid file entry.",
2839
0
     function );
2840
2841
0
    return( -1 );
2842
0
  }
2843
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2844
2845
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2846
0
  if( libcthreads_read_write_lock_grab_for_read(
2847
0
       internal_file_entry->read_write_lock,
2848
0
       error ) != 1 )
2849
0
  {
2850
0
    libcerror_error_set(
2851
0
     error,
2852
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2853
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2854
0
     "%s: unable to grab read/write lock for reading.",
2855
0
     function );
2856
2857
0
    return( -1 );
2858
0
  }
2859
0
#endif
2860
0
  if( internal_file_entry->directory_entry != NULL )
2861
0
  {
2862
0
    result = libfsntfs_directory_entry_get_utf16_name_size(
2863
0
              internal_file_entry->directory_entry,
2864
0
              utf16_string_size,
2865
0
              error );
2866
2867
0
    if( result != 1 )
2868
0
    {
2869
0
      libcerror_error_set(
2870
0
       error,
2871
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2872
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2873
0
       "%s: unable to retrieve size of UTF-16 name from directory.",
2874
0
       function );
2875
2876
0
      result = -1;
2877
0
    }
2878
0
  }
2879
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2880
0
  if( libcthreads_read_write_lock_release_for_read(
2881
0
       internal_file_entry->read_write_lock,
2882
0
       error ) != 1 )
2883
0
  {
2884
0
    libcerror_error_set(
2885
0
     error,
2886
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2887
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2888
0
     "%s: unable to release read/write lock for reading.",
2889
0
     function );
2890
2891
0
    return( -1 );
2892
0
  }
2893
0
#endif
2894
0
  return( result );
2895
0
}
2896
2897
/* Retrieves the UTF-16 encoded name
2898
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
2899
 * The size should include the end of string character
2900
 * This value is retrieved from the directory entry $FILE_NAME attribute
2901
 * Returns 1 if successful, 0 if not available or -1 on error
2902
 */
2903
int libfsntfs_file_entry_get_utf16_name(
2904
     libfsntfs_file_entry_t *file_entry,
2905
     uint16_t *utf16_string,
2906
     size_t utf16_string_size,
2907
     libcerror_error_t **error )
2908
0
{
2909
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2910
0
  static char *function                                = "libfsntfs_file_entry_get_utf16_name";
2911
0
  int result                                           = 0;
2912
2913
0
  if( file_entry == NULL )
2914
0
  {
2915
0
    libcerror_error_set(
2916
0
     error,
2917
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2918
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2919
0
     "%s: invalid file entry.",
2920
0
     function );
2921
2922
0
    return( -1 );
2923
0
  }
2924
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2925
2926
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2927
0
  if( libcthreads_read_write_lock_grab_for_read(
2928
0
       internal_file_entry->read_write_lock,
2929
0
       error ) != 1 )
2930
0
  {
2931
0
    libcerror_error_set(
2932
0
     error,
2933
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2934
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2935
0
     "%s: unable to grab read/write lock for reading.",
2936
0
     function );
2937
2938
0
    return( -1 );
2939
0
  }
2940
0
#endif
2941
0
  if( internal_file_entry->directory_entry != NULL )
2942
0
  {
2943
0
    result = libfsntfs_directory_entry_get_utf16_name(
2944
0
              internal_file_entry->directory_entry,
2945
0
              utf16_string,
2946
0
              utf16_string_size,
2947
0
              error );
2948
2949
0
    if( result != 1 )
2950
0
    {
2951
0
      libcerror_error_set(
2952
0
       error,
2953
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2954
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2955
0
       "%s: unable to retrieve UTF-16 name from directory entry.",
2956
0
       function );
2957
2958
0
      result = -1;
2959
0
    }
2960
0
  }
2961
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2962
0
  if( libcthreads_read_write_lock_release_for_read(
2963
0
       internal_file_entry->read_write_lock,
2964
0
       error ) != 1 )
2965
0
  {
2966
0
    libcerror_error_set(
2967
0
     error,
2968
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2969
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2970
0
     "%s: unable to release read/write lock for reading.",
2971
0
     function );
2972
2973
0
    return( -1 );
2974
0
  }
2975
0
#endif
2976
0
  return( result );
2977
0
}
2978
2979
/* Retrieves the $FILE_NAME attribute index
2980
 * Returns 1 if successful, 0 if not available or -1 on error
2981
 */
2982
int libfsntfs_file_entry_get_name_attribute_index(
2983
     libfsntfs_file_entry_t *file_entry,
2984
     int *attribute_index,
2985
     libcerror_error_t **error )
2986
0
{
2987
0
  uint8_t lookup_name_root[ 2 ]                        = { '.', 0 };
2988
2989
0
  libfsntfs_attribute_t *attribute                     = NULL;
2990
0
  libfsntfs_file_name_values_t *file_name_values       = NULL;
2991
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2992
0
  uint8_t *lookup_name                                 = NULL;
2993
0
  static char *function                                = "libfsntfs_file_entry_get_name_attribute_index";
2994
0
  size_t lookup_name_size                              = 0;
2995
0
  uint64_t lookup_parent_file_reference                = 0;
2996
0
  uint32_t attribute_type                              = 0;
2997
0
  uint8_t lookup_name_space                            = 0;
2998
0
  int number_of_attributes                             = 0;
2999
0
  int safe_attribute_index                             = 0;
3000
3001
0
  if( file_entry == NULL )
3002
0
  {
3003
0
    libcerror_error_set(
3004
0
     error,
3005
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3006
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3007
0
     "%s: invalid file entry.",
3008
0
     function );
3009
3010
0
    return( -1 );
3011
0
  }
3012
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
3013
3014
0
  if( attribute_index == NULL )
3015
0
  {
3016
0
    libcerror_error_set(
3017
0
     error,
3018
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3019
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3020
0
     "%s: invalid attribute index",
3021
0
     function );
3022
3023
0
    return( -1 );
3024
0
  }
3025
/* TODO add thread lock suport */
3026
3027
0
  if( internal_file_entry->directory_entry == NULL )
3028
0
  {
3029
0
    lookup_name       = lookup_name_root;
3030
0
    lookup_name_size  = 2;
3031
0
    lookup_name_space = LIBFSNTFS_FILE_NAME_SPACE_DOS_WINDOWS;
3032
0
  }
3033
0
  else
3034
0
  {
3035
0
    if( internal_file_entry->directory_entry->file_name_values == NULL )
3036
0
    {
3037
0
      libcerror_error_set(
3038
0
       error,
3039
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3040
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3041
0
       "%s: invalid file entry - invalid directory entry - missing file name values.",
3042
0
       function );
3043
3044
0
      return( -1 );
3045
0
    }
3046
0
    lookup_name                  = internal_file_entry->directory_entry->file_name_values->name;
3047
0
    lookup_name_size             = internal_file_entry->directory_entry->file_name_values->name_size;
3048
0
    lookup_name_space            = internal_file_entry->directory_entry->file_name_values->name_space;
3049
0
    lookup_parent_file_reference = internal_file_entry->directory_entry->file_name_values->parent_file_reference;
3050
0
  }
3051
0
  if( libfsntfs_mft_entry_get_number_of_attributes(
3052
0
       internal_file_entry->mft_entry,
3053
0
       &number_of_attributes,
3054
0
       error ) != 1 )
3055
0
  {
3056
0
    libcerror_error_set(
3057
0
     error,
3058
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3059
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3060
0
     "%s: unable to retrieve number of attributes.",
3061
0
     function );
3062
3063
0
    return( -1 );
3064
0
  }
3065
0
  for( safe_attribute_index = 0;
3066
0
       safe_attribute_index < number_of_attributes;
3067
0
       safe_attribute_index++ )
3068
0
  {
3069
0
    if( libfsntfs_internal_file_entry_get_attribute_by_index(
3070
0
         internal_file_entry,
3071
0
         internal_file_entry->mft_entry,
3072
0
         safe_attribute_index,
3073
0
         &attribute,
3074
0
         error ) != 1 )
3075
0
    {
3076
0
      libcerror_error_set(
3077
0
       error,
3078
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3079
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3080
0
       "%s: unable to retrieve attribute: %d.",
3081
0
       function,
3082
0
       safe_attribute_index );
3083
3084
0
      return( -1 );
3085
0
    }
3086
0
    if( libfsntfs_attribute_get_type(
3087
0
         attribute,
3088
0
         &attribute_type,
3089
0
         error ) != 1 )
3090
0
    {
3091
0
      libcerror_error_set(
3092
0
       error,
3093
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3094
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3095
0
       "%s: unable to retrieve attribute: %d type.",
3096
0
       function,
3097
0
       safe_attribute_index );
3098
3099
0
      return( -1 );
3100
0
    }
3101
0
    if( attribute_type != LIBFSNTFS_ATTRIBUTE_TYPE_FILE_NAME )
3102
0
    {
3103
0
      continue;
3104
0
    }
3105
0
    if( libfsntfs_internal_attribute_get_value(
3106
0
         (libfsntfs_internal_attribute_t *) attribute,
3107
0
         (intptr_t **) &file_name_values,
3108
0
         error ) != 1 )
3109
0
    {
3110
0
      libcerror_error_set(
3111
0
       error,
3112
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3113
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3114
0
       "%s: unable to retrieve attribute: %d value.",
3115
0
       function,
3116
0
       safe_attribute_index );
3117
3118
0
      return( -1 );
3119
0
    }
3120
0
    if( ( lookup_parent_file_reference == file_name_values->parent_file_reference )
3121
0
     && ( lookup_name_space == file_name_values->name_space )
3122
0
     && ( lookup_name_size == file_name_values->name_size )
3123
0
     && ( memory_compare(
3124
0
           lookup_name,
3125
0
           file_name_values->name,
3126
0
           file_name_values->name_size ) == 0 ) )
3127
0
    {
3128
0
      *attribute_index = safe_attribute_index;
3129
3130
0
      return( 1 );
3131
0
    }
3132
0
  }
3133
0
  return( 0 );
3134
0
}
3135
3136
/* Retrieves the size of the UTF-8 encoded name for a specific $FILE_NAME attribute
3137
 * The returned size includes the end of string character
3138
 * Returns 1 if successful or -1 on error
3139
 */
3140
int libfsntfs_file_entry_get_utf8_name_size_by_attribute_index(
3141
     libfsntfs_file_entry_t *file_entry,
3142
     int attribute_index,
3143
     size_t *utf8_string_size,
3144
     libcerror_error_t **error )
3145
0
{
3146
0
  libfsntfs_attribute_t *attribute                     = NULL;
3147
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
3148
0
  static char *function                                = "libfsntfs_file_entry_get_utf8_name_size_by_attribute_index";
3149
0
  int result                                           = 1;
3150
3151
0
  if( file_entry == NULL )
3152
0
  {
3153
0
    libcerror_error_set(
3154
0
     error,
3155
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3156
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3157
0
     "%s: invalid file entry.",
3158
0
     function );
3159
3160
0
    return( -1 );
3161
0
  }
3162
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
3163
3164
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3165
0
  if( libcthreads_read_write_lock_grab_for_write(
3166
0
       internal_file_entry->read_write_lock,
3167
0
       error ) != 1 )
3168
0
  {
3169
0
    libcerror_error_set(
3170
0
     error,
3171
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3172
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3173
0
     "%s: unable to grab read/write lock for writing.",
3174
0
     function );
3175
3176
0
    return( -1 );
3177
0
  }
3178
0
#endif
3179
0
  if( libfsntfs_internal_file_entry_get_attribute_by_index(
3180
0
       internal_file_entry,
3181
0
       internal_file_entry->mft_entry,
3182
0
       attribute_index,
3183
0
       &attribute,
3184
0
       error ) != 1 )
3185
0
  {
3186
0
    libcerror_error_set(
3187
0
     error,
3188
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3189
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3190
0
     "%s: unable to retrieve attribute: %d.",
3191
0
     function,
3192
0
     attribute_index );
3193
3194
0
    result = -1;
3195
0
  }
3196
0
  else if( libfsntfs_file_name_attribute_get_utf8_name_size(
3197
0
            attribute,
3198
0
            utf8_string_size,
3199
0
            error ) != 1 )
3200
0
  {
3201
0
    libcerror_error_set(
3202
0
     error,
3203
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3204
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3205
0
     "%s: unable to retrieve size of UTF-8 name from $FILE_NAME attribute.",
3206
0
     function );
3207
3208
0
    result = -1;
3209
0
  }
3210
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3211
0
  if( libcthreads_read_write_lock_release_for_write(
3212
0
       internal_file_entry->read_write_lock,
3213
0
       error ) != 1 )
3214
0
  {
3215
0
    libcerror_error_set(
3216
0
     error,
3217
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3218
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3219
0
     "%s: unable to release read/write lock for writing.",
3220
0
     function );
3221
3222
0
    return( -1 );
3223
0
  }
3224
0
#endif
3225
0
  return( result );
3226
0
}
3227
3228
/* Retrieves the UTF-8 encoded name for a specific $FILE_NAME attribute
3229
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
3230
 * The size should include the end of string character
3231
 * Returns 1 if successful or -1 on error
3232
 */
3233
int libfsntfs_file_entry_get_utf8_name_by_attribute_index(
3234
     libfsntfs_file_entry_t *file_entry,
3235
     int attribute_index,
3236
     uint8_t *utf8_string,
3237
     size_t utf8_string_size,
3238
     libcerror_error_t **error )
3239
0
{
3240
0
  libfsntfs_attribute_t *attribute                     = NULL;
3241
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
3242
0
  static char *function                                = "libfsntfs_file_entry_get_utf8_name_by_attribute_index";
3243
0
  int result                                           = 1;
3244
3245
0
  if( file_entry == NULL )
3246
0
  {
3247
0
    libcerror_error_set(
3248
0
     error,
3249
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3250
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3251
0
     "%s: invalid file entry.",
3252
0
     function );
3253
3254
0
    return( -1 );
3255
0
  }
3256
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
3257
3258
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3259
0
  if( libcthreads_read_write_lock_grab_for_write(
3260
0
       internal_file_entry->read_write_lock,
3261
0
       error ) != 1 )
3262
0
  {
3263
0
    libcerror_error_set(
3264
0
     error,
3265
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3266
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3267
0
     "%s: unable to grab read/write lock for writing.",
3268
0
     function );
3269
3270
0
    return( -1 );
3271
0
  }
3272
0
#endif
3273
0
  if( libfsntfs_internal_file_entry_get_attribute_by_index(
3274
0
       internal_file_entry,
3275
0
       internal_file_entry->mft_entry,
3276
0
       attribute_index,
3277
0
       &attribute,
3278
0
       error ) != 1 )
3279
0
  {
3280
0
    libcerror_error_set(
3281
0
     error,
3282
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3283
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3284
0
     "%s: unable to retrieve attribute: %d.",
3285
0
     function,
3286
0
     attribute_index );
3287
3288
0
    result = -1;
3289
0
  }
3290
0
  else if( libfsntfs_file_name_attribute_get_utf8_name(
3291
0
            attribute,
3292
0
            utf8_string,
3293
0
            utf8_string_size,
3294
0
            error ) != 1 )
3295
0
  {
3296
0
    libcerror_error_set(
3297
0
     error,
3298
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3299
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3300
0
     "%s: unable to retrieve UTF-8 name from $FILE_NAME attribute.",
3301
0
     function );
3302
3303
0
    result = -1;
3304
0
  }
3305
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3306
0
  if( libcthreads_read_write_lock_release_for_write(
3307
0
       internal_file_entry->read_write_lock,
3308
0
       error ) != 1 )
3309
0
  {
3310
0
    libcerror_error_set(
3311
0
     error,
3312
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3313
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3314
0
     "%s: unable to release read/write lock for writing.",
3315
0
     function );
3316
3317
0
    return( -1 );
3318
0
  }
3319
0
#endif
3320
0
  return( result );
3321
0
}
3322
3323
/* Retrieves the size of the UTF-16 encoded name for a specific $FILE_NAME attribute
3324
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
3325
 * The returned size includes the end of string character
3326
 * Returns 1 if successful or -1 on error
3327
 */
3328
int libfsntfs_file_entry_get_utf16_name_size_by_attribute_index(
3329
     libfsntfs_file_entry_t *file_entry,
3330
     int attribute_index,
3331
     size_t *utf16_string_size,
3332
     libcerror_error_t **error )
3333
0
{
3334
0
  libfsntfs_attribute_t *attribute                     = NULL;
3335
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
3336
0
  static char *function                                = "libfsntfs_file_entry_get_utf16_name_size_by_attribute_index";
3337
0
  int result                                           = 1;
3338
3339
0
  if( file_entry == NULL )
3340
0
  {
3341
0
    libcerror_error_set(
3342
0
     error,
3343
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3344
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3345
0
     "%s: invalid file entry.",
3346
0
     function );
3347
3348
0
    return( -1 );
3349
0
  }
3350
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
3351
3352
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3353
0
  if( libcthreads_read_write_lock_grab_for_write(
3354
0
       internal_file_entry->read_write_lock,
3355
0
       error ) != 1 )
3356
0
  {
3357
0
    libcerror_error_set(
3358
0
     error,
3359
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3360
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3361
0
     "%s: unable to grab read/write lock for writing.",
3362
0
     function );
3363
3364
0
    return( -1 );
3365
0
  }
3366
0
#endif
3367
0
  if( libfsntfs_internal_file_entry_get_attribute_by_index(
3368
0
       internal_file_entry,
3369
0
       internal_file_entry->mft_entry,
3370
0
       attribute_index,
3371
0
       &attribute,
3372
0
       error ) != 1 )
3373
0
  {
3374
0
    libcerror_error_set(
3375
0
     error,
3376
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3377
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3378
0
     "%s: unable to retrieve attribute: %d.",
3379
0
     function,
3380
0
     attribute_index );
3381
3382
0
    result = -1;
3383
0
  }
3384
0
  else if( libfsntfs_file_name_attribute_get_utf16_name_size(
3385
0
            attribute,
3386
0
            utf16_string_size,
3387
0
            error ) != 1 )
3388
0
  {
3389
0
    libcerror_error_set(
3390
0
     error,
3391
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3392
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3393
0
     "%s: unable to retrieve size of UTF-16 name from $FILE_NAME attribute.",
3394
0
     function );
3395
3396
0
    result = -1;
3397
0
  }
3398
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3399
0
  if( libcthreads_read_write_lock_release_for_write(
3400
0
       internal_file_entry->read_write_lock,
3401
0
       error ) != 1 )
3402
0
  {
3403
0
    libcerror_error_set(
3404
0
     error,
3405
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3406
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3407
0
     "%s: unable to release read/write lock for writing.",
3408
0
     function );
3409
3410
0
    return( -1 );
3411
0
  }
3412
0
#endif
3413
0
  return( result );
3414
0
}
3415
3416
/* Retrieves the UTF-16 encoded name for a specific $FILE_NAME attribute
3417
 * The size should include the end of string character
3418
 * Returns 1 if successful or -1 on error
3419
 */
3420
int libfsntfs_file_entry_get_utf16_name_by_attribute_index(
3421
     libfsntfs_file_entry_t *file_entry,
3422
     int attribute_index,
3423
     uint16_t *utf16_string,
3424
     size_t utf16_string_size,
3425
     libcerror_error_t **error )
3426
0
{
3427
0
  libfsntfs_attribute_t *attribute                     = NULL;
3428
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
3429
0
  static char *function                                = "libfsntfs_file_entry_get_utf16_name_by_attribute_index";
3430
0
  int result                                           = 1;
3431
3432
0
  if( file_entry == NULL )
3433
0
  {
3434
0
    libcerror_error_set(
3435
0
     error,
3436
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3437
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3438
0
     "%s: invalid file entry.",
3439
0
     function );
3440
3441
0
    return( -1 );
3442
0
  }
3443
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
3444
3445
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3446
0
  if( libcthreads_read_write_lock_grab_for_write(
3447
0
       internal_file_entry->read_write_lock,
3448
0
       error ) != 1 )
3449
0
  {
3450
0
    libcerror_error_set(
3451
0
     error,
3452
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3453
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3454
0
     "%s: unable to grab read/write lock for writing.",
3455
0
     function );
3456
3457
0
    return( -1 );
3458
0
  }
3459
0
#endif
3460
0
  if( libfsntfs_internal_file_entry_get_attribute_by_index(
3461
0
       internal_file_entry,
3462
0
       internal_file_entry->mft_entry,
3463
0
       attribute_index,
3464
0
       &attribute,
3465
0
       error ) != 1 )
3466
0
  {
3467
0
    libcerror_error_set(
3468
0
     error,
3469
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3470
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3471
0
     "%s: unable to retrieve attribute: %d.",
3472
0
     function,
3473
0
     attribute_index );
3474
3475
0
    result = -1;
3476
0
  }
3477
0
  else if( libfsntfs_file_name_attribute_get_utf16_name(
3478
0
            attribute,
3479
0
            utf16_string,
3480
0
            utf16_string_size,
3481
0
            error ) != 1 )
3482
0
  {
3483
0
    libcerror_error_set(
3484
0
     error,
3485
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3486
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3487
0
     "%s: unable to retrieve UTF-16 name from $FILE_NAME attribute.",
3488
0
     function );
3489
3490
0
    result = -1;
3491
0
  }
3492
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3493
0
  if( libcthreads_read_write_lock_release_for_write(
3494
0
       internal_file_entry->read_write_lock,
3495
0
       error ) != 1 )
3496
0
  {
3497
0
    libcerror_error_set(
3498
0
     error,
3499
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3500
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3501
0
     "%s: unable to release read/write lock for writing.",
3502
0
     function );
3503
3504
0
    return( -1 );
3505
0
  }
3506
0
#endif
3507
0
  return( result );
3508
0
}
3509
3510
/* Retrieves the path hint for a specific $FILE_NAME attribute
3511
 * Returns 1 if successful or -1 on error
3512
 */
3513
int libfsntfs_internal_file_entry_get_path_hint(
3514
     libfsntfs_internal_file_entry_t *internal_file_entry,
3515
     int attribute_index,
3516
     libfsntfs_path_hint_t **path_hint,
3517
     libcerror_error_t **error )
3518
0
{
3519
0
  libfsntfs_attribute_t *attribute               = NULL;
3520
0
  libfsntfs_file_name_values_t *file_name_values = NULL;
3521
0
  libfsntfs_path_hint_t *parent_path_hint        = NULL;
3522
0
  libfsntfs_path_hint_t *safe_path_hint          = NULL;
3523
0
  uint8_t *parent_path                           = NULL;
3524
0
  static char *function                          = "libfsntfs_internal_file_entry_get_path_hint";
3525
0
  size_t name_size                               = 0;
3526
0
  size_t parent_path_size                        = 0;
3527
0
  uint64_t file_reference                        = 0;
3528
0
  uint64_t mft_entry_index                       = 0;
3529
0
  uint64_t parent_file_reference                 = 0;
3530
0
  uint64_t parent_mft_entry_index                = 0;
3531
0
  int result                                     = 0;
3532
3533
0
  if( internal_file_entry == NULL )
3534
0
  {
3535
0
    libcerror_error_set(
3536
0
     error,
3537
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3538
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3539
0
     "%s: invalid file entry.",
3540
0
     function );
3541
3542
0
    return( -1 );
3543
0
  }
3544
0
  if( path_hint == NULL )
3545
0
  {
3546
0
    libcerror_error_set(
3547
0
     error,
3548
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3549
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3550
0
     "%s: invalid path hint.",
3551
0
     function );
3552
3553
0
    return( -1 );
3554
0
  }
3555
/* TODO cache path hint in attribute */
3556
0
  if( libfsntfs_internal_file_entry_get_attribute_by_index(
3557
0
       internal_file_entry,
3558
0
       internal_file_entry->mft_entry,
3559
0
       attribute_index,
3560
0
       &attribute,
3561
0
       error ) != 1 )
3562
0
  {
3563
0
    libcerror_error_set(
3564
0
     error,
3565
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3566
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3567
0
     "%s: unable to retrieve attribute: %d.",
3568
0
     function,
3569
0
     attribute_index );
3570
3571
0
    goto on_error;
3572
0
  }
3573
0
  if( attribute == NULL )
3574
0
  {
3575
0
    libcerror_error_set(
3576
0
     error,
3577
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3578
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3579
0
     "%s: missing attribute?: %d.",
3580
0
     function,
3581
0
     attribute_index );
3582
3583
0
    goto on_error;
3584
0
  }
3585
0
  if( ( (libfsntfs_internal_attribute_t *) attribute )->path_hint == NULL )
3586
0
  {
3587
0
    if( libfsntfs_mft_entry_get_file_reference(
3588
0
         internal_file_entry->mft_entry,
3589
0
         &file_reference,
3590
0
         error ) != 1 )
3591
0
    {
3592
0
      libcerror_error_set(
3593
0
       error,
3594
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3595
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3596
0
       "%s: unable to retrieve file reference from MFT entry.",
3597
0
       function );
3598
3599
0
      goto on_error;
3600
0
    }
3601
0
    mft_entry_index = file_reference & 0xffffffffffffUL;
3602
3603
0
    if( libfsntfs_file_name_attribute_get_parent_file_reference(
3604
0
         attribute,
3605
0
         &parent_file_reference,
3606
0
         error ) != 1 )
3607
0
    {
3608
0
      libcerror_error_set(
3609
0
       error,
3610
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3611
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3612
0
       "%s: unable to retrieve parent reference from $FILE_NAME attribute.",
3613
0
       function );
3614
3615
0
      result = -1;
3616
0
    }
3617
0
    parent_mft_entry_index = parent_file_reference & 0xffffffffffffUL;
3618
3619
0
    parent_path      = NULL;
3620
0
    parent_path_size = 0;
3621
3622
0
    if( ( mft_entry_index != LIBFSNTFS_MFT_ENTRY_INDEX_ROOT_DIRECTORY )
3623
0
     && ( parent_mft_entry_index == LIBFSNTFS_MFT_ENTRY_INDEX_ROOT_DIRECTORY ) )
3624
0
    {
3625
0
      parent_path      = (uint8_t *) "";
3626
0
      parent_path_size = 1;
3627
0
    }
3628
0
    else if( ( parent_mft_entry_index != 0 )
3629
0
          && ( parent_mft_entry_index != mft_entry_index ) )
3630
0
    {
3631
0
      result = libfsntfs_file_system_get_path_hint(
3632
0
                internal_file_entry->file_system,
3633
0
                internal_file_entry->file_io_handle,
3634
0
                parent_file_reference,
3635
0
                &parent_path_hint,
3636
0
                0,
3637
0
                error );
3638
3639
0
      if( result == -1 )
3640
0
      {
3641
0
        libcerror_error_set(
3642
0
         error,
3643
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3644
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3645
0
         "%s: unable to retrieve path hint for MFT entry: %" PRIu64 ".",
3646
0
         function,
3647
0
         parent_mft_entry_index );
3648
3649
0
        goto on_error;
3650
0
      }
3651
0
      else if( result == 0 )
3652
0
      {
3653
0
        parent_path      = (uint8_t *) "$Orphan";
3654
0
        parent_path_size = 8;
3655
0
      }
3656
0
      else
3657
0
      {
3658
0
        parent_path      = parent_path_hint->path;
3659
0
        parent_path_size = parent_path_hint->path_size;
3660
0
      }
3661
0
    }
3662
0
    if( libfsntfs_file_name_attribute_get_utf8_name_size(
3663
0
         attribute,
3664
0
         &name_size,
3665
0
         error ) != 1 )
3666
0
    {
3667
0
      libcerror_error_set(
3668
0
       error,
3669
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3670
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3671
0
       "%s: unable to retrieve size of UTF-8 name from $FILE_NAME attribute.",
3672
0
       function );
3673
3674
0
      goto on_error;
3675
0
    }
3676
0
    if( libfsntfs_path_hint_initialize(
3677
0
         &safe_path_hint,
3678
0
         error ) != 1 )
3679
0
    {
3680
0
      libcerror_error_set(
3681
0
       error,
3682
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3683
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3684
0
       "%s: unable to create path hint.",
3685
0
       function );
3686
3687
0
      goto on_error;
3688
0
    }
3689
0
    safe_path_hint->file_reference = file_reference;
3690
0
    safe_path_hint->path_size      = parent_path_size + name_size;
3691
3692
0
    safe_path_hint->path = (uint8_t *) memory_allocate(
3693
0
                sizeof( uint8_t ) * safe_path_hint->path_size );
3694
3695
0
    if( safe_path_hint->path == NULL )
3696
0
    {
3697
0
      libcerror_error_set(
3698
0
       error,
3699
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
3700
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
3701
0
       "%s: unable to create path.",
3702
0
       function );
3703
3704
0
      goto on_error;
3705
0
    }
3706
0
    if( ( parent_path != NULL )
3707
0
     && ( parent_path_size > 0 ) )
3708
0
    {
3709
0
      if( memory_copy(
3710
0
           safe_path_hint->path,
3711
0
           parent_path,
3712
0
           parent_path_size ) == NULL )
3713
0
      {
3714
0
        libcerror_error_set(
3715
0
         error,
3716
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
3717
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
3718
0
         "%s: unable to copy parent path to path.",
3719
0
         function );
3720
3721
0
        goto on_error;
3722
0
      }
3723
0
      safe_path_hint->path[ parent_path_size - 1 ] = '\\';
3724
0
    }
3725
0
    if( name_size > 0 )
3726
0
    {
3727
0
      if( libfsntfs_file_name_attribute_get_utf8_name(
3728
0
           attribute,
3729
0
           &( safe_path_hint->path[ parent_path_size ] ),
3730
0
           name_size,
3731
0
           error ) != 1 )
3732
0
      {
3733
0
        libcerror_error_set(
3734
0
         error,
3735
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3736
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3737
0
         "%s: unable to retrieve UTF-8 name from $FILE_NAME attribute.",
3738
0
         function );
3739
3740
0
        goto on_error;
3741
0
      }
3742
0
    }
3743
0
    if( mft_entry_index == LIBFSNTFS_MFT_ENTRY_INDEX_ROOT_DIRECTORY )
3744
0
    {
3745
0
      safe_path_hint->path[ 0 ] = '\\';
3746
0
    }
3747
0
    ( (libfsntfs_internal_attribute_t *) attribute )->path_hint = safe_path_hint;
3748
0
  }
3749
0
  *path_hint = ( (libfsntfs_internal_attribute_t *) attribute )->path_hint;
3750
3751
0
  return( 1 );
3752
3753
0
on_error:
3754
0
  if( safe_path_hint != NULL )
3755
0
  {
3756
0
    libfsntfs_path_hint_free(
3757
0
     &safe_path_hint,
3758
0
     NULL );
3759
0
  }
3760
0
  if( file_name_values != NULL )
3761
0
  {
3762
0
    libfsntfs_file_name_values_free(
3763
0
     &file_name_values,
3764
0
     NULL );
3765
0
  }
3766
0
  return( -1 );
3767
0
}
3768
3769
/* Retrieves the size of the UTF-8 encoded path hint for a specific $FILE_NAME attribute
3770
 * The returned size includes the end of string character
3771
 * Returns 1 if successful, 0 if not available or -1 on error
3772
 */
3773
int libfsntfs_file_entry_get_utf8_path_hint_size(
3774
     libfsntfs_file_entry_t *file_entry,
3775
     int attribute_index,
3776
     size_t *utf8_string_size,
3777
     libcerror_error_t **error )
3778
0
{
3779
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
3780
0
  libfsntfs_path_hint_t *path_hint                     = NULL;
3781
0
  static char *function                                = "libfsntfs_file_entry_get_utf8_path_hint_size";
3782
0
  int result                                           = 1;
3783
3784
0
  if( file_entry == NULL )
3785
0
  {
3786
0
    libcerror_error_set(
3787
0
     error,
3788
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3789
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3790
0
     "%s: invalid file entry.",
3791
0
     function );
3792
3793
0
    return( -1 );
3794
0
  }
3795
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
3796
3797
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3798
0
  if( libcthreads_read_write_lock_grab_for_read(
3799
0
       internal_file_entry->read_write_lock,
3800
0
       error ) != 1 )
3801
0
  {
3802
0
    libcerror_error_set(
3803
0
     error,
3804
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3805
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3806
0
     "%s: unable to grab read/write lock for reading.",
3807
0
     function );
3808
3809
0
    return( -1 );
3810
0
  }
3811
0
#endif
3812
0
  if( libfsntfs_internal_file_entry_get_path_hint(
3813
0
       internal_file_entry,
3814
0
       attribute_index,
3815
0
       &path_hint,
3816
0
       error ) != 1 )
3817
0
  {
3818
0
    libcerror_error_set(
3819
0
     error,
3820
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3821
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3822
0
     "%s: unable to retrieve path hint.",
3823
0
     function );
3824
3825
0
    result = -1;
3826
0
  }
3827
0
  else
3828
0
  {
3829
0
    if( libfsntfs_path_hint_get_utf8_path_size(
3830
0
         path_hint,
3831
0
         utf8_string_size,
3832
0
         error ) != 1 )
3833
0
    {
3834
0
      libcerror_error_set(
3835
0
       error,
3836
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3837
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3838
0
       "%s: unable to retrieve size of UTF-8 path hint.",
3839
0
       function );
3840
3841
0
      result = -1;
3842
0
    }
3843
0
  }
3844
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3845
0
  if( libcthreads_read_write_lock_release_for_read(
3846
0
       internal_file_entry->read_write_lock,
3847
0
       error ) != 1 )
3848
0
  {
3849
0
    libcerror_error_set(
3850
0
     error,
3851
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3852
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3853
0
     "%s: unable to release read/write lock for reading.",
3854
0
     function );
3855
3856
0
    return( -1 );
3857
0
  }
3858
0
#endif
3859
0
  return( result );
3860
0
}
3861
3862
/* Retrieves the UTF-8 encoded path hint
3863
 * The size should include the end of string character
3864
 * Returns 1 if successful, 0 if not available or -1 on error
3865
 */
3866
int libfsntfs_file_entry_get_utf8_path_hint(
3867
     libfsntfs_file_entry_t *file_entry,
3868
     int attribute_index,
3869
     uint8_t *utf8_string,
3870
     size_t utf8_string_size,
3871
     libcerror_error_t **error )
3872
0
{
3873
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
3874
0
  libfsntfs_path_hint_t *path_hint                     = NULL;
3875
0
  static char *function                                = "libfsntfs_file_entry_get_utf8_path_hint";
3876
0
  int result                                           = 1;
3877
3878
0
  if( file_entry == NULL )
3879
0
  {
3880
0
    libcerror_error_set(
3881
0
     error,
3882
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3883
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3884
0
     "%s: invalid file entry.",
3885
0
     function );
3886
3887
0
    return( -1 );
3888
0
  }
3889
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
3890
3891
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3892
0
  if( libcthreads_read_write_lock_grab_for_read(
3893
0
       internal_file_entry->read_write_lock,
3894
0
       error ) != 1 )
3895
0
  {
3896
0
    libcerror_error_set(
3897
0
     error,
3898
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3899
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3900
0
     "%s: unable to grab read/write lock for reading.",
3901
0
     function );
3902
3903
0
    return( -1 );
3904
0
  }
3905
0
#endif
3906
0
  if( libfsntfs_internal_file_entry_get_path_hint(
3907
0
       internal_file_entry,
3908
0
       attribute_index,
3909
0
       &path_hint,
3910
0
       error ) != 1 )
3911
0
  {
3912
0
    libcerror_error_set(
3913
0
     error,
3914
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3915
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3916
0
     "%s: unable to retrieve path hint.",
3917
0
     function );
3918
3919
0
    result = -1;
3920
0
  }
3921
0
  else
3922
0
  {
3923
0
    if( libfsntfs_path_hint_get_utf8_path(
3924
0
         path_hint,
3925
0
         utf8_string,
3926
0
         utf8_string_size,
3927
0
         error ) != 1 )
3928
0
    {
3929
0
      libcerror_error_set(
3930
0
       error,
3931
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3932
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3933
0
       "%s: unable to retrieve UTF-8 path hint.",
3934
0
       function );
3935
3936
0
      result = -1;
3937
0
    }
3938
0
  }
3939
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3940
0
  if( libcthreads_read_write_lock_release_for_read(
3941
0
       internal_file_entry->read_write_lock,
3942
0
       error ) != 1 )
3943
0
  {
3944
0
    libcerror_error_set(
3945
0
     error,
3946
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3947
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3948
0
     "%s: unable to release read/write lock for reading.",
3949
0
     function );
3950
3951
0
    return( -1 );
3952
0
  }
3953
0
#endif
3954
0
  return( result );
3955
0
}
3956
3957
/* Retrieves the size of the UTF-16 encoded path hint for a specific $FILE_NAME attribute
3958
 * The returned size includes the end of string character
3959
 * Returns 1 if successful, 0 if not available or -1 on error
3960
 */
3961
int libfsntfs_file_entry_get_utf16_path_hint_size(
3962
     libfsntfs_file_entry_t *file_entry,
3963
     int attribute_index,
3964
     size_t *utf16_string_size,
3965
     libcerror_error_t **error )
3966
0
{
3967
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
3968
0
  libfsntfs_path_hint_t *path_hint                     = NULL;
3969
0
  static char *function                                = "libfsntfs_file_entry_get_utf16_path_hint_size";
3970
0
  int result                                           = 1;
3971
3972
0
  if( file_entry == NULL )
3973
0
  {
3974
0
    libcerror_error_set(
3975
0
     error,
3976
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3977
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3978
0
     "%s: invalid file entry.",
3979
0
     function );
3980
3981
0
    return( -1 );
3982
0
  }
3983
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
3984
3985
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3986
0
  if( libcthreads_read_write_lock_grab_for_read(
3987
0
       internal_file_entry->read_write_lock,
3988
0
       error ) != 1 )
3989
0
  {
3990
0
    libcerror_error_set(
3991
0
     error,
3992
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3993
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3994
0
     "%s: unable to grab read/write lock for reading.",
3995
0
     function );
3996
3997
0
    return( -1 );
3998
0
  }
3999
0
#endif
4000
0
  if( libfsntfs_internal_file_entry_get_path_hint(
4001
0
       internal_file_entry,
4002
0
       attribute_index,
4003
0
       &path_hint,
4004
0
       error ) != 1 )
4005
0
  {
4006
0
    libcerror_error_set(
4007
0
     error,
4008
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4009
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4010
0
     "%s: unable to retrieve path hint.",
4011
0
     function );
4012
4013
0
    result = -1;
4014
0
  }
4015
0
  else
4016
0
  {
4017
0
    if( libfsntfs_path_hint_get_utf16_path_size(
4018
0
         path_hint,
4019
0
         utf16_string_size,
4020
0
         error ) != 1 )
4021
0
    {
4022
0
      libcerror_error_set(
4023
0
       error,
4024
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4025
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4026
0
       "%s: unable to retrieve size of UTF-16 path hint.",
4027
0
       function );
4028
4029
0
      result = -1;
4030
0
    }
4031
0
  }
4032
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4033
0
  if( libcthreads_read_write_lock_release_for_read(
4034
0
       internal_file_entry->read_write_lock,
4035
0
       error ) != 1 )
4036
0
  {
4037
0
    libcerror_error_set(
4038
0
     error,
4039
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4040
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4041
0
     "%s: unable to release read/write lock for reading.",
4042
0
     function );
4043
4044
0
    return( -1 );
4045
0
  }
4046
0
#endif
4047
0
  return( result );
4048
0
}
4049
4050
/* Retrieves the UTF-16 encoded path hint
4051
 * The size should include the end of string character
4052
 * Returns 1 if successful, 0 if not available or -1 on error
4053
 */
4054
int libfsntfs_file_entry_get_utf16_path_hint(
4055
     libfsntfs_file_entry_t *file_entry,
4056
     int attribute_index,
4057
     uint16_t *utf16_string,
4058
     size_t utf16_string_size,
4059
     libcerror_error_t **error )
4060
0
{
4061
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
4062
0
  libfsntfs_path_hint_t *path_hint                     = NULL;
4063
0
  static char *function                                = "libfsntfs_file_entry_get_utf16_path_hint";
4064
0
  int result                                           = 1;
4065
4066
0
  if( file_entry == NULL )
4067
0
  {
4068
0
    libcerror_error_set(
4069
0
     error,
4070
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4071
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4072
0
     "%s: invalid file entry.",
4073
0
     function );
4074
4075
0
    return( -1 );
4076
0
  }
4077
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
4078
4079
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4080
0
  if( libcthreads_read_write_lock_grab_for_read(
4081
0
       internal_file_entry->read_write_lock,
4082
0
       error ) != 1 )
4083
0
  {
4084
0
    libcerror_error_set(
4085
0
     error,
4086
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4087
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4088
0
     "%s: unable to grab read/write lock for reading.",
4089
0
     function );
4090
4091
0
    return( -1 );
4092
0
  }
4093
0
#endif
4094
0
  if( libfsntfs_internal_file_entry_get_path_hint(
4095
0
       internal_file_entry,
4096
0
       attribute_index,
4097
0
       &path_hint,
4098
0
       error ) != 1 )
4099
0
  {
4100
0
    libcerror_error_set(
4101
0
     error,
4102
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4103
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4104
0
     "%s: unable to retrieve path hint.",
4105
0
     function );
4106
4107
0
    result = -1;
4108
0
  }
4109
0
  else
4110
0
  {
4111
0
    if( libfsntfs_path_hint_get_utf16_path(
4112
0
         path_hint,
4113
0
         utf16_string,
4114
0
         utf16_string_size,
4115
0
         error ) != 1 )
4116
0
    {
4117
0
      libcerror_error_set(
4118
0
       error,
4119
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4120
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4121
0
       "%s: unable to retrieve UTF-16 path hint.",
4122
0
       function );
4123
4124
0
      result = -1;
4125
0
    }
4126
0
  }
4127
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4128
0
  if( libcthreads_read_write_lock_release_for_read(
4129
0
       internal_file_entry->read_write_lock,
4130
0
       error ) != 1 )
4131
0
  {
4132
0
    libcerror_error_set(
4133
0
     error,
4134
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4135
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4136
0
     "%s: unable to release read/write lock for reading.",
4137
0
     function );
4138
4139
0
    return( -1 );
4140
0
  }
4141
0
#endif
4142
0
  return( result );
4143
0
}
4144
4145
/* Retrieves the size of the UTF-8 encoded symbolic link target
4146
 * The returned size includes the end of string character
4147
 * This value is retrieved from a symbolic link $REPARSE_POINT attribute
4148
 * Returns 1 if successful, 0 if not available or -1 on error
4149
 */
4150
int libfsntfs_file_entry_get_utf8_symbolic_link_target_size(
4151
     libfsntfs_file_entry_t *file_entry,
4152
     size_t *utf8_string_size,
4153
     libcerror_error_t **error )
4154
0
{
4155
0
  libfsntfs_attribute_t *reparse_point_attribute       = NULL;
4156
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
4157
0
  static char *function                                = "libfsntfs_file_entry_get_utf8_symbolic_link_target_size";
4158
0
  uint32_t reparse_point_tag           = 0;
4159
0
  int result                                           = 0;
4160
4161
0
  if( file_entry == NULL )
4162
0
  {
4163
0
    libcerror_error_set(
4164
0
     error,
4165
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4166
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4167
0
     "%s: invalid file entry.",
4168
0
     function );
4169
4170
0
    return( -1 );
4171
0
  }
4172
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
4173
4174
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4175
0
  if( libcthreads_read_write_lock_grab_for_write(
4176
0
       internal_file_entry->read_write_lock,
4177
0
       error ) != 1 )
4178
0
  {
4179
0
    libcerror_error_set(
4180
0
     error,
4181
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4182
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4183
0
     "%s: unable to grab read/write lock for writing.",
4184
0
     function );
4185
4186
0
    return( -1 );
4187
0
  }
4188
0
#endif
4189
0
  result = libfsntfs_internal_file_entry_get_reparse_point_attribute(
4190
0
            internal_file_entry,
4191
0
            internal_file_entry->mft_entry,
4192
0
            &reparse_point_attribute,
4193
0
            error );
4194
4195
0
  if( result == -1 )
4196
0
  {
4197
0
    libcerror_error_set(
4198
0
     error,
4199
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4200
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4201
0
     "%s: unable to retrieve reparse point attribute.",
4202
0
     function );
4203
4204
0
    result = -1;
4205
0
  }
4206
0
  else if( result != 0 )
4207
0
  {
4208
0
    result = libfsntfs_reparse_point_attribute_get_tag(
4209
0
              reparse_point_attribute,
4210
0
              &reparse_point_tag,
4211
0
              error );
4212
4213
0
    if( result != 1 )
4214
0
    {
4215
0
      libcerror_error_set(
4216
0
       error,
4217
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4218
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4219
0
       "%s: unable to retrieve size of UTF-8 substitute name from reparse point attribute.",
4220
0
       function );
4221
4222
0
      result = -1;
4223
0
    }
4224
0
    if( reparse_point_tag == 0xa000000c )
4225
0
    {
4226
0
      result = libfsntfs_reparse_point_attribute_get_utf8_substitute_name_size(
4227
0
                reparse_point_attribute,
4228
0
                utf8_string_size,
4229
0
                error );
4230
4231
0
      if( result == -1 )
4232
0
      {
4233
0
        libcerror_error_set(
4234
0
         error,
4235
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4236
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4237
0
         "%s: unable to retrieve size of UTF-8 substitute name from reparse point attribute.",
4238
0
         function );
4239
4240
0
        result = -1;
4241
0
      }
4242
0
    }
4243
0
    else
4244
0
    {
4245
0
      result = 0;
4246
0
    }
4247
0
  }
4248
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4249
0
  if( libcthreads_read_write_lock_release_for_write(
4250
0
       internal_file_entry->read_write_lock,
4251
0
       error ) != 1 )
4252
0
  {
4253
0
    libcerror_error_set(
4254
0
     error,
4255
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4256
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4257
0
     "%s: unable to release read/write lock for writing.",
4258
0
     function );
4259
4260
0
    return( -1 );
4261
0
  }
4262
0
#endif
4263
0
  return( result );
4264
0
}
4265
4266
/* Retrieves the UTF-8 encoded symbolic link target
4267
 * The size should include the end of string character
4268
 * This value is retrieved from a symbolic link $REPARSE_POINT attribute
4269
 * Returns 1 if successful, 0 if not available or -1 on error
4270
 */
4271
int libfsntfs_file_entry_get_utf8_symbolic_link_target(
4272
     libfsntfs_file_entry_t *file_entry,
4273
     uint8_t *utf8_string,
4274
     size_t utf8_string_size,
4275
     libcerror_error_t **error )
4276
0
{
4277
0
  libfsntfs_attribute_t *reparse_point_attribute       = NULL;
4278
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
4279
0
  static char *function                                = "libfsntfs_file_entry_get_utf8_symbolic_link_target";
4280
0
  uint32_t reparse_point_tag           = 0;
4281
0
  int result                                           = 0;
4282
4283
0
  if( file_entry == NULL )
4284
0
  {
4285
0
    libcerror_error_set(
4286
0
     error,
4287
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4288
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4289
0
     "%s: invalid file entry.",
4290
0
     function );
4291
4292
0
    return( -1 );
4293
0
  }
4294
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
4295
4296
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4297
0
  if( libcthreads_read_write_lock_grab_for_write(
4298
0
       internal_file_entry->read_write_lock,
4299
0
       error ) != 1 )
4300
0
  {
4301
0
    libcerror_error_set(
4302
0
     error,
4303
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4304
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4305
0
     "%s: unable to grab read/write lock for writing.",
4306
0
     function );
4307
4308
0
    return( -1 );
4309
0
  }
4310
0
#endif
4311
0
  result = libfsntfs_internal_file_entry_get_reparse_point_attribute(
4312
0
            internal_file_entry,
4313
0
            internal_file_entry->mft_entry,
4314
0
            &reparse_point_attribute,
4315
0
            error );
4316
4317
0
  if( result == -1 )
4318
0
  {
4319
0
    libcerror_error_set(
4320
0
     error,
4321
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4322
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4323
0
     "%s: unable to retrieve reparse point attribute.",
4324
0
     function );
4325
4326
0
    result = -1;
4327
0
  }
4328
0
  else if( result != 0 )
4329
0
  {
4330
0
    result = libfsntfs_reparse_point_attribute_get_tag(
4331
0
              reparse_point_attribute,
4332
0
              &reparse_point_tag,
4333
0
              error );
4334
4335
0
    if( result != 1 )
4336
0
    {
4337
0
      libcerror_error_set(
4338
0
       error,
4339
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4340
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4341
0
       "%s: unable to retrieve size of UTF-8 substitute name from reparse point attribute.",
4342
0
       function );
4343
4344
0
      result = -1;
4345
0
    }
4346
0
    if( reparse_point_tag == 0xa000000c )
4347
0
    {
4348
0
      result = libfsntfs_reparse_point_attribute_get_utf8_substitute_name(
4349
0
          reparse_point_attribute,
4350
0
          utf8_string,
4351
0
          utf8_string_size,
4352
0
          error );
4353
4354
0
      if( result == -1 )
4355
0
      {
4356
0
        libcerror_error_set(
4357
0
         error,
4358
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4359
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4360
0
         "%s: unable to retrieve UTF-8 substitute name from reparse point attribute.",
4361
0
         function );
4362
4363
0
        result = -1;
4364
0
      }
4365
0
    }
4366
0
    else
4367
0
    {
4368
0
      result = 0;
4369
0
    }
4370
0
  }
4371
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4372
0
  if( libcthreads_read_write_lock_release_for_write(
4373
0
       internal_file_entry->read_write_lock,
4374
0
       error ) != 1 )
4375
0
  {
4376
0
    libcerror_error_set(
4377
0
     error,
4378
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4379
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4380
0
     "%s: unable to release read/write lock for writing.",
4381
0
     function );
4382
4383
0
    return( -1 );
4384
0
  }
4385
0
#endif
4386
0
  return( result );
4387
0
}
4388
4389
/* Retrieves the size of the UTF-16 encoded symbolic link target
4390
 * The returned size includes the end of string character
4391
 * This value is retrieved from a symbolic link $REPARSE_POINT attribute
4392
 * Returns 1 if successful, 0 if not available or -1 on error
4393
 */
4394
int libfsntfs_file_entry_get_utf16_symbolic_link_target_size(
4395
     libfsntfs_file_entry_t *file_entry,
4396
     size_t *utf16_string_size,
4397
     libcerror_error_t **error )
4398
0
{
4399
0
  libfsntfs_attribute_t *reparse_point_attribute       = NULL;
4400
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
4401
0
  static char *function                                = "libfsntfs_file_entry_get_utf16_symbolic_link_target_size";
4402
0
  uint32_t reparse_point_tag           = 0;
4403
0
  int result                                           = 0;
4404
4405
0
  if( file_entry == NULL )
4406
0
  {
4407
0
    libcerror_error_set(
4408
0
     error,
4409
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4410
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4411
0
     "%s: invalid file entry.",
4412
0
     function );
4413
4414
0
    return( -1 );
4415
0
  }
4416
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
4417
4418
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4419
0
  if( libcthreads_read_write_lock_grab_for_write(
4420
0
       internal_file_entry->read_write_lock,
4421
0
       error ) != 1 )
4422
0
  {
4423
0
    libcerror_error_set(
4424
0
     error,
4425
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4426
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4427
0
     "%s: unable to grab read/write lock for writing.",
4428
0
     function );
4429
4430
0
    return( -1 );
4431
0
  }
4432
0
#endif
4433
0
  result = libfsntfs_internal_file_entry_get_reparse_point_attribute(
4434
0
            internal_file_entry,
4435
0
            internal_file_entry->mft_entry,
4436
0
            &reparse_point_attribute,
4437
0
            error );
4438
4439
0
  if( result == -1 )
4440
0
  {
4441
0
    libcerror_error_set(
4442
0
     error,
4443
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4444
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4445
0
     "%s: unable to retrieve reparse point attribute.",
4446
0
     function );
4447
4448
0
    result = -1;
4449
0
  }
4450
0
  else if( result != 0 )
4451
0
  {
4452
0
    result = libfsntfs_reparse_point_attribute_get_tag(
4453
0
              reparse_point_attribute,
4454
0
              &reparse_point_tag,
4455
0
              error );
4456
4457
0
    if( result != 1 )
4458
0
    {
4459
0
      libcerror_error_set(
4460
0
       error,
4461
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4462
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4463
0
       "%s: unable to retrieve size of UTF-8 substitute name from reparse point attribute.",
4464
0
       function );
4465
4466
0
      result = -1;
4467
0
    }
4468
0
    if( reparse_point_tag == 0xa000000c )
4469
0
    {
4470
0
      result = libfsntfs_reparse_point_attribute_get_utf16_substitute_name_size(
4471
0
          reparse_point_attribute,
4472
0
          utf16_string_size,
4473
0
          error );
4474
4475
0
      if( result == -1 )
4476
0
      {
4477
0
        libcerror_error_set(
4478
0
         error,
4479
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4480
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4481
0
         "%s: unable to retrieve size of UTF-16 substitute name from reparse point attribute.",
4482
0
         function );
4483
4484
0
        result = -1;
4485
0
      }
4486
0
    }
4487
0
    else
4488
0
    {
4489
0
      result = 0;
4490
0
    }
4491
0
  }
4492
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4493
0
  if( libcthreads_read_write_lock_release_for_write(
4494
0
       internal_file_entry->read_write_lock,
4495
0
       error ) != 1 )
4496
0
  {
4497
0
    libcerror_error_set(
4498
0
     error,
4499
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4500
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4501
0
     "%s: unable to release read/write lock for writing.",
4502
0
     function );
4503
4504
0
    return( -1 );
4505
0
  }
4506
0
#endif
4507
0
  return( result );
4508
0
}
4509
4510
/* Retrieves the UTF-16 encoded symbolic link target
4511
 * The size should include the end of string character
4512
 * This value is retrieved from a symbolic link $REPARSE_POINT attribute
4513
 * Returns 1 if successful, 0 if not available or -1 on error
4514
 */
4515
int libfsntfs_file_entry_get_utf16_symbolic_link_target(
4516
     libfsntfs_file_entry_t *file_entry,
4517
     uint16_t *utf16_string,
4518
     size_t utf16_string_size,
4519
     libcerror_error_t **error )
4520
0
{
4521
0
  libfsntfs_attribute_t *reparse_point_attribute       = NULL;
4522
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
4523
0
  static char *function                                = "libfsntfs_file_entry_get_utf16_symbolic_link_target";
4524
0
  uint32_t reparse_point_tag           = 0;
4525
0
  int result                                           = 0;
4526
4527
0
  if( file_entry == NULL )
4528
0
  {
4529
0
    libcerror_error_set(
4530
0
     error,
4531
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4532
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4533
0
     "%s: invalid file entry.",
4534
0
     function );
4535
4536
0
    return( -1 );
4537
0
  }
4538
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
4539
4540
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4541
0
  if( libcthreads_read_write_lock_grab_for_write(
4542
0
       internal_file_entry->read_write_lock,
4543
0
       error ) != 1 )
4544
0
  {
4545
0
    libcerror_error_set(
4546
0
     error,
4547
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4548
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4549
0
     "%s: unable to grab read/write lock for writing.",
4550
0
     function );
4551
4552
0
    return( -1 );
4553
0
  }
4554
0
#endif
4555
0
  result = libfsntfs_internal_file_entry_get_reparse_point_attribute(
4556
0
            internal_file_entry,
4557
0
            internal_file_entry->mft_entry,
4558
0
            &reparse_point_attribute,
4559
0
            error );
4560
4561
0
  if( result == -1 )
4562
0
  {
4563
0
    libcerror_error_set(
4564
0
     error,
4565
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4566
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4567
0
     "%s: unable to retrieve reparse point attribute.",
4568
0
     function );
4569
4570
0
    result = -1;
4571
0
  }
4572
0
  else if( result != 0 )
4573
0
  {
4574
0
    result = libfsntfs_reparse_point_attribute_get_tag(
4575
0
              reparse_point_attribute,
4576
0
              &reparse_point_tag,
4577
0
              error );
4578
4579
0
    if( result != 1 )
4580
0
    {
4581
0
      libcerror_error_set(
4582
0
       error,
4583
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4584
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4585
0
       "%s: unable to retrieve size of UTF-8 substitute name from reparse point attribute.",
4586
0
       function );
4587
4588
0
      result = -1;
4589
0
    }
4590
0
    if( reparse_point_tag == 0xa000000c )
4591
0
    {
4592
0
      result = libfsntfs_reparse_point_attribute_get_utf16_substitute_name(
4593
0
          reparse_point_attribute,
4594
0
          utf16_string,
4595
0
          utf16_string_size,
4596
0
          error );
4597
4598
0
      if( result == -1 )
4599
0
      {
4600
0
        libcerror_error_set(
4601
0
         error,
4602
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4603
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4604
0
         "%s: unable to retrieve UTF-16 substitute name from reparse point attribute.",
4605
0
         function );
4606
4607
0
        result = -1;
4608
0
      }
4609
0
    }
4610
0
    else
4611
0
    {
4612
0
      result = 0;
4613
0
    }
4614
0
  }
4615
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4616
0
  if( libcthreads_read_write_lock_release_for_write(
4617
0
       internal_file_entry->read_write_lock,
4618
0
       error ) != 1 )
4619
0
  {
4620
0
    libcerror_error_set(
4621
0
     error,
4622
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4623
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4624
0
     "%s: unable to release read/write lock for writing.",
4625
0
     function );
4626
4627
0
    return( -1 );
4628
0
  }
4629
0
#endif
4630
0
  return( result );
4631
0
}
4632
4633
/* Retrieves the security descriptor (data) size
4634
 * Returns 1 if successful, 0 if not available or -1 on error
4635
 */
4636
int libfsntfs_file_entry_get_security_descriptor_size(
4637
     libfsntfs_file_entry_t *file_entry,
4638
     size_t *data_size,
4639
     libcerror_error_t **error )
4640
0
{
4641
0
  libfsntfs_attribute_t *security_descriptor_attribute                 = NULL;
4642
0
  libfsntfs_attribute_t *standard_information_attribute                = NULL;
4643
0
  libfsntfs_internal_file_entry_t *internal_file_entry                 = NULL;
4644
0
  libfsntfs_security_descriptor_values_t *security_descriptor_values   = NULL;
4645
0
  libfsntfs_standard_information_values_t *standard_information_values = NULL;
4646
0
  static char *function                                                = "libfsntfs_file_entry_get_security_descriptor_size";
4647
0
  uint32_t security_descriptor_identifier                              = 0;
4648
0
  int result                                                           = 0;
4649
4650
0
  if( file_entry == NULL )
4651
0
  {
4652
0
    libcerror_error_set(
4653
0
     error,
4654
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4655
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4656
0
     "%s: invalid file entry.",
4657
0
     function );
4658
4659
0
    return( -1 );
4660
0
  }
4661
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
4662
4663
/* TODO add thread lock suport */
4664
4665
0
  result = libfsntfs_internal_file_entry_get_security_descriptor_attribute(
4666
0
            internal_file_entry,
4667
0
            &security_descriptor_attribute,
4668
0
            error );
4669
4670
0
  if( result == -1 )
4671
0
  {
4672
0
    libcerror_error_set(
4673
0
     error,
4674
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4675
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4676
0
     "%s: unable to retrieve security descriptor attribute.",
4677
0
     function );
4678
4679
0
    return( -1 );
4680
0
  }
4681
0
  else if( result != 0 )
4682
0
  {
4683
0
    if( libfsntfs_internal_attribute_get_value(
4684
0
         (libfsntfs_internal_attribute_t *) security_descriptor_attribute,
4685
0
         (intptr_t **) &security_descriptor_values,
4686
0
         error ) != 1 )
4687
0
    {
4688
0
      libcerror_error_set(
4689
0
       error,
4690
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4691
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4692
0
       "%s: unable to retrieve security descriptor attribute value.",
4693
0
       function );
4694
4695
0
      goto on_error;
4696
0
    }
4697
0
  }
4698
0
  else
4699
0
  {
4700
0
    result = libfsntfs_internal_file_entry_get_standard_information_attribute(
4701
0
              internal_file_entry,
4702
0
              &standard_information_attribute,
4703
0
              error );
4704
4705
0
    if( result == -1 )
4706
0
    {
4707
0
      libcerror_error_set(
4708
0
       error,
4709
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4710
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4711
0
       "%s: unable to retrieve standard information attribute.",
4712
0
       function );
4713
4714
0
      return( -1 );
4715
0
    }
4716
0
    else if( result == 0 )
4717
0
    {
4718
0
      return( 0 );
4719
0
    }
4720
0
    if( internal_file_entry->security_descriptor_values == NULL )
4721
0
    {
4722
0
      if( libfsntfs_internal_attribute_get_value(
4723
0
           (libfsntfs_internal_attribute_t *) standard_information_attribute,
4724
0
           (intptr_t **) &standard_information_values,
4725
0
           error ) != 1 )
4726
0
      {
4727
0
        libcerror_error_set(
4728
0
         error,
4729
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4730
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4731
0
         "%s: unable to retrieve standard information attribute value.",
4732
0
         function );
4733
4734
0
        goto on_error;
4735
0
      }
4736
0
      if( libfsntfs_standard_information_values_get_security_descriptor_identifier(
4737
0
           standard_information_values,
4738
0
           &security_descriptor_identifier,
4739
0
           error ) != 1 )
4740
0
      {
4741
0
        libcerror_error_set(
4742
0
         error,
4743
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4744
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4745
0
         "%s: unable to retrieve security descriptor identifier from standard information attribute.",
4746
0
         function );
4747
4748
0
        goto on_error;
4749
0
      }
4750
0
      result = libfsntfs_file_system_get_security_descriptor_values_by_identifier(
4751
0
                internal_file_entry->file_system,
4752
0
                internal_file_entry->file_io_handle,
4753
0
                security_descriptor_identifier,
4754
0
                &( internal_file_entry->security_descriptor_values ),
4755
0
                error );
4756
4757
0
      if( result == -1 )
4758
0
      {
4759
0
        libcerror_error_set(
4760
0
         error,
4761
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4762
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4763
0
         "%s: unable to retrieve security descriptor from index for identifier: %" PRIu32 ".",
4764
0
         function,
4765
0
         security_descriptor_identifier );
4766
4767
0
        goto on_error;
4768
0
      }
4769
0
      else if( result == 0 )
4770
0
      {
4771
0
        return( 0 );
4772
0
      }
4773
      /* file_entry takes over management of security_descriptor_values
4774
       */
4775
0
    }
4776
0
    security_descriptor_values = internal_file_entry->security_descriptor_values;
4777
0
  }
4778
0
  result = libfsntfs_security_descriptor_values_get_data_size(
4779
0
            security_descriptor_values,
4780
0
            data_size,
4781
0
            error );
4782
4783
0
  if( result == -1 )
4784
0
  {
4785
0
    libcerror_error_set(
4786
0
     error,
4787
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4788
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4789
0
     "%s: unable to retrieve security descriptor data size.",
4790
0
     function );
4791
4792
0
    goto on_error;
4793
0
  }
4794
0
  return( result );
4795
4796
0
on_error:
4797
0
  if( internal_file_entry->security_descriptor_values != NULL )
4798
0
  {
4799
0
    libfsntfs_security_descriptor_values_free(
4800
0
     &( internal_file_entry->security_descriptor_values ),
4801
0
     NULL );
4802
0
  }
4803
0
  return( -1 );
4804
0
}
4805
4806
/* Retrieves the security descriptor (data)
4807
 * Returns 1 if successful, 0 if not available or -1 on error
4808
 */
4809
int libfsntfs_file_entry_get_security_descriptor(
4810
     libfsntfs_file_entry_t *file_entry,
4811
     uint8_t *data,
4812
     size_t data_size,
4813
     libcerror_error_t **error )
4814
0
{
4815
0
  libfsntfs_attribute_t *security_descriptor_attribute                 = NULL;
4816
0
  libfsntfs_attribute_t *standard_information_attribute                = NULL;
4817
0
  libfsntfs_internal_file_entry_t *internal_file_entry                 = NULL;
4818
0
  libfsntfs_security_descriptor_values_t *security_descriptor_values   = NULL;
4819
0
  libfsntfs_standard_information_values_t *standard_information_values = NULL;
4820
0
  static char *function                                                = "libfsntfs_file_entry_get_security_descriptor";
4821
0
  uint32_t security_descriptor_identifier                              = 0;
4822
0
  int result                                                           = 0;
4823
4824
0
  if( file_entry == NULL )
4825
0
  {
4826
0
    libcerror_error_set(
4827
0
     error,
4828
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4829
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4830
0
     "%s: invalid file entry.",
4831
0
     function );
4832
4833
0
    return( -1 );
4834
0
  }
4835
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
4836
4837
/* TODO add thread lock suport */
4838
4839
0
  result = libfsntfs_internal_file_entry_get_security_descriptor_attribute(
4840
0
            internal_file_entry,
4841
0
            &security_descriptor_attribute,
4842
0
            error );
4843
4844
0
  if( result == -1 )
4845
0
  {
4846
0
    libcerror_error_set(
4847
0
     error,
4848
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4849
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4850
0
     "%s: unable to retrieve security descriptor attribute.",
4851
0
     function );
4852
4853
0
    return( -1 );
4854
0
  }
4855
0
  else if( result != 0 )
4856
0
  {
4857
0
    if( libfsntfs_internal_attribute_get_value(
4858
0
         (libfsntfs_internal_attribute_t *) security_descriptor_attribute,
4859
0
         (intptr_t **) &security_descriptor_values,
4860
0
         error ) != 1 )
4861
0
    {
4862
0
      libcerror_error_set(
4863
0
       error,
4864
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4865
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4866
0
       "%s: unable to retrieve security descriptor attribute value.",
4867
0
       function );
4868
4869
0
      goto on_error;
4870
0
    }
4871
0
  }
4872
0
  else
4873
0
  {
4874
0
    result = libfsntfs_internal_file_entry_get_standard_information_attribute(
4875
0
              internal_file_entry,
4876
0
              &standard_information_attribute,
4877
0
              error );
4878
4879
0
    if( result == -1 )
4880
0
    {
4881
0
      libcerror_error_set(
4882
0
       error,
4883
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4884
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4885
0
       "%s: unable to retrieve standard information attribute.",
4886
0
       function );
4887
4888
0
      return( -1 );
4889
0
    }
4890
0
    else if( result == 0 )
4891
0
    {
4892
0
      return( 0 );
4893
0
    }
4894
0
    if( internal_file_entry->security_descriptor_values == NULL )
4895
0
    {
4896
0
      if( libfsntfs_internal_attribute_get_value(
4897
0
           (libfsntfs_internal_attribute_t *) standard_information_attribute,
4898
0
           (intptr_t **) &standard_information_values,
4899
0
           error ) != 1 )
4900
0
      {
4901
0
        libcerror_error_set(
4902
0
         error,
4903
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4904
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4905
0
         "%s: unable to retrieve standard information attribute value.",
4906
0
         function );
4907
4908
0
        goto on_error;
4909
0
      }
4910
0
      if( libfsntfs_standard_information_values_get_security_descriptor_identifier(
4911
0
           standard_information_values,
4912
0
           &security_descriptor_identifier,
4913
0
           error ) != 1 )
4914
0
      {
4915
0
        libcerror_error_set(
4916
0
         error,
4917
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4918
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4919
0
         "%s: unable to retrieve security descriptor identifier from standard information attribute.",
4920
0
         function );
4921
4922
0
        goto on_error;
4923
0
      }
4924
0
      result = libfsntfs_file_system_get_security_descriptor_values_by_identifier(
4925
0
                internal_file_entry->file_system,
4926
0
                internal_file_entry->file_io_handle,
4927
0
                security_descriptor_identifier,
4928
0
                &( internal_file_entry->security_descriptor_values ),
4929
0
                error );
4930
4931
0
      if( result == -1 )
4932
0
      {
4933
0
        libcerror_error_set(
4934
0
         error,
4935
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4936
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4937
0
         "%s: unable to retrieve security descriptor from index for identifier: %" PRIu32 ".",
4938
0
         function,
4939
0
         security_descriptor_identifier );
4940
4941
0
        goto on_error;
4942
0
      }
4943
0
      else if( result == 0 )
4944
0
      {
4945
0
        return( 0 );
4946
0
      }
4947
      /* file_entry takes over management of security_descriptor_values
4948
       */
4949
0
    }
4950
0
    security_descriptor_values = internal_file_entry->security_descriptor_values;
4951
0
  }
4952
0
  result = libfsntfs_security_descriptor_values_get_data(
4953
0
            security_descriptor_values,
4954
0
            data,
4955
0
            data_size,
4956
0
            error );
4957
4958
0
  if( result == -1 )
4959
0
  {
4960
0
    libcerror_error_set(
4961
0
     error,
4962
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4963
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4964
0
     "%s: unable to retrieve security descriptor data.",
4965
0
     function );
4966
4967
0
    goto on_error;
4968
0
  }
4969
0
  return( result );
4970
4971
0
on_error:
4972
0
  if( internal_file_entry->security_descriptor_values != NULL )
4973
0
  {
4974
0
    libfsntfs_security_descriptor_values_free(
4975
0
     &( internal_file_entry->security_descriptor_values ),
4976
0
     NULL );
4977
0
  }
4978
0
  return( -1 );
4979
0
}
4980
4981
/* Retrieves the number of attributes
4982
 * Returns 1 if successful or -1 on error
4983
 */
4984
int libfsntfs_file_entry_get_number_of_attributes(
4985
     libfsntfs_file_entry_t *file_entry,
4986
     int *number_of_attributes,
4987
     libcerror_error_t **error )
4988
0
{
4989
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
4990
0
  static char *function                                = "libfsntfs_file_entry_get_number_of_attributes";
4991
0
  int result                                           = 1;
4992
4993
0
  if( file_entry == NULL )
4994
0
  {
4995
0
    libcerror_error_set(
4996
0
     error,
4997
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4998
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4999
0
     "%s: invalid file entry.",
5000
0
     function );
5001
5002
0
    return( -1 );
5003
0
  }
5004
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5005
5006
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5007
0
  if( libcthreads_read_write_lock_grab_for_read(
5008
0
       internal_file_entry->read_write_lock,
5009
0
       error ) != 1 )
5010
0
  {
5011
0
    libcerror_error_set(
5012
0
     error,
5013
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5014
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5015
0
     "%s: unable to grab read/write lock for reading.",
5016
0
     function );
5017
5018
0
    return( -1 );
5019
0
  }
5020
0
#endif
5021
0
  if( libfsntfs_mft_entry_get_number_of_attributes(
5022
0
       internal_file_entry->mft_entry,
5023
0
       number_of_attributes,
5024
0
       error ) != 1 )
5025
0
  {
5026
0
    libcerror_error_set(
5027
0
     error,
5028
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5029
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5030
0
     "%s: unable to retrieve number of attributes.",
5031
0
     function );
5032
5033
0
    result = -1;
5034
0
  }
5035
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5036
0
  if( libcthreads_read_write_lock_release_for_read(
5037
0
       internal_file_entry->read_write_lock,
5038
0
       error ) != 1 )
5039
0
  {
5040
0
    libcerror_error_set(
5041
0
     error,
5042
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5043
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5044
0
     "%s: unable to release read/write lock for reading.",
5045
0
     function );
5046
5047
0
    return( -1 );
5048
0
  }
5049
0
#endif
5050
0
  return( result );
5051
0
}
5052
5053
/* Retrieves the attribute for the specific index
5054
 * Returns 1 if successful or -1 on error
5055
 */
5056
int libfsntfs_file_entry_get_attribute_by_index(
5057
     libfsntfs_file_entry_t *file_entry,
5058
     int attribute_index,
5059
     libfsntfs_attribute_t **attribute,
5060
     libcerror_error_t **error )
5061
0
{
5062
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5063
0
  static char *function                                = "libfsntfs_file_entry_get_attribute_by_index";
5064
0
  int result                                           = 1;
5065
5066
0
  if( file_entry == NULL )
5067
0
  {
5068
0
    libcerror_error_set(
5069
0
     error,
5070
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5071
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5072
0
     "%s: invalid file entry.",
5073
0
     function );
5074
5075
0
    return( -1 );
5076
0
  }
5077
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5078
5079
0
  if( attribute == NULL )
5080
0
  {
5081
0
    libcerror_error_set(
5082
0
     error,
5083
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5084
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5085
0
     "%s: invalid attribute.",
5086
0
     function );
5087
5088
0
    return( -1 );
5089
0
  }
5090
0
  if( *attribute != NULL )
5091
0
  {
5092
0
    libcerror_error_set(
5093
0
     error,
5094
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5095
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
5096
0
     "%s: invalid attribute value already set.",
5097
0
     function );
5098
5099
0
    return( -1 );
5100
0
  }
5101
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5102
0
  if( libcthreads_read_write_lock_grab_for_write(
5103
0
       internal_file_entry->read_write_lock,
5104
0
       error ) != 1 )
5105
0
  {
5106
0
    libcerror_error_set(
5107
0
     error,
5108
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5109
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5110
0
     "%s: unable to grab read/write lock for writing.",
5111
0
     function );
5112
5113
0
    return( -1 );
5114
0
  }
5115
0
#endif
5116
0
  if( libfsntfs_internal_file_entry_get_attribute_by_index(
5117
0
       internal_file_entry,
5118
0
       internal_file_entry->mft_entry,
5119
0
       attribute_index,
5120
0
       attribute,
5121
0
       error ) != 1 )
5122
0
  {
5123
0
    libcerror_error_set(
5124
0
     error,
5125
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5126
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5127
0
     "%s: unable to retrieve attribute: %d.",
5128
0
     function,
5129
0
     attribute_index );
5130
5131
0
    result = -1;
5132
0
  }
5133
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5134
0
  if( libcthreads_read_write_lock_release_for_write(
5135
0
       internal_file_entry->read_write_lock,
5136
0
       error ) != 1 )
5137
0
  {
5138
0
    libcerror_error_set(
5139
0
     error,
5140
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5141
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5142
0
     "%s: unable to release read/write lock for writing.",
5143
0
     function );
5144
5145
0
    return( -1 );
5146
0
  }
5147
0
#endif
5148
0
  return( result );
5149
0
}
5150
5151
/* Determines if the file entry has a $I30 entry
5152
 * Returns 1 if the file entry has a $I30 entry, 0 if not or -1 on error
5153
 */
5154
int libfsntfs_file_entry_has_i30_entry(
5155
     libfsntfs_file_entry_t *file_entry,
5156
     libcerror_error_t **error )
5157
0
{
5158
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5159
0
  static char *function                                = "libfsntfs_file_entry_has_i30_entry";
5160
0
  int result                                           = 0;
5161
5162
0
  if( file_entry == NULL )
5163
0
  {
5164
0
    libcerror_error_set(
5165
0
     error,
5166
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5167
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5168
0
     "%s: invalid file entry.",
5169
0
     function );
5170
5171
0
    return( -1 );
5172
0
  }
5173
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5174
5175
0
  if( internal_file_entry->directory_entry != NULL )
5176
0
  {
5177
0
    result = 1;
5178
0
  }
5179
0
  return( result );
5180
0
}
5181
5182
/* Determines if the file entry has the directory entries ($I30) index
5183
 * Returns 1 if the file entry has a directory entries index, 0 if not or -1 on error
5184
 */
5185
int libfsntfs_file_entry_has_directory_entries_index(
5186
     libfsntfs_file_entry_t *file_entry,
5187
     libcerror_error_t **error )
5188
0
{
5189
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5190
0
  static char *function                                = "libfsntfs_file_entry_has_directory_entries_index";
5191
0
  int result                                           = 0;
5192
5193
0
  if( file_entry == NULL )
5194
0
  {
5195
0
    libcerror_error_set(
5196
0
     error,
5197
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5198
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5199
0
     "%s: invalid file entry.",
5200
0
     function );
5201
5202
0
    return( -1 );
5203
0
  }
5204
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5205
5206
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5207
0
  if( libcthreads_read_write_lock_grab_for_read(
5208
0
       internal_file_entry->read_write_lock,
5209
0
       error ) != 1 )
5210
0
  {
5211
0
    libcerror_error_set(
5212
0
     error,
5213
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5214
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5215
0
     "%s: unable to grab read/write lock for reading.",
5216
0
     function );
5217
5218
0
    return( -1 );
5219
0
  }
5220
0
#endif
5221
0
  result = libfsntfs_mft_entry_has_directory_entries_index(
5222
0
            internal_file_entry->mft_entry,
5223
0
            error );
5224
5225
0
  if( result == -1 )
5226
0
  {
5227
0
    libcerror_error_set(
5228
0
     error,
5229
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5230
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5231
0
     "%s: unable to determine if MFT entry has an directory entries index.",
5232
0
     function );
5233
5234
0
    result = -1;
5235
0
  }
5236
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5237
0
  if( libcthreads_read_write_lock_release_for_read(
5238
0
       internal_file_entry->read_write_lock,
5239
0
       error ) != 1 )
5240
0
  {
5241
0
    libcerror_error_set(
5242
0
     error,
5243
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5244
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5245
0
     "%s: unable to release read/write lock for reading.",
5246
0
     function );
5247
5248
0
    return( -1 );
5249
0
  }
5250
0
#endif
5251
0
  return( result );
5252
0
}
5253
5254
/* Determines if the file entry has a default data stream (nameless $DATA attribute)
5255
 * Returns 1 if the file entry has a default data stream, 0 if not or -1 on error
5256
 */
5257
int libfsntfs_file_entry_has_default_data_stream(
5258
     libfsntfs_file_entry_t *file_entry,
5259
     libcerror_error_t **error )
5260
0
{
5261
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5262
0
  static char *function                                = "libfsntfs_file_entry_has_default_data_stream";
5263
0
  int result                                           = 0;
5264
5265
0
  if( file_entry == NULL )
5266
0
  {
5267
0
    libcerror_error_set(
5268
0
     error,
5269
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5270
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5271
0
     "%s: invalid file entry.",
5272
0
     function );
5273
5274
0
    return( -1 );
5275
0
  }
5276
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5277
5278
0
  if( internal_file_entry->mft_entry == NULL )
5279
0
  {
5280
0
    libcerror_error_set(
5281
0
     error,
5282
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5283
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5284
0
     "%s: invalid file entry - missing MFT entry.",
5285
0
     function );
5286
5287
0
    return( -1 );
5288
0
  }
5289
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5290
0
  if( libcthreads_read_write_lock_grab_for_read(
5291
0
       internal_file_entry->read_write_lock,
5292
0
       error ) != 1 )
5293
0
  {
5294
0
    libcerror_error_set(
5295
0
     error,
5296
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5297
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5298
0
     "%s: unable to grab read/write lock for reading.",
5299
0
     function );
5300
5301
0
    return( -1 );
5302
0
  }
5303
0
#endif
5304
0
  if( internal_file_entry->mft_entry->data_attribute != NULL )
5305
0
  {
5306
0
    result = 1;
5307
0
  }
5308
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5309
0
  if( libcthreads_read_write_lock_release_for_read(
5310
0
       internal_file_entry->read_write_lock,
5311
0
       error ) != 1 )
5312
0
  {
5313
0
    libcerror_error_set(
5314
0
     error,
5315
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5316
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5317
0
     "%s: unable to release read/write lock for reading.",
5318
0
     function );
5319
5320
0
    return( -1 );
5321
0
  }
5322
0
#endif
5323
0
  return( result );
5324
0
}
5325
5326
/* Determines if the file entry is a symbolic link
5327
 * Returns 1 if the file entry is a symbolic link, 0 if not or -1 on error
5328
 */
5329
int libfsntfs_file_entry_is_symbolic_link(
5330
     libfsntfs_file_entry_t *file_entry,
5331
     libcerror_error_t **error )
5332
0
{
5333
0
  libfsntfs_attribute_t *reparse_point_attribute       = NULL;
5334
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5335
0
  static char *function                                = "libfsntfs_file_entry_is_symbolic_link";
5336
0
  uint32_t reparse_point_tag                           = 0;
5337
0
  int result                                           = 0;
5338
5339
0
  if( file_entry == NULL )
5340
0
  {
5341
0
    libcerror_error_set(
5342
0
     error,
5343
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5344
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5345
0
     "%s: invalid file entry.",
5346
0
     function );
5347
5348
0
    return( -1 );
5349
0
  }
5350
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5351
5352
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5353
0
  if( libcthreads_read_write_lock_grab_for_read(
5354
0
       internal_file_entry->read_write_lock,
5355
0
       error ) != 1 )
5356
0
  {
5357
0
    libcerror_error_set(
5358
0
     error,
5359
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5360
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5361
0
     "%s: unable to grab read/write lock for reading.",
5362
0
     function );
5363
5364
0
    return( -1 );
5365
0
  }
5366
0
#endif
5367
0
  result = libfsntfs_internal_file_entry_get_reparse_point_attribute(
5368
0
            internal_file_entry,
5369
0
            internal_file_entry->mft_entry,
5370
0
            &reparse_point_attribute,
5371
0
            error );
5372
5373
0
  if( result == -1 )
5374
0
  {
5375
0
    libcerror_error_set(
5376
0
     error,
5377
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5378
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5379
0
     "%s: unable to retrieve reparse point attribute.",
5380
0
     function );
5381
5382
0
    result = -1;
5383
0
  }
5384
0
  else if( result != 0 )
5385
0
  {
5386
0
    if( libfsntfs_reparse_point_attribute_get_tag(
5387
0
         reparse_point_attribute,
5388
0
         &reparse_point_tag,
5389
0
         error ) != 1 )
5390
0
    {
5391
0
      libcerror_error_set(
5392
0
       error,
5393
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5394
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5395
0
       "%s: unable to retrieve tag from reparse point attribute.",
5396
0
       function );
5397
5398
0
      result = -1;
5399
0
    }
5400
0
    if( reparse_point_tag == 0xa000000cUL )
5401
0
    {
5402
0
      result = 1;
5403
0
    }
5404
0
    else
5405
0
    {
5406
0
      result = 0;
5407
0
    }
5408
0
  }
5409
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5410
0
  if( libcthreads_read_write_lock_release_for_read(
5411
0
       internal_file_entry->read_write_lock,
5412
0
       error ) != 1 )
5413
0
  {
5414
0
    libcerror_error_set(
5415
0
     error,
5416
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5417
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5418
0
     "%s: unable to release read/write lock for reading.",
5419
0
     function );
5420
5421
0
    return( -1 );
5422
0
  }
5423
0
#endif
5424
0
  return( result );
5425
0
}
5426
5427
/* Retrieves the number of alternate data streams
5428
 * Returns 1 if successful or -1 on error
5429
 */
5430
int libfsntfs_file_entry_get_number_of_alternate_data_streams(
5431
     libfsntfs_file_entry_t *file_entry,
5432
     int *number_of_alternate_data_streams,
5433
     libcerror_error_t **error )
5434
0
{
5435
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5436
0
  static char *function                                = "libfsntfs_file_entry_get_number_of_alternate_data_streams";
5437
0
  int result                                           = 1;
5438
5439
0
  if( file_entry == NULL )
5440
0
  {
5441
0
    libcerror_error_set(
5442
0
     error,
5443
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5444
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5445
0
     "%s: invalid file entry.",
5446
0
     function );
5447
5448
0
    return( -1 );
5449
0
  }
5450
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5451
5452
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5453
0
  if( libcthreads_read_write_lock_grab_for_read(
5454
0
       internal_file_entry->read_write_lock,
5455
0
       error ) != 1 )
5456
0
  {
5457
0
    libcerror_error_set(
5458
0
     error,
5459
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5460
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5461
0
     "%s: unable to grab read/write lock for reading.",
5462
0
     function );
5463
5464
0
    return( -1 );
5465
0
  }
5466
0
#endif
5467
0
  if( libfsntfs_mft_entry_get_number_of_alternate_data_attributes(
5468
0
       internal_file_entry->mft_entry,
5469
0
       number_of_alternate_data_streams,
5470
0
       error ) != 1 )
5471
0
  {
5472
0
    libcerror_error_set(
5473
0
     error,
5474
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5475
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5476
0
     "%s: unable to retrieve number of alternate data attributes.",
5477
0
     function );
5478
5479
0
    result = -1;
5480
0
  }
5481
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5482
0
  if( libcthreads_read_write_lock_release_for_read(
5483
0
       internal_file_entry->read_write_lock,
5484
0
       error ) != 1 )
5485
0
  {
5486
0
    libcerror_error_set(
5487
0
     error,
5488
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5489
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5490
0
     "%s: unable to release read/write lock for reading.",
5491
0
     function );
5492
5493
0
    return( -1 );
5494
0
  }
5495
0
#endif
5496
0
  return( result );
5497
0
}
5498
5499
/* Retrieves the alternate data stream for the specific index
5500
 * Returns 1 if successful or -1 on error
5501
 */
5502
int libfsntfs_file_entry_get_alternate_data_stream_by_index(
5503
     libfsntfs_file_entry_t *file_entry,
5504
     int alternate_data_stream_index,
5505
     libfsntfs_data_stream_t **alternate_data_stream,
5506
     libcerror_error_t **error )
5507
0
{
5508
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5509
0
  libfsntfs_mft_attribute_t *data_attribute            = NULL;
5510
0
  static char *function                                = "libfsntfs_file_entry_get_alternate_data_stream_by_index";
5511
0
  int result                                           = 1;
5512
5513
0
  if( file_entry == NULL )
5514
0
  {
5515
0
    libcerror_error_set(
5516
0
     error,
5517
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5518
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5519
0
     "%s: invalid file entry.",
5520
0
     function );
5521
5522
0
    return( -1 );
5523
0
  }
5524
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5525
5526
0
  if( alternate_data_stream == NULL )
5527
0
  {
5528
0
    libcerror_error_set(
5529
0
     error,
5530
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5531
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5532
0
     "%s: invalid alternate data stream.",
5533
0
     function );
5534
5535
0
    return( -1 );
5536
0
  }
5537
0
  if( *alternate_data_stream != NULL )
5538
0
  {
5539
0
    libcerror_error_set(
5540
0
     error,
5541
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5542
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
5543
0
     "%s: invalid alternate data stream value already set.",
5544
0
     function );
5545
5546
0
    return( -1 );
5547
0
  }
5548
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5549
0
  if( libcthreads_read_write_lock_grab_for_read(
5550
0
       internal_file_entry->read_write_lock,
5551
0
       error ) != 1 )
5552
0
  {
5553
0
    libcerror_error_set(
5554
0
     error,
5555
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5556
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5557
0
     "%s: unable to grab read/write lock for reading.",
5558
0
     function );
5559
5560
0
    return( -1 );
5561
0
  }
5562
0
#endif
5563
0
  if( libfsntfs_mft_entry_get_alternate_data_attribute_by_index(
5564
0
       internal_file_entry->mft_entry,
5565
0
       alternate_data_stream_index,
5566
0
       &data_attribute,
5567
0
       error ) != 1 )
5568
0
  {
5569
0
    libcerror_error_set(
5570
0
     error,
5571
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5572
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5573
0
     "%s: unable to retrieve alternate data attribute: %d.",
5574
0
     function,
5575
0
     alternate_data_stream_index );
5576
5577
0
    result = -1;
5578
0
  }
5579
0
  if( result == 1 )
5580
0
  {
5581
0
    if( libfsntfs_data_stream_initialize(
5582
0
         alternate_data_stream,
5583
0
         internal_file_entry->io_handle,
5584
0
         internal_file_entry->file_io_handle,
5585
0
         data_attribute,
5586
0
         error ) != 1 )
5587
0
    {
5588
0
      libcerror_error_set(
5589
0
       error,
5590
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5591
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5592
0
       "%s: unable to create alternate data stream: %d.",
5593
0
       function,
5594
0
       alternate_data_stream_index );
5595
5596
0
      result = -1;
5597
0
    }
5598
0
  }
5599
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5600
0
  if( libcthreads_read_write_lock_release_for_read(
5601
0
       internal_file_entry->read_write_lock,
5602
0
       error ) != 1 )
5603
0
  {
5604
0
    libcerror_error_set(
5605
0
     error,
5606
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5607
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5608
0
     "%s: unable to release read/write lock for reading.",
5609
0
     function );
5610
5611
0
    return( -1 );
5612
0
  }
5613
0
#endif
5614
0
  return( result );
5615
0
}
5616
5617
/* Determines if there is an alternate data stream for an UTF-8 encoded name
5618
 * Returns 1 if available, 0 if not or -1 on error
5619
 */
5620
int libfsntfs_file_entry_has_alternate_data_stream_by_utf8_name(
5621
     libfsntfs_file_entry_t *file_entry,
5622
     const uint8_t *utf8_string,
5623
     size_t utf8_string_length,
5624
     libcerror_error_t **error )
5625
0
{
5626
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5627
0
  libfsntfs_mft_attribute_t *data_attribute            = NULL;
5628
0
  static char *function                                = "libfsntfs_file_entry_has_alternate_data_stream_by_utf8_name";
5629
0
  int result                                           = 0;
5630
5631
0
  if( file_entry == NULL )
5632
0
  {
5633
0
    libcerror_error_set(
5634
0
     error,
5635
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5636
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5637
0
     "%s: invalid file entry.",
5638
0
     function );
5639
5640
0
    return( -1 );
5641
0
  }
5642
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5643
5644
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5645
0
  if( libcthreads_read_write_lock_grab_for_read(
5646
0
       internal_file_entry->read_write_lock,
5647
0
       error ) != 1 )
5648
0
  {
5649
0
    libcerror_error_set(
5650
0
     error,
5651
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5652
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5653
0
     "%s: unable to grab read/write lock for reading.",
5654
0
     function );
5655
5656
0
    return( -1 );
5657
0
  }
5658
0
#endif
5659
0
  result = libfsntfs_mft_entry_get_alternate_data_attribute_by_utf8_name(
5660
0
            internal_file_entry->mft_entry,
5661
0
            utf8_string,
5662
0
            utf8_string_length,
5663
0
            &data_attribute,
5664
0
            error );
5665
5666
0
  if( result == -1 )
5667
0
  {
5668
0
    libcerror_error_set(
5669
0
     error,
5670
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5671
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5672
0
     "%s: unable to retrieve alternate data attribute.",
5673
0
     function );
5674
5675
0
    result = -1;
5676
0
  }
5677
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5678
0
  if( libcthreads_read_write_lock_release_for_read(
5679
0
       internal_file_entry->read_write_lock,
5680
0
       error ) != 1 )
5681
0
  {
5682
0
    libcerror_error_set(
5683
0
     error,
5684
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5685
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5686
0
     "%s: unable to release read/write lock for reading.",
5687
0
     function );
5688
5689
0
    return( -1 );
5690
0
  }
5691
0
#endif
5692
0
  return( result );
5693
0
}
5694
5695
/* Determines if there is an alternate data stream for an UTF-8 encoded name
5696
 * Returns 1 if available, 0 if not or -1 on error
5697
 */
5698
int libfsntfs_file_entry_has_alternate_data_stream_by_utf16_name(
5699
     libfsntfs_file_entry_t *file_entry,
5700
     const uint16_t *utf16_string,
5701
     size_t utf16_string_length,
5702
     libcerror_error_t **error )
5703
0
{
5704
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5705
0
  libfsntfs_mft_attribute_t *data_attribute            = NULL;
5706
0
  static char *function                                = "libfsntfs_file_entry_has_alternate_data_stream_by_utf16_name";
5707
0
  int result                                           = 0;
5708
5709
0
  if( file_entry == NULL )
5710
0
  {
5711
0
    libcerror_error_set(
5712
0
     error,
5713
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5714
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5715
0
     "%s: invalid file entry.",
5716
0
     function );
5717
5718
0
    return( -1 );
5719
0
  }
5720
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5721
5722
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5723
0
  if( libcthreads_read_write_lock_grab_for_read(
5724
0
       internal_file_entry->read_write_lock,
5725
0
       error ) != 1 )
5726
0
  {
5727
0
    libcerror_error_set(
5728
0
     error,
5729
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5730
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5731
0
     "%s: unable to grab read/write lock for reading.",
5732
0
     function );
5733
5734
0
    return( -1 );
5735
0
  }
5736
0
#endif
5737
0
  result = libfsntfs_mft_entry_get_alternate_data_attribute_by_utf16_name(
5738
0
            internal_file_entry->mft_entry,
5739
0
            utf16_string,
5740
0
            utf16_string_length,
5741
0
            &data_attribute,
5742
0
            error );
5743
5744
0
  if( result == -1 )
5745
0
  {
5746
0
    libcerror_error_set(
5747
0
     error,
5748
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5749
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5750
0
     "%s: unable to retrieve alternate data attribute.",
5751
0
     function );
5752
5753
0
    result = -1;
5754
0
  }
5755
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5756
0
  if( libcthreads_read_write_lock_release_for_read(
5757
0
       internal_file_entry->read_write_lock,
5758
0
       error ) != 1 )
5759
0
  {
5760
0
    libcerror_error_set(
5761
0
     error,
5762
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5763
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5764
0
     "%s: unable to release read/write lock for reading.",
5765
0
     function );
5766
5767
0
    return( -1 );
5768
0
  }
5769
0
#endif
5770
0
  return( result );
5771
0
}
5772
5773
/* Retrieves the alternate data stream for an UTF-8 encoded name
5774
 * Returns 1 if successful, 0 if no such file entry or -1 on error
5775
 */
5776
int libfsntfs_file_entry_get_alternate_data_stream_by_utf8_name(
5777
     libfsntfs_file_entry_t *file_entry,
5778
     const uint8_t *utf8_string,
5779
     size_t utf8_string_length,
5780
     libfsntfs_data_stream_t **alternate_data_stream,
5781
     libcerror_error_t **error )
5782
0
{
5783
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5784
0
  libfsntfs_mft_attribute_t *data_attribute            = NULL;
5785
0
  static char *function                                = "libfsntfs_file_entry_get_alternate_data_stream_by_utf8_name";
5786
0
  int result                                           = 0;
5787
5788
0
  if( file_entry == NULL )
5789
0
  {
5790
0
    libcerror_error_set(
5791
0
     error,
5792
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5793
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5794
0
     "%s: invalid file entry.",
5795
0
     function );
5796
5797
0
    return( -1 );
5798
0
  }
5799
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5800
5801
0
  if( alternate_data_stream == NULL )
5802
0
  {
5803
0
    libcerror_error_set(
5804
0
     error,
5805
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5806
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5807
0
     "%s: invalid alternate data stream.",
5808
0
     function );
5809
5810
0
    return( -1 );
5811
0
  }
5812
0
  if( *alternate_data_stream != NULL )
5813
0
  {
5814
0
    libcerror_error_set(
5815
0
     error,
5816
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5817
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
5818
0
     "%s: invalid alternate data stream value already set.",
5819
0
     function );
5820
5821
0
    return( -1 );
5822
0
  }
5823
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5824
0
  if( libcthreads_read_write_lock_grab_for_read(
5825
0
       internal_file_entry->read_write_lock,
5826
0
       error ) != 1 )
5827
0
  {
5828
0
    libcerror_error_set(
5829
0
     error,
5830
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5831
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5832
0
     "%s: unable to grab read/write lock for reading.",
5833
0
     function );
5834
5835
0
    return( -1 );
5836
0
  }
5837
0
#endif
5838
0
  result = libfsntfs_mft_entry_get_alternate_data_attribute_by_utf8_name(
5839
0
            internal_file_entry->mft_entry,
5840
0
            utf8_string,
5841
0
            utf8_string_length,
5842
0
            &data_attribute,
5843
0
            error );
5844
5845
0
  if( result == -1 )
5846
0
  {
5847
0
    libcerror_error_set(
5848
0
     error,
5849
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5850
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5851
0
     "%s: unable to retrieve alternate data attribute.",
5852
0
     function );
5853
5854
0
    result = -1;
5855
0
  }
5856
0
  else if( result != 0 )
5857
0
  {
5858
0
    if( libfsntfs_data_stream_initialize(
5859
0
         alternate_data_stream,
5860
0
         internal_file_entry->io_handle,
5861
0
         internal_file_entry->file_io_handle,
5862
0
         data_attribute,
5863
0
         error ) != 1 )
5864
0
    {
5865
0
      libcerror_error_set(
5866
0
       error,
5867
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5868
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5869
0
       "%s: unable to create alternate data stream.",
5870
0
       function );
5871
5872
0
      result = -1;
5873
0
    }
5874
0
  }
5875
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5876
0
  if( libcthreads_read_write_lock_release_for_read(
5877
0
       internal_file_entry->read_write_lock,
5878
0
       error ) != 1 )
5879
0
  {
5880
0
    libcerror_error_set(
5881
0
     error,
5882
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5883
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5884
0
     "%s: unable to release read/write lock for reading.",
5885
0
     function );
5886
5887
0
    return( -1 );
5888
0
  }
5889
0
#endif
5890
0
  return( result );
5891
0
}
5892
5893
/* Retrieves the alternate data stream for an UTF-16 encoded name
5894
 * Returns 1 if successful, 0 if no such file entry or -1 on error
5895
 */
5896
int libfsntfs_file_entry_get_alternate_data_stream_by_utf16_name(
5897
     libfsntfs_file_entry_t *file_entry,
5898
     const uint16_t *utf16_string,
5899
     size_t utf16_string_length,
5900
     libfsntfs_data_stream_t **alternate_data_stream,
5901
     libcerror_error_t **error )
5902
0
{
5903
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5904
0
  libfsntfs_mft_attribute_t *data_attribute            = NULL;
5905
0
  static char *function                                = "libfsntfs_file_entry_get_alternate_data_stream_by_utf16_name";
5906
0
  int result                                           = 0;
5907
5908
0
  if( file_entry == NULL )
5909
0
  {
5910
0
    libcerror_error_set(
5911
0
     error,
5912
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5913
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5914
0
     "%s: invalid file entry.",
5915
0
     function );
5916
5917
0
    return( -1 );
5918
0
  }
5919
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5920
5921
0
  if( alternate_data_stream == NULL )
5922
0
  {
5923
0
    libcerror_error_set(
5924
0
     error,
5925
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5926
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5927
0
     "%s: invalid alternate data stream.",
5928
0
     function );
5929
5930
0
    return( -1 );
5931
0
  }
5932
0
  if( *alternate_data_stream != NULL )
5933
0
  {
5934
0
    libcerror_error_set(
5935
0
     error,
5936
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5937
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
5938
0
     "%s: invalid alternate data stream value already set.",
5939
0
     function );
5940
5941
0
    return( -1 );
5942
0
  }
5943
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5944
0
  if( libcthreads_read_write_lock_grab_for_read(
5945
0
       internal_file_entry->read_write_lock,
5946
0
       error ) != 1 )
5947
0
  {
5948
0
    libcerror_error_set(
5949
0
     error,
5950
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5951
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5952
0
     "%s: unable to grab read/write lock for reading.",
5953
0
     function );
5954
5955
0
    return( -1 );
5956
0
  }
5957
0
#endif
5958
0
  result = libfsntfs_mft_entry_get_alternate_data_attribute_by_utf16_name(
5959
0
            internal_file_entry->mft_entry,
5960
0
            utf16_string,
5961
0
            utf16_string_length,
5962
0
            &data_attribute,
5963
0
            error );
5964
5965
0
  if( result == -1 )
5966
0
  {
5967
0
    libcerror_error_set(
5968
0
     error,
5969
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5970
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5971
0
     "%s: unable to retrieve alternate data attribute.",
5972
0
     function );
5973
5974
0
    result = -1;
5975
0
  }
5976
0
  else if( result != 0 )
5977
0
  {
5978
0
    if( libfsntfs_data_stream_initialize(
5979
0
         alternate_data_stream,
5980
0
         internal_file_entry->io_handle,
5981
0
         internal_file_entry->file_io_handle,
5982
0
         data_attribute,
5983
0
         error ) != 1 )
5984
0
    {
5985
0
      libcerror_error_set(
5986
0
       error,
5987
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5988
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5989
0
       "%s: unable to create alternate data stream.",
5990
0
       function );
5991
5992
0
      result = -1;
5993
0
    }
5994
0
  }
5995
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5996
0
  if( libcthreads_read_write_lock_release_for_read(
5997
0
       internal_file_entry->read_write_lock,
5998
0
       error ) != 1 )
5999
0
  {
6000
0
    libcerror_error_set(
6001
0
     error,
6002
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6003
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6004
0
     "%s: unable to release read/write lock for reading.",
6005
0
     function );
6006
6007
0
    return( -1 );
6008
0
  }
6009
0
#endif
6010
0
  return( result );
6011
0
}
6012
6013
/* Retrieves the number of sub file entries
6014
 * Returns 1 if successful or -1 on error
6015
 */
6016
int libfsntfs_file_entry_get_number_of_sub_file_entries(
6017
     libfsntfs_file_entry_t *file_entry,
6018
     int *number_of_sub_file_entries,
6019
     libcerror_error_t **error )
6020
273
{
6021
273
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
6022
273
  static char *function                                = "libfsntfs_file_entry_get_number_of_sub_file_entries";
6023
273
  int result                                           = 1;
6024
273
  int safe_number_of_sub_file_entries                  = 0;
6025
6026
273
  if( file_entry == NULL )
6027
0
  {
6028
0
    libcerror_error_set(
6029
0
     error,
6030
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6031
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6032
0
     "%s: invalid file entry.",
6033
0
     function );
6034
6035
0
    return( -1 );
6036
0
  }
6037
273
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
6038
6039
273
  if( number_of_sub_file_entries == NULL )
6040
0
  {
6041
0
    libcerror_error_set(
6042
0
     error,
6043
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6044
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6045
0
     "%s: invalid number of sub file entries.",
6046
0
     function );
6047
6048
0
    return( -1 );
6049
0
  }
6050
273
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6051
273
  if( libcthreads_read_write_lock_grab_for_read(
6052
273
       internal_file_entry->read_write_lock,
6053
273
       error ) != 1 )
6054
0
  {
6055
0
    libcerror_error_set(
6056
0
     error,
6057
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6058
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6059
0
     "%s: unable to grab read/write lock for reading.",
6060
0
     function );
6061
6062
0
    return( -1 );
6063
0
  }
6064
273
#endif
6065
273
  if( internal_file_entry->directory_entries_tree != NULL )
6066
159
  {
6067
159
    if( libfsntfs_directory_entries_tree_get_number_of_entries(
6068
159
         internal_file_entry->directory_entries_tree,
6069
159
         &safe_number_of_sub_file_entries,
6070
159
         error ) != 1 )
6071
0
    {
6072
0
      libcerror_error_set(
6073
0
       error,
6074
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6075
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6076
0
       "%s: unable to retrieve number of entries from directory entries tree.",
6077
0
       function );
6078
6079
0
      result = -1;
6080
0
    }
6081
159
  }
6082
273
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6083
273
  if( libcthreads_read_write_lock_release_for_read(
6084
273
       internal_file_entry->read_write_lock,
6085
273
       error ) != 1 )
6086
0
  {
6087
0
    libcerror_error_set(
6088
0
     error,
6089
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6090
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6091
0
     "%s: unable to release read/write lock for reading.",
6092
0
     function );
6093
6094
0
    return( -1 );
6095
0
  }
6096
273
#endif
6097
273
  if( result == 1 )
6098
273
  {
6099
273
    *number_of_sub_file_entries = safe_number_of_sub_file_entries;
6100
273
  }
6101
273
  return( result );
6102
273
}
6103
6104
/* Retrieves the sub file entry for the specific index
6105
 * Returns 1 if successful or -1 on error
6106
 */
6107
int libfsntfs_file_entry_get_sub_file_entry_by_index(
6108
     libfsntfs_file_entry_t *file_entry,
6109
     int sub_file_entry_index,
6110
     libfsntfs_file_entry_t **sub_file_entry,
6111
     libcerror_error_t **error )
6112
42
{
6113
42
  libfsntfs_directory_entry_t *sub_directory_entry     = NULL;
6114
42
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
6115
42
  static char *function                                = "libfsntfs_file_entry_get_sub_file_entry_by_index";
6116
42
  uint64_t mft_entry_index                             = 0;
6117
42
  int result                                           = 1;
6118
6119
42
  if( file_entry == NULL )
6120
0
  {
6121
0
    libcerror_error_set(
6122
0
     error,
6123
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6124
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6125
0
     "%s: invalid file entry.",
6126
0
     function );
6127
6128
0
    return( -1 );
6129
0
  }
6130
42
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
6131
6132
42
  if( sub_file_entry == NULL )
6133
0
  {
6134
0
    libcerror_error_set(
6135
0
     error,
6136
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6137
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6138
0
     "%s: invalid sub file entry.",
6139
0
     function );
6140
6141
0
    return( -1 );
6142
0
  }
6143
42
  if( *sub_file_entry != NULL )
6144
0
  {
6145
0
    libcerror_error_set(
6146
0
     error,
6147
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6148
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
6149
0
     "%s: invalid sub file entry value already set.",
6150
0
     function );
6151
6152
0
    return( -1 );
6153
0
  }
6154
42
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6155
42
  if( libcthreads_read_write_lock_grab_for_read(
6156
42
       internal_file_entry->read_write_lock,
6157
42
       error ) != 1 )
6158
0
  {
6159
0
    libcerror_error_set(
6160
0
     error,
6161
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6162
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6163
0
     "%s: unable to grab read/write lock for reading.",
6164
0
     function );
6165
6166
0
    return( -1 );
6167
0
  }
6168
42
#endif
6169
42
  if( libfsntfs_directory_entries_tree_get_entry_by_index(
6170
42
       internal_file_entry->directory_entries_tree,
6171
42
       internal_file_entry->file_io_handle,
6172
42
       sub_file_entry_index,
6173
42
       &sub_directory_entry,
6174
42
       error ) != 1 )
6175
0
  {
6176
0
    libcerror_error_set(
6177
0
     error,
6178
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6179
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6180
0
     "%s: unable to retrieve entry: %d from directory entries tree.",
6181
0
     function,
6182
0
     sub_file_entry_index );
6183
6184
0
    result = -1;
6185
0
  }
6186
42
  else
6187
42
  {
6188
42
    if( libfsntfs_directory_entry_get_mft_entry_index(
6189
42
         sub_directory_entry,
6190
42
         &mft_entry_index,
6191
42
         error ) != 1 )
6192
4
    {
6193
4
      libcerror_error_set(
6194
4
       error,
6195
4
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6196
4
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6197
4
       "%s: unable to retrieve MFT entry index.",
6198
4
       function );
6199
6200
4
      result = -1;
6201
4
    }
6202
    /* sub_file_entry takes over management of sub_directory_entry
6203
     */
6204
38
    else if( libfsntfs_file_entry_initialize(
6205
38
        sub_file_entry,
6206
38
        internal_file_entry->io_handle,
6207
38
        internal_file_entry->file_io_handle,
6208
38
        internal_file_entry->file_system,
6209
38
        mft_entry_index,
6210
38
        sub_directory_entry,
6211
38
        internal_file_entry->flags,
6212
38
        error ) != 1 )
6213
15
    {
6214
15
      libcerror_error_set(
6215
15
       error,
6216
15
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6217
15
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6218
15
       "%s: unable to create sub file entry: %d with MFT entry: %" PRIu64 ".",
6219
15
       function,
6220
15
       sub_file_entry_index,
6221
15
       mft_entry_index );
6222
6223
15
      result = -1;
6224
15
    }
6225
42
  }
6226
42
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6227
42
  if( libcthreads_read_write_lock_release_for_read(
6228
42
       internal_file_entry->read_write_lock,
6229
42
       error ) != 1 )
6230
0
  {
6231
0
    libcerror_error_set(
6232
0
     error,
6233
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6234
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6235
0
     "%s: unable to release read/write lock for reading.",
6236
0
     function );
6237
6238
0
    result = -1;
6239
0
  }
6240
42
#endif
6241
42
  if( result == -1 )
6242
19
  {
6243
19
    if( sub_directory_entry != NULL )
6244
19
    {
6245
19
      libfsntfs_directory_entry_free(
6246
19
       &sub_directory_entry,
6247
19
       NULL );
6248
19
    }
6249
19
  }
6250
42
  return( result );
6251
42
}
6252
6253
/* Retrieves the sub file entry for an UTF-8 encoded name
6254
 * Returns 1 if successful, 0 if no such file entry or -1 on error
6255
 */
6256
int libfsntfs_file_entry_get_sub_file_entry_by_utf8_name(
6257
     libfsntfs_file_entry_t *file_entry,
6258
     const uint8_t *utf8_string,
6259
     size_t utf8_string_length,
6260
     libfsntfs_file_entry_t **sub_file_entry,
6261
     libcerror_error_t **error )
6262
0
{
6263
0
  libfsntfs_directory_entry_t *sub_directory_entry     = NULL;
6264
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
6265
0
  static char *function                                = "libfsntfs_file_entry_get_sub_file_entry_by_utf8_name";
6266
0
  uint64_t mft_entry_index                             = 0;
6267
0
  int result                                           = 0;
6268
6269
0
  if( file_entry == NULL )
6270
0
  {
6271
0
    libcerror_error_set(
6272
0
     error,
6273
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6274
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6275
0
     "%s: invalid file entry.",
6276
0
     function );
6277
6278
0
    return( -1 );
6279
0
  }
6280
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
6281
6282
0
  if( sub_file_entry == NULL )
6283
0
  {
6284
0
    libcerror_error_set(
6285
0
     error,
6286
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6287
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6288
0
     "%s: invalid sub file entry.",
6289
0
     function );
6290
6291
0
    return( -1 );
6292
0
  }
6293
0
  if( *sub_file_entry != NULL )
6294
0
  {
6295
0
    libcerror_error_set(
6296
0
     error,
6297
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6298
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
6299
0
     "%s: invalid sub file entry value already set.",
6300
0
     function );
6301
6302
0
    return( -1 );
6303
0
  }
6304
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6305
0
  if( libcthreads_read_write_lock_grab_for_read(
6306
0
       internal_file_entry->read_write_lock,
6307
0
       error ) != 1 )
6308
0
  {
6309
0
    libcerror_error_set(
6310
0
     error,
6311
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6312
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6313
0
     "%s: unable to grab read/write lock for reading.",
6314
0
     function );
6315
6316
0
    return( -1 );
6317
0
  }
6318
0
#endif
6319
0
  result = libfsntfs_directory_entries_tree_get_entry_by_utf8_name(
6320
0
            internal_file_entry->directory_entries_tree,
6321
0
            internal_file_entry->file_io_handle,
6322
0
            utf8_string,
6323
0
            utf8_string_length,
6324
0
            &sub_directory_entry,
6325
0
            error );
6326
6327
0
  if( result == -1 )
6328
0
  {
6329
0
    libcerror_error_set(
6330
0
     error,
6331
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6332
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6333
0
     "%s: unable to retrieve directory entry.",
6334
0
     function );
6335
6336
0
    result = -1;
6337
0
  }
6338
0
  else if( result != 0 )
6339
0
  {
6340
0
    if( libfsntfs_directory_entry_get_mft_entry_index(
6341
0
         sub_directory_entry,
6342
0
         &mft_entry_index,
6343
0
         error ) != 1 )
6344
0
    {
6345
0
      libcerror_error_set(
6346
0
       error,
6347
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6348
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6349
0
       "%s: unable to retrieve MFT entry index.",
6350
0
       function );
6351
6352
0
      result = -1;
6353
0
    }
6354
    /* sub_file_entry takes over management of sub_directory_entry
6355
     */
6356
0
    else if( libfsntfs_file_entry_initialize(
6357
0
              sub_file_entry,
6358
0
              internal_file_entry->io_handle,
6359
0
              internal_file_entry->file_io_handle,
6360
0
              internal_file_entry->file_system,
6361
0
              mft_entry_index,
6362
0
              sub_directory_entry,
6363
0
              internal_file_entry->flags,
6364
0
              error ) != 1 )
6365
0
    {
6366
0
      libcerror_error_set(
6367
0
       error,
6368
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6369
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6370
0
       "%s: unable to create sub file entry with MFT entry: %" PRIu64 ".",
6371
0
       function,
6372
0
       mft_entry_index );
6373
6374
0
      result = -1;
6375
0
    }
6376
0
  }
6377
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6378
0
  if( libcthreads_read_write_lock_release_for_read(
6379
0
       internal_file_entry->read_write_lock,
6380
0
       error ) != 1 )
6381
0
  {
6382
0
    libcerror_error_set(
6383
0
     error,
6384
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6385
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6386
0
     "%s: unable to release read/write lock for reading.",
6387
0
     function );
6388
6389
0
    result = -1;
6390
0
  }
6391
0
#endif
6392
0
  if( result == -1 )
6393
0
  {
6394
0
    if( sub_directory_entry != NULL )
6395
0
    {
6396
0
      libfsntfs_directory_entry_free(
6397
0
       &sub_directory_entry,
6398
0
       NULL );
6399
0
    }
6400
0
  }
6401
0
  return( result );
6402
0
}
6403
6404
/* Retrieves the sub file entry for an UTF-16 encoded name
6405
 * Returns 1 if successful, 0 if no such file entry or -1 on error
6406
 */
6407
int libfsntfs_file_entry_get_sub_file_entry_by_utf16_name(
6408
     libfsntfs_file_entry_t *file_entry,
6409
     const uint16_t *utf16_string,
6410
     size_t utf16_string_length,
6411
     libfsntfs_file_entry_t **sub_file_entry,
6412
     libcerror_error_t **error )
6413
0
{
6414
0
  libfsntfs_directory_entry_t *sub_directory_entry     = NULL;
6415
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
6416
0
  static char *function                                = "libfsntfs_file_entry_get_sub_file_entry_by_utf16_name";
6417
0
  uint64_t mft_entry_index                             = 0;
6418
0
  int result                                           = 0;
6419
6420
0
  if( file_entry == NULL )
6421
0
  {
6422
0
    libcerror_error_set(
6423
0
     error,
6424
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6425
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6426
0
     "%s: invalid file entry.",
6427
0
     function );
6428
6429
0
    return( -1 );
6430
0
  }
6431
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
6432
6433
0
  if( sub_file_entry == NULL )
6434
0
  {
6435
0
    libcerror_error_set(
6436
0
     error,
6437
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6438
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6439
0
     "%s: invalid sub file entry.",
6440
0
     function );
6441
6442
0
    return( -1 );
6443
0
  }
6444
0
  if( *sub_file_entry != NULL )
6445
0
  {
6446
0
    libcerror_error_set(
6447
0
     error,
6448
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6449
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
6450
0
     "%s: invalid sub file entry value already set.",
6451
0
     function );
6452
6453
0
    return( -1 );
6454
0
  }
6455
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6456
0
  if( libcthreads_read_write_lock_grab_for_read(
6457
0
       internal_file_entry->read_write_lock,
6458
0
       error ) != 1 )
6459
0
  {
6460
0
    libcerror_error_set(
6461
0
     error,
6462
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6463
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6464
0
     "%s: unable to grab read/write lock for reading.",
6465
0
     function );
6466
6467
0
    return( -1 );
6468
0
  }
6469
0
#endif
6470
0
  result = libfsntfs_directory_entries_tree_get_entry_by_utf16_name(
6471
0
            internal_file_entry->directory_entries_tree,
6472
0
            internal_file_entry->file_io_handle,
6473
0
            utf16_string,
6474
0
            utf16_string_length,
6475
0
            &sub_directory_entry,
6476
0
            error );
6477
6478
0
  if( result == -1 )
6479
0
  {
6480
0
    libcerror_error_set(
6481
0
     error,
6482
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6483
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6484
0
     "%s: unable to retrieve directory entry.",
6485
0
     function );
6486
6487
0
    result = -1;
6488
0
  }
6489
0
  else if( result != 0 )
6490
0
  {
6491
0
    if( libfsntfs_directory_entry_get_mft_entry_index(
6492
0
         sub_directory_entry,
6493
0
         &mft_entry_index,
6494
0
         error ) != 1 )
6495
0
    {
6496
0
      libcerror_error_set(
6497
0
       error,
6498
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6499
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6500
0
       "%s: unable to retrieve MFT entry index.",
6501
0
       function );
6502
6503
0
      result = -1;
6504
0
    }
6505
    /* sub_file_entry takes over management of sub_directory_entry
6506
     */
6507
0
    else if( libfsntfs_file_entry_initialize(
6508
0
              sub_file_entry,
6509
0
              internal_file_entry->io_handle,
6510
0
              internal_file_entry->file_io_handle,
6511
0
              internal_file_entry->file_system,
6512
0
              mft_entry_index,
6513
0
              sub_directory_entry,
6514
0
              internal_file_entry->flags,
6515
0
              error ) != 1 )
6516
0
    {
6517
0
      libcerror_error_set(
6518
0
       error,
6519
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6520
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
6521
0
       "%s: unable to create sub file entry with MFT entry: %" PRIu64 ".",
6522
0
       function,
6523
0
       mft_entry_index );
6524
6525
0
      result = -1;
6526
0
    }
6527
0
  }
6528
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6529
0
  if( libcthreads_read_write_lock_release_for_read(
6530
0
       internal_file_entry->read_write_lock,
6531
0
       error ) != 1 )
6532
0
  {
6533
0
    libcerror_error_set(
6534
0
     error,
6535
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6536
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6537
0
     "%s: unable to release read/write lock for reading.",
6538
0
     function );
6539
6540
0
    result = -1;
6541
0
  }
6542
0
#endif
6543
0
  if( result == -1 )
6544
0
  {
6545
0
    if( sub_directory_entry != NULL )
6546
0
    {
6547
0
      libfsntfs_directory_entry_free(
6548
0
       &sub_directory_entry,
6549
0
       NULL );
6550
0
    }
6551
0
  }
6552
0
  return( result );
6553
0
}
6554
6555
/* Reads data at the current offset from the default data stream (nameless $DATA attribute)
6556
 * Returns the number of bytes read or -1 on error
6557
 */
6558
ssize_t libfsntfs_file_entry_read_buffer(
6559
         libfsntfs_file_entry_t *file_entry,
6560
         void *buffer,
6561
         size_t buffer_size,
6562
         libcerror_error_t **error )
6563
0
{
6564
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
6565
0
  static char *function                                = "libfsntfs_file_entry_read_buffer";
6566
0
  ssize_t read_count                                   = 0;
6567
6568
0
  if( file_entry == NULL )
6569
0
  {
6570
0
    libcerror_error_set(
6571
0
     error,
6572
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6573
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6574
0
     "%s: invalid file entry.",
6575
0
     function );
6576
6577
0
    return( -1 );
6578
0
  }
6579
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
6580
6581
0
  if( internal_file_entry->data_attribute == NULL )
6582
0
  {
6583
0
    libcerror_error_set(
6584
0
     error,
6585
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6586
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6587
0
     "%s: invalid file entry - missing data attribute.",
6588
0
     function );
6589
6590
0
    return( -1 );
6591
0
  }
6592
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6593
0
  if( libcthreads_read_write_lock_grab_for_write(
6594
0
       internal_file_entry->read_write_lock,
6595
0
       error ) != 1 )
6596
0
  {
6597
0
    libcerror_error_set(
6598
0
     error,
6599
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6600
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6601
0
     "%s: unable to grab read/write lock for writing.",
6602
0
     function );
6603
6604
0
    return( -1 );
6605
0
  }
6606
0
#endif
6607
0
  read_count = libfdata_stream_read_buffer(
6608
0
                internal_file_entry->data_cluster_block_stream,
6609
0
                (intptr_t *) internal_file_entry->file_io_handle,
6610
0
                buffer,
6611
0
                buffer_size,
6612
0
                0,
6613
0
                error );
6614
6615
0
  if( read_count < 0 )
6616
0
  {
6617
0
    libcerror_error_set(
6618
0
     error,
6619
0
     LIBCERROR_ERROR_DOMAIN_IO,
6620
0
     LIBCERROR_IO_ERROR_READ_FAILED,
6621
0
     "%s: unable to read from data cluster block stream.",
6622
0
     function );
6623
6624
0
    read_count = -1;
6625
0
  }
6626
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6627
0
  if( libcthreads_read_write_lock_release_for_write(
6628
0
       internal_file_entry->read_write_lock,
6629
0
       error ) != 1 )
6630
0
  {
6631
0
    libcerror_error_set(
6632
0
     error,
6633
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6634
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6635
0
     "%s: unable to release read/write lock for writing.",
6636
0
     function );
6637
6638
0
    return( -1 );
6639
0
  }
6640
0
#endif
6641
0
  return( read_count );
6642
0
}
6643
6644
/* Reads data at a specific offset from the default data stream (nameless $DATA attribute)
6645
 * Returns the number of bytes read or -1 on error
6646
 */
6647
ssize_t libfsntfs_file_entry_read_buffer_at_offset(
6648
         libfsntfs_file_entry_t *file_entry,
6649
         void *buffer,
6650
         size_t buffer_size,
6651
         off64_t offset,
6652
         libcerror_error_t **error )
6653
0
{
6654
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
6655
0
  static char *function                                = "libfsntfs_file_entry_read_buffer_at_offset";
6656
0
  ssize_t read_count                                   = 0;
6657
6658
0
  if( file_entry == NULL )
6659
0
  {
6660
0
    libcerror_error_set(
6661
0
     error,
6662
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6663
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6664
0
     "%s: invalid file entry.",
6665
0
     function );
6666
6667
0
    return( -1 );
6668
0
  }
6669
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
6670
6671
0
  if( internal_file_entry->data_attribute == NULL )
6672
0
  {
6673
0
    libcerror_error_set(
6674
0
     error,
6675
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6676
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6677
0
     "%s: invalid file entry - missing data attribute.",
6678
0
     function );
6679
6680
0
    return( -1 );
6681
0
  }
6682
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6683
0
  if( libcthreads_read_write_lock_grab_for_write(
6684
0
       internal_file_entry->read_write_lock,
6685
0
       error ) != 1 )
6686
0
  {
6687
0
    libcerror_error_set(
6688
0
     error,
6689
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6690
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6691
0
     "%s: unable to grab read/write lock for writing.",
6692
0
     function );
6693
6694
0
    return( -1 );
6695
0
  }
6696
0
#endif
6697
0
  read_count = libfdata_stream_read_buffer_at_offset(
6698
0
                internal_file_entry->data_cluster_block_stream,
6699
0
                (intptr_t *) internal_file_entry->file_io_handle,
6700
0
                buffer,
6701
0
                buffer_size,
6702
0
                offset,
6703
0
                0,
6704
0
                error );
6705
6706
0
  if( read_count < 0 )
6707
0
  {
6708
0
    libcerror_error_set(
6709
0
     error,
6710
0
     LIBCERROR_ERROR_DOMAIN_IO,
6711
0
     LIBCERROR_IO_ERROR_READ_FAILED,
6712
0
     "%s: unable to read from data cluster block stream.",
6713
0
     function );
6714
6715
0
    read_count = -1;
6716
0
  }
6717
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6718
0
  if( libcthreads_read_write_lock_release_for_write(
6719
0
       internal_file_entry->read_write_lock,
6720
0
       error ) != 1 )
6721
0
  {
6722
0
    libcerror_error_set(
6723
0
     error,
6724
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6725
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6726
0
     "%s: unable to release read/write lock for writing.",
6727
0
     function );
6728
6729
0
    return( -1 );
6730
0
  }
6731
0
#endif
6732
0
  return( read_count );
6733
0
}
6734
6735
/* Seeks a certain offset in the default data stream (nameless $DATA attribute)
6736
 * Returns the offset if seek is successful or -1 on error
6737
 */
6738
off64_t libfsntfs_file_entry_seek_offset(
6739
         libfsntfs_file_entry_t *file_entry,
6740
         off64_t offset,
6741
         int whence,
6742
         libcerror_error_t **error )
6743
0
{
6744
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
6745
0
  static char *function                                = "libfsntfs_file_entry_seek_offset";
6746
6747
0
  if( file_entry == NULL )
6748
0
  {
6749
0
    libcerror_error_set(
6750
0
     error,
6751
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6752
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6753
0
     "%s: invalid file entry.",
6754
0
     function );
6755
6756
0
    return( -1 );
6757
0
  }
6758
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
6759
6760
0
  if( internal_file_entry->data_attribute == NULL )
6761
0
  {
6762
0
    libcerror_error_set(
6763
0
     error,
6764
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6765
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6766
0
     "%s: invalid file entry - missing data attribute.",
6767
0
     function );
6768
6769
0
    return( -1 );
6770
0
  }
6771
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6772
0
  if( libcthreads_read_write_lock_grab_for_write(
6773
0
       internal_file_entry->read_write_lock,
6774
0
       error ) != 1 )
6775
0
  {
6776
0
    libcerror_error_set(
6777
0
     error,
6778
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6779
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6780
0
     "%s: unable to grab read/write lock for writing.",
6781
0
     function );
6782
6783
0
    return( -1 );
6784
0
  }
6785
0
#endif
6786
0
  offset = libfdata_stream_seek_offset(
6787
0
            internal_file_entry->data_cluster_block_stream,
6788
0
            offset,
6789
0
            whence,
6790
0
            error );
6791
6792
0
  if( offset == -1 )
6793
0
  {
6794
0
    libcerror_error_set(
6795
0
     error,
6796
0
     LIBCERROR_ERROR_DOMAIN_IO,
6797
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
6798
0
     "%s: unable to seek offset in data cluster block stream.",
6799
0
     function );
6800
6801
0
    offset = -1;
6802
0
  }
6803
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6804
0
  if( libcthreads_read_write_lock_release_for_write(
6805
0
       internal_file_entry->read_write_lock,
6806
0
       error ) != 1 )
6807
0
  {
6808
0
    libcerror_error_set(
6809
0
     error,
6810
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6811
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6812
0
     "%s: unable to release read/write lock for writing.",
6813
0
     function );
6814
6815
0
    return( -1 );
6816
0
  }
6817
0
#endif
6818
0
  return( offset );
6819
0
}
6820
6821
/* Retrieves the current offset of the default data stream (nameless $DATA attribute)
6822
 * Returns the offset if successful or -1 on error
6823
 */
6824
int libfsntfs_file_entry_get_offset(
6825
     libfsntfs_file_entry_t *file_entry,
6826
     off64_t *offset,
6827
     libcerror_error_t **error )
6828
0
{
6829
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
6830
0
  static char *function                                = "libfsntfs_file_entry_get_offset";
6831
0
  int result                                           = 1;
6832
6833
0
  if( file_entry == NULL )
6834
0
  {
6835
0
    libcerror_error_set(
6836
0
     error,
6837
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6838
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6839
0
     "%s: invalid file entry.",
6840
0
     function );
6841
6842
0
    return( -1 );
6843
0
  }
6844
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
6845
6846
0
  if( internal_file_entry->data_attribute == NULL )
6847
0
  {
6848
0
    libcerror_error_set(
6849
0
     error,
6850
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6851
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6852
0
     "%s: invalid file entry - missing data attribute.",
6853
0
     function );
6854
6855
0
    return( -1 );
6856
0
  }
6857
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6858
0
  if( libcthreads_read_write_lock_grab_for_read(
6859
0
       internal_file_entry->read_write_lock,
6860
0
       error ) != 1 )
6861
0
  {
6862
0
    libcerror_error_set(
6863
0
     error,
6864
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6865
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6866
0
     "%s: unable to grab read/write lock for reading.",
6867
0
     function );
6868
6869
0
    return( -1 );
6870
0
  }
6871
0
#endif
6872
0
  if( libfdata_stream_get_offset(
6873
0
       internal_file_entry->data_cluster_block_stream,
6874
0
       offset,
6875
0
       error ) != 1 )
6876
0
  {
6877
0
    libcerror_error_set(
6878
0
     error,
6879
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6880
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6881
0
     "%s: unable to retrieve offset from data cluster block stream.",
6882
0
     function );
6883
6884
0
    result = -1;
6885
0
  }
6886
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6887
0
  if( libcthreads_read_write_lock_release_for_read(
6888
0
       internal_file_entry->read_write_lock,
6889
0
       error ) != 1 )
6890
0
  {
6891
0
    libcerror_error_set(
6892
0
     error,
6893
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6894
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6895
0
     "%s: unable to release read/write lock for reading.",
6896
0
     function );
6897
6898
0
    return( -1 );
6899
0
  }
6900
0
#endif
6901
0
  return( result );
6902
0
}
6903
6904
/* Retrieves the size of the default data stream (nameless $DATA attribute)
6905
 * Returns 1 if successful or -1 on error
6906
 */
6907
int libfsntfs_file_entry_get_size(
6908
     libfsntfs_file_entry_t *file_entry,
6909
     size64_t *size,
6910
     libcerror_error_t **error )
6911
0
{
6912
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
6913
0
  static char *function                                = "libfsntfs_file_entry_get_size";
6914
0
  size64_t safe_size                                   = 0;
6915
0
  int result                                           = 1;
6916
6917
0
  if( file_entry == NULL )
6918
0
  {
6919
0
    libcerror_error_set(
6920
0
     error,
6921
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6922
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6923
0
     "%s: invalid file entry.",
6924
0
     function );
6925
6926
0
    return( -1 );
6927
0
  }
6928
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
6929
6930
0
  if( size == NULL )
6931
0
  {
6932
0
    libcerror_error_set(
6933
0
     error,
6934
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6935
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6936
0
     "%s: invalid size.",
6937
0
     function );
6938
6939
0
    return( -1 );
6940
0
  }
6941
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6942
0
  if( libcthreads_read_write_lock_grab_for_read(
6943
0
       internal_file_entry->read_write_lock,
6944
0
       error ) != 1 )
6945
0
  {
6946
0
    libcerror_error_set(
6947
0
     error,
6948
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6949
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6950
0
     "%s: unable to grab read/write lock for reading.",
6951
0
     function );
6952
6953
0
    return( -1 );
6954
0
  }
6955
0
#endif
6956
0
  if( internal_file_entry->data_cluster_block_stream != NULL )
6957
0
  {
6958
0
    if( libfdata_stream_get_size(
6959
0
         internal_file_entry->data_cluster_block_stream,
6960
0
         &safe_size,
6961
0
         error ) != 1 )
6962
0
    {
6963
0
      libcerror_error_set(
6964
0
       error,
6965
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6966
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6967
0
       "%s: unable to retrieve data attribute data size.",
6968
0
       function );
6969
6970
0
      result = -1;
6971
0
    }
6972
0
  }
6973
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6974
0
  if( libcthreads_read_write_lock_release_for_read(
6975
0
       internal_file_entry->read_write_lock,
6976
0
       error ) != 1 )
6977
0
  {
6978
0
    libcerror_error_set(
6979
0
     error,
6980
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6981
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6982
0
     "%s: unable to release read/write lock for reading.",
6983
0
     function );
6984
6985
0
    return( -1 );
6986
0
  }
6987
0
#endif
6988
0
  if( result == 1 )
6989
0
  {
6990
0
    *size = safe_size;
6991
0
  }
6992
0
  return( result );
6993
0
}
6994
6995
/* Retrieves the number of extents (decoded data runs) of the default data stream (nameless $DATA attribute)
6996
 * Returns 1 if successful or -1 on error
6997
 */
6998
int libfsntfs_file_entry_get_number_of_extents(
6999
     libfsntfs_file_entry_t *file_entry,
7000
     int *number_of_extents,
7001
     libcerror_error_t **error )
7002
0
{
7003
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
7004
0
  static char *function                                = "libfsntfs_file_entry_get_number_of_extents";
7005
0
  int result                                           = 1;
7006
0
  int safe_number_of_extents                           = 0;
7007
7008
0
  if( file_entry == NULL )
7009
0
  {
7010
0
    libcerror_error_set(
7011
0
     error,
7012
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7013
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7014
0
     "%s: invalid file entry.",
7015
0
     function );
7016
7017
0
    return( -1 );
7018
0
  }
7019
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
7020
7021
0
  if( number_of_extents == NULL )
7022
0
  {
7023
0
    libcerror_error_set(
7024
0
     error,
7025
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7026
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7027
0
     "%s: invalid number of extents.",
7028
0
     function );
7029
7030
0
    return( -1 );
7031
0
  }
7032
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
7033
0
  if( libcthreads_read_write_lock_grab_for_read(
7034
0
       internal_file_entry->read_write_lock,
7035
0
       error ) != 1 )
7036
0
  {
7037
0
    libcerror_error_set(
7038
0
     error,
7039
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7040
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7041
0
     "%s: unable to grab read/write lock for reading.",
7042
0
     function );
7043
7044
0
    return( -1 );
7045
0
  }
7046
0
#endif
7047
0
  if( internal_file_entry->extents_array != NULL )
7048
0
  {
7049
0
    if( libcdata_array_get_number_of_entries(
7050
0
         internal_file_entry->extents_array,
7051
0
         &safe_number_of_extents,
7052
0
         error ) != 1 )
7053
0
    {
7054
0
      libcerror_error_set(
7055
0
       error,
7056
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7057
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7058
0
       "%s: unable to retrieve number of extents.",
7059
0
       function );
7060
7061
0
      result = -1;
7062
0
    }
7063
0
  }
7064
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
7065
0
  if( libcthreads_read_write_lock_release_for_read(
7066
0
       internal_file_entry->read_write_lock,
7067
0
       error ) != 1 )
7068
0
  {
7069
0
    libcerror_error_set(
7070
0
     error,
7071
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7072
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7073
0
     "%s: unable to release read/write lock for reading.",
7074
0
     function );
7075
7076
0
    return( -1 );
7077
0
  }
7078
0
#endif
7079
0
  if( result == 1 )
7080
0
  {
7081
0
    *number_of_extents = safe_number_of_extents;
7082
0
  }
7083
0
  return( result );
7084
0
}
7085
7086
/* Retrieves a specific extent (decoded data run) of the default data stream (nameless $DATA attribute)
7087
 * Returns 1 if successful or -1 on error
7088
 */
7089
int libfsntfs_file_entry_get_extent_by_index(
7090
     libfsntfs_file_entry_t *file_entry,
7091
     int extent_index,
7092
     off64_t *extent_offset,
7093
     size64_t *extent_size,
7094
     uint32_t *extent_flags,
7095
     libcerror_error_t **error )
7096
0
{
7097
0
  libfsntfs_extent_t *data_extent                      = NULL;
7098
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
7099
0
  static char *function                                = "libfsntfs_file_entry_get_extent_by_index";
7100
0
  int result                                           = 1;
7101
7102
0
  if( file_entry == NULL )
7103
0
  {
7104
0
    libcerror_error_set(
7105
0
     error,
7106
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
7107
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
7108
0
     "%s: invalid file entry.",
7109
0
     function );
7110
7111
0
    return( -1 );
7112
0
  }
7113
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
7114
7115
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
7116
0
  if( libcthreads_read_write_lock_grab_for_read(
7117
0
       internal_file_entry->read_write_lock,
7118
0
       error ) != 1 )
7119
0
  {
7120
0
    libcerror_error_set(
7121
0
     error,
7122
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7123
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7124
0
     "%s: unable to grab read/write lock for reading.",
7125
0
     function );
7126
7127
0
    return( -1 );
7128
0
  }
7129
0
#endif
7130
0
  if( libcdata_array_get_entry_by_index(
7131
0
       internal_file_entry->extents_array,
7132
0
       extent_index,
7133
0
       (intptr_t **) &data_extent,
7134
0
       error ) != 1 )
7135
0
  {
7136
0
    libcerror_error_set(
7137
0
     error,
7138
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7139
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7140
0
     "%s: unable to retrieve extent: %d.",
7141
0
     function,
7142
0
     extent_index );
7143
7144
0
    result = -1;
7145
0
  }
7146
0
  if( result == 1 )
7147
0
  {
7148
0
    if( libfsntfs_extent_get_values(
7149
0
         data_extent,
7150
0
         extent_offset,
7151
0
         extent_size,
7152
0
         extent_flags,
7153
0
         error ) != 1 )
7154
0
    {
7155
0
      libcerror_error_set(
7156
0
       error,
7157
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
7158
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
7159
0
       "%s: unable to retrieve extent: %d values.",
7160
0
       function,
7161
0
       extent_index );
7162
7163
0
      result = -1;
7164
0
    }
7165
0
  }
7166
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
7167
0
  if( libcthreads_read_write_lock_release_for_read(
7168
0
       internal_file_entry->read_write_lock,
7169
0
       error ) != 1 )
7170
0
  {
7171
0
    libcerror_error_set(
7172
0
     error,
7173
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
7174
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
7175
0
     "%s: unable to release read/write lock for reading.",
7176
0
     function );
7177
7178
0
    return( -1 );
7179
0
  }
7180
0
#endif
7181
0
  return( result );
7182
0
}
7183