Coverage Report

Created: 2023-11-27 06:51

/src/libfsntfs/libfsntfs/libfsntfs_file_entry.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * File entry functions
3
 *
4
 * Copyright (C) 2010-2023, 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.04k
{
63
2.04k
  libfsntfs_attribute_t *reparse_point_attribute           = NULL;
64
2.04k
  libfsntfs_internal_file_entry_t *internal_file_entry     = NULL;
65
2.04k
  libfsntfs_mft_attribute_t *data_extents_attribute        = NULL;
66
2.04k
  libfsntfs_mft_attribute_t *wof_compressed_data_attribute = NULL;
67
2.04k
  libfsntfs_mft_entry_t *mft_entry                         = NULL;
68
2.04k
  static char *function                                    = "libfsntfs_file_entry_initialize";
69
2.04k
  uint64_t base_record_file_reference                      = 0;
70
2.04k
  uint32_t compression_method                              = 0;
71
2.04k
  int result                                               = 0;
72
73
2.04k
  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.04k
  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.04k
  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.04k
  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.04k
  internal_file_entry = memory_allocate_structure(
118
2.04k
                         libfsntfs_internal_file_entry_t );
119
120
2.04k
  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.04k
  if( memory_set(
132
2.04k
       internal_file_entry,
133
2.04k
       0,
134
2.04k
       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.04k
  if( libfsntfs_file_system_get_mft_entry_by_index_no_cache(
149
2.04k
       file_system,
150
2.04k
       file_io_handle,
151
2.04k
       mft_entry_index,
152
2.04k
       &mft_entry,
153
2.04k
       error ) != 1 )
154
24
  {
155
24
    libcerror_error_set(
156
24
     error,
157
24
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
158
24
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
159
24
     "%s: unable to retrieve MFT entry: %" PRIu64 ".",
160
24
     function,
161
24
     mft_entry_index );
162
163
24
    goto on_error;
164
24
  }
165
2.02k
  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.02k
  if( ( flags & LIBFSNTFS_FILE_ENTRY_FLAGS_MFT_ONLY ) == 0 )
178
2.02k
  {
179
2.02k
    result = libfsntfs_mft_entry_get_base_record_file_reference(
180
2.02k
              mft_entry,
181
2.02k
              &base_record_file_reference,
182
2.02k
              error );
183
184
2.02k
    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.02k
    if( ( result == 1 )
196
2.02k
     && ( base_record_file_reference == 0 ) )
197
1.91k
    {
198
1.91k
      if( mft_entry->has_i30_index != 0 )
199
1.58k
      {
200
1.58k
        if( libfsntfs_directory_entries_tree_initialize(
201
1.58k
             &( internal_file_entry->directory_entries_tree ),
202
1.58k
             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.58k
        if( libfsntfs_directory_entries_tree_read_from_i30_index(
214
1.58k
             internal_file_entry->directory_entries_tree,
215
1.58k
             io_handle,
216
1.58k
             file_io_handle,
217
1.58k
             mft_entry,
218
1.58k
             flags,
219
1.58k
             error ) != 1 )
220
1.43k
        {
221
1.43k
          libcerror_error_set(
222
1.43k
           error,
223
1.43k
           LIBCERROR_ERROR_DOMAIN_IO,
224
1.43k
           LIBCERROR_IO_ERROR_READ_FAILED,
225
1.43k
           "%s: unable to read MFT entry: %" PRIu32 " directory entries tree.",
226
1.43k
           function,
227
1.43k
           mft_entry->index );
228
229
1.43k
          goto on_error;
230
1.43k
        }
231
1.58k
      }
232
480
      if( mft_entry->data_attribute != NULL )
233
356
      {
234
356
        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
356
        if( wof_compressed_data_attribute == NULL )
273
356
        {
274
356
          data_extents_attribute = mft_entry->data_attribute;
275
356
        }
276
0
        else
277
0
        {
278
0
          data_extents_attribute = wof_compressed_data_attribute;
279
0
        }
280
356
        if( libfsntfs_mft_attribute_get_data_extents_array(
281
356
             data_extents_attribute,
282
356
             io_handle,
283
356
             &( internal_file_entry->extents_array ),
284
356
             error ) != 1 )
285
296
        {
286
296
          libcerror_error_set(
287
296
           error,
288
296
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
289
296
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
290
296
           "%s: unable to create extents array.",
291
296
           function );
292
293
296
          goto on_error;
294
296
        }
295
60
        if( libfsntfs_cluster_block_stream_initialize(
296
60
             &( internal_file_entry->data_cluster_block_stream ),
297
60
             io_handle,
298
60
             mft_entry->data_attribute,
299
60
             wof_compressed_data_attribute,
300
60
             compression_method,
301
60
             error ) != 1 )
302
7
        {
303
7
          libcerror_error_set(
304
7
           error,
305
7
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
306
7
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
307
7
           "%s: unable to create data cluster block stream.",
308
7
           function );
309
310
7
          goto on_error;
311
7
        }
312
60
      }
313
480
    }
314
2.02k
  }
315
287
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
316
287
  if( libcthreads_read_write_lock_initialize(
317
287
       &( internal_file_entry->read_write_lock ),
318
287
       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
287
#endif
330
287
  internal_file_entry->io_handle       = io_handle;
331
287
  internal_file_entry->file_io_handle  = file_io_handle;
332
287
  internal_file_entry->file_system     = file_system;
333
287
  internal_file_entry->mft_entry       = mft_entry;
334
287
  internal_file_entry->directory_entry = directory_entry;
335
287
  internal_file_entry->data_attribute  = mft_entry->data_attribute;
336
287
  internal_file_entry->flags           = flags;
337
338
287
  *file_entry = (libfsntfs_file_entry_t *) internal_file_entry;
339
340
287
  return( 1 );
341
342
1.76k
on_error:
343
1.76k
  if( mft_entry != NULL )
344
1.73k
  {
345
1.73k
    libfsntfs_mft_entry_free(
346
1.73k
     &mft_entry,
347
1.73k
     NULL );
348
1.73k
  }
349
1.76k
  if( internal_file_entry != NULL )
350
1.76k
  {
351
1.76k
    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.76k
    if( internal_file_entry->directory_entries_tree != NULL )
358
1.43k
    {
359
1.43k
      libfsntfs_directory_entries_tree_free(
360
1.43k
       &( internal_file_entry->directory_entries_tree ),
361
1.43k
       NULL );
362
1.43k
    }
363
1.76k
    if( internal_file_entry->extents_array != NULL )
364
7
    {
365
7
      libcdata_array_free(
366
7
       &( internal_file_entry->extents_array ),
367
7
       (int (*)(intptr_t **, libcerror_error_t **)) &libfsntfs_extent_free,
368
7
       NULL );
369
7
    }
370
1.76k
    memory_free(
371
1.76k
     internal_file_entry );
372
1.76k
  }
373
1.76k
  return( -1 );
374
287
}
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
287
{
383
287
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
384
287
  static char *function                                = "libfsntfs_file_entry_free";
385
287
  int result                                           = 1;
386
387
287
  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
287
  if( *file_entry != NULL )
399
287
  {
400
287
    internal_file_entry = (libfsntfs_internal_file_entry_t *) *file_entry;
401
287
    *file_entry         = NULL;
402
403
287
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
404
287
    if( libcthreads_read_write_lock_free(
405
287
         &( internal_file_entry->read_write_lock ),
406
287
         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
287
#endif
418
    /* The file_io_handle, io_handle and file_system references are freed elsewhere
419
     */
420
287
    if( internal_file_entry->data_cluster_block_stream != NULL )
421
53
    {
422
53
      if( libfdata_stream_free(
423
53
           &( internal_file_entry->data_cluster_block_stream ),
424
53
           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
53
    }
436
    /* The reparse_point_attribute, security_descriptor_attribute and standard_information_attribute references are managed by the attributes_array
437
     */
438
287
    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
287
    if( libcdata_array_free(
456
287
         &( internal_file_entry->extents_array ),
457
287
         (int (*)(intptr_t **, libcerror_error_t **)) &libfsntfs_extent_free,
458
287
         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
287
    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
287
    if( internal_file_entry->directory_entries_tree != NULL )
486
153
    {
487
153
      if( libfsntfs_directory_entries_tree_free(
488
153
           &( internal_file_entry->directory_entries_tree ),
489
153
           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
153
    }
501
287
    if( internal_file_entry->directory_entry != NULL )
502
24
    {
503
24
      if( libfsntfs_directory_entry_free(
504
24
           &( internal_file_entry->directory_entry ),
505
24
           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
24
    }
517
287
    if( internal_file_entry->mft_entry != NULL )
518
287
    {
519
287
      if( libfsntfs_mft_entry_free(
520
287
           &( internal_file_entry->mft_entry ),
521
287
           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
287
    }
533
287
    memory_free(
534
287
     internal_file_entry );
535
287
  }
536
287
  return( result );
537
287
}
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
 * Returns 1 if successful or -1 on error
1161
 */
1162
int libfsntfs_file_entry_get_file_reference(
1163
     libfsntfs_file_entry_t *file_entry,
1164
     uint64_t *file_reference,
1165
     libcerror_error_t **error )
1166
0
{
1167
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
1168
0
  static char *function                                = "libfsntfs_file_entry_get_file_reference";
1169
0
  int result                                           = 1;
1170
1171
0
  if( file_entry == NULL )
1172
0
  {
1173
0
    libcerror_error_set(
1174
0
     error,
1175
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1176
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1177
0
     "%s: invalid file entry.",
1178
0
     function );
1179
1180
0
    return( -1 );
1181
0
  }
1182
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1183
1184
0
  if( file_reference == NULL )
1185
0
  {
1186
0
    libcerror_error_set(
1187
0
     error,
1188
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1189
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1190
0
     "%s: invalid file reference.",
1191
0
     function );
1192
1193
0
    return( -1 );
1194
0
  }
1195
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1196
0
  if( libcthreads_read_write_lock_grab_for_read(
1197
0
       internal_file_entry->read_write_lock,
1198
0
       error ) != 1 )
1199
0
  {
1200
0
    libcerror_error_set(
1201
0
     error,
1202
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1203
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1204
0
     "%s: unable to grab read/write lock for reading.",
1205
0
     function );
1206
1207
0
    return( -1 );
1208
0
  }
1209
0
#endif
1210
0
  if( internal_file_entry->directory_entry != NULL )
1211
0
  {
1212
0
    if( libfsntfs_directory_entry_get_file_reference(
1213
0
         internal_file_entry->directory_entry,
1214
0
         file_reference,
1215
0
         error ) != 1 )
1216
0
    {
1217
0
      libcerror_error_set(
1218
0
       error,
1219
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1220
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1221
0
       "%s: unable to retrieve reference from directory entry.",
1222
0
       function );
1223
1224
0
      result = -1;
1225
0
    }
1226
0
  }
1227
0
  else
1228
0
  {
1229
0
    if( libfsntfs_mft_entry_get_file_reference(
1230
0
         internal_file_entry->mft_entry,
1231
0
         file_reference,
1232
0
         error ) != 1 )
1233
0
    {
1234
0
      libcerror_error_set(
1235
0
       error,
1236
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1237
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1238
0
       "%s: unable to retrieve file reference from MFT entry.",
1239
0
       function );
1240
1241
0
      result = -1;
1242
0
    }
1243
0
  }
1244
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1245
0
  if( libcthreads_read_write_lock_release_for_read(
1246
0
       internal_file_entry->read_write_lock,
1247
0
       error ) != 1 )
1248
0
  {
1249
0
    libcerror_error_set(
1250
0
     error,
1251
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1252
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1253
0
     "%s: unable to release read/write lock for reading.",
1254
0
     function );
1255
1256
0
    return( -1 );
1257
0
  }
1258
0
#endif
1259
0
  return( result );
1260
0
}
1261
1262
/* Retrieves the base record file reference
1263
 * Returns 1 if successful, 0 if not available or -1 on error
1264
 */
1265
int libfsntfs_file_entry_get_base_record_file_reference(
1266
     libfsntfs_file_entry_t *file_entry,
1267
     uint64_t *file_reference,
1268
     libcerror_error_t **error )
1269
0
{
1270
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
1271
0
  static char *function                                = "libfsntfs_file_entry_get_base_record_file_reference";
1272
0
  int result                                           = 1;
1273
1274
0
  if( file_entry == NULL )
1275
0
  {
1276
0
    libcerror_error_set(
1277
0
     error,
1278
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1279
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1280
0
     "%s: invalid file entry.",
1281
0
     function );
1282
1283
0
    return( -1 );
1284
0
  }
1285
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1286
1287
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1288
0
  if( libcthreads_read_write_lock_grab_for_read(
1289
0
       internal_file_entry->read_write_lock,
1290
0
       error ) != 1 )
1291
0
  {
1292
0
    libcerror_error_set(
1293
0
     error,
1294
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1295
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1296
0
     "%s: unable to grab read/write lock for reading.",
1297
0
     function );
1298
1299
0
    return( -1 );
1300
0
  }
1301
0
#endif
1302
0
  result = libfsntfs_mft_entry_get_base_record_file_reference(
1303
0
            internal_file_entry->mft_entry,
1304
0
            file_reference,
1305
0
            error );
1306
1307
0
  if( result == -1 )
1308
0
  {
1309
0
    libcerror_error_set(
1310
0
     error,
1311
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1312
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1313
0
     "%s: unable to retrieve base record file reference from MFT entry.",
1314
0
     function );
1315
1316
0
    result = -1;
1317
0
  }
1318
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1319
0
  if( libcthreads_read_write_lock_release_for_read(
1320
0
       internal_file_entry->read_write_lock,
1321
0
       error ) != 1 )
1322
0
  {
1323
0
    libcerror_error_set(
1324
0
     error,
1325
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1326
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1327
0
     "%s: unable to release read/write lock for reading.",
1328
0
     function );
1329
1330
0
    return( -1 );
1331
0
  }
1332
0
#endif
1333
0
  return( result );
1334
0
}
1335
1336
/* Retrieves the parent file reference
1337
 * This value is retrieved from the directory entry $FILE_NAME attribute
1338
 * Returns 1 if successful, 0 if not available or -1 on error
1339
 */
1340
int libfsntfs_file_entry_get_parent_file_reference(
1341
     libfsntfs_file_entry_t *file_entry,
1342
     uint64_t *parent_file_reference,
1343
     libcerror_error_t **error )
1344
0
{
1345
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
1346
0
  static char *function                                = "libfsntfs_file_entry_get_parent_file_reference";
1347
0
  int result                                           = 1;
1348
1349
0
  if( file_entry == NULL )
1350
0
  {
1351
0
    libcerror_error_set(
1352
0
     error,
1353
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1354
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1355
0
     "%s: invalid file entry.",
1356
0
     function );
1357
1358
0
    return( -1 );
1359
0
  }
1360
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1361
1362
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1363
0
  if( libcthreads_read_write_lock_grab_for_read(
1364
0
       internal_file_entry->read_write_lock,
1365
0
       error ) != 1 )
1366
0
  {
1367
0
    libcerror_error_set(
1368
0
     error,
1369
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1370
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1371
0
     "%s: unable to grab read/write lock for reading.",
1372
0
     function );
1373
1374
0
    return( -1 );
1375
0
  }
1376
0
#endif
1377
0
  if( libfsntfs_directory_entry_get_parent_file_reference(
1378
0
       internal_file_entry->directory_entry,
1379
0
       parent_file_reference,
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_GET_FAILED,
1386
0
     "%s: unable to retrieve parent reference from directory entry.",
1387
0
     function );
1388
1389
0
    result = -1;
1390
0
  }
1391
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1392
0
  if( libcthreads_read_write_lock_release_for_read(
1393
0
       internal_file_entry->read_write_lock,
1394
0
       error ) != 1 )
1395
0
  {
1396
0
    libcerror_error_set(
1397
0
     error,
1398
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1399
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1400
0
     "%s: unable to release read/write lock for reading.",
1401
0
     function );
1402
1403
0
    return( -1 );
1404
0
  }
1405
0
#endif
1406
0
  return( result );
1407
0
}
1408
1409
/* Retrieves the parent file reference for a specific $FILE_NAME attribute
1410
 * Returns 1 if successful or -1 on error
1411
 */
1412
int libfsntfs_file_entry_get_parent_file_reference_by_attribute_index(
1413
     libfsntfs_file_entry_t *file_entry,
1414
     int attribute_index,
1415
     uint64_t *parent_file_reference,
1416
     libcerror_error_t **error )
1417
0
{
1418
0
  libfsntfs_attribute_t *attribute                     = NULL;
1419
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
1420
0
  static char *function                                = "libfsntfs_file_entry_get_parent_file_reference_by_attribute_index";
1421
0
  int result                                           = 1;
1422
1423
0
  if( file_entry == NULL )
1424
0
  {
1425
0
    libcerror_error_set(
1426
0
     error,
1427
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1428
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1429
0
     "%s: invalid file entry.",
1430
0
     function );
1431
1432
0
    return( -1 );
1433
0
  }
1434
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1435
1436
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1437
0
  if( libcthreads_read_write_lock_grab_for_read(
1438
0
       internal_file_entry->read_write_lock,
1439
0
       error ) != 1 )
1440
0
  {
1441
0
    libcerror_error_set(
1442
0
     error,
1443
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1444
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1445
0
     "%s: unable to grab read/write lock for reading.",
1446
0
     function );
1447
1448
0
    return( -1 );
1449
0
  }
1450
0
#endif
1451
0
  if( libfsntfs_internal_file_entry_get_attribute_by_index(
1452
0
       internal_file_entry,
1453
0
       internal_file_entry->mft_entry,
1454
0
       attribute_index,
1455
0
       &attribute,
1456
0
       error ) != 1 )
1457
0
  {
1458
0
    libcerror_error_set(
1459
0
     error,
1460
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1461
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1462
0
     "%s: unable to retrieve attribute: %d.",
1463
0
     function,
1464
0
     attribute_index );
1465
1466
0
    result = -1;
1467
0
  }
1468
0
  else if( libfsntfs_file_name_attribute_get_parent_file_reference(
1469
0
            attribute,
1470
0
            parent_file_reference,
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_GET_FAILED,
1477
0
     "%s: unable to retrieve parent reference from $FILE_NAME attribute.",
1478
0
     function );
1479
1480
0
    result = -1;
1481
0
  }
1482
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1483
0
  if( libcthreads_read_write_lock_release_for_read(
1484
0
       internal_file_entry->read_write_lock,
1485
0
       error ) != 1 )
1486
0
  {
1487
0
    libcerror_error_set(
1488
0
     error,
1489
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1490
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1491
0
     "%s: unable to release read/write lock for reading.",
1492
0
     function );
1493
1494
0
    return( -1 );
1495
0
  }
1496
0
#endif
1497
0
  return( result );
1498
0
}
1499
1500
/* Retrieves the journal sequence number
1501
 * Returns 1 if successful or -1 on error
1502
 */
1503
int libfsntfs_file_entry_get_journal_sequence_number(
1504
     libfsntfs_file_entry_t *file_entry,
1505
     uint64_t *journal_sequence_number,
1506
     libcerror_error_t **error )
1507
0
{
1508
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
1509
0
  static char *function                                = "libfsntfs_file_entry_get_journal_sequence_number";
1510
0
  int result                                           = 1;
1511
1512
0
  if( file_entry == NULL )
1513
0
  {
1514
0
    libcerror_error_set(
1515
0
     error,
1516
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1517
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1518
0
     "%s: invalid file entry.",
1519
0
     function );
1520
1521
0
    return( -1 );
1522
0
  }
1523
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1524
1525
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1526
0
  if( libcthreads_read_write_lock_grab_for_read(
1527
0
       internal_file_entry->read_write_lock,
1528
0
       error ) != 1 )
1529
0
  {
1530
0
    libcerror_error_set(
1531
0
     error,
1532
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1533
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1534
0
     "%s: unable to grab read/write lock for reading.",
1535
0
     function );
1536
1537
0
    return( -1 );
1538
0
  }
1539
0
#endif
1540
0
  if( libfsntfs_mft_entry_get_journal_sequence_number(
1541
0
       internal_file_entry->mft_entry,
1542
0
       journal_sequence_number,
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_GET_FAILED,
1549
0
     "%s: unable to retrieve journal sequence number from MFT entry.",
1550
0
     function );
1551
1552
0
    result = -1;
1553
0
  }
1554
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1555
0
  if( libcthreads_read_write_lock_release_for_read(
1556
0
       internal_file_entry->read_write_lock,
1557
0
       error ) != 1 )
1558
0
  {
1559
0
    libcerror_error_set(
1560
0
     error,
1561
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1562
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1563
0
     "%s: unable to release read/write lock for reading.",
1564
0
     function );
1565
1566
0
    return( -1 );
1567
0
  }
1568
0
#endif
1569
0
  return( result );
1570
0
}
1571
1572
/* Retrieves the creation date and time
1573
 * This value is retrieved from the $STANDARD_INFORMATION attribute
1574
 * Returns 1 if successful, 0 if not available or -1 on error
1575
 */
1576
int libfsntfs_file_entry_get_creation_time(
1577
     libfsntfs_file_entry_t *file_entry,
1578
     uint64_t *filetime,
1579
     libcerror_error_t **error )
1580
0
{
1581
0
  libfsntfs_attribute_t *standard_information_attribute                = NULL;
1582
0
  libfsntfs_internal_file_entry_t *internal_file_entry                 = NULL;
1583
0
  libfsntfs_standard_information_values_t *standard_information_values = NULL;
1584
0
  static char *function                                                = "libfsntfs_file_entry_get_creation_time";
1585
0
  int result                                                           = 0;
1586
1587
0
  if( file_entry == NULL )
1588
0
  {
1589
0
    libcerror_error_set(
1590
0
     error,
1591
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1592
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1593
0
     "%s: invalid file entry.",
1594
0
     function );
1595
1596
0
    return( -1 );
1597
0
  }
1598
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1599
1600
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1601
0
  if( libcthreads_read_write_lock_grab_for_read(
1602
0
       internal_file_entry->read_write_lock,
1603
0
       error ) != 1 )
1604
0
  {
1605
0
    libcerror_error_set(
1606
0
     error,
1607
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1608
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1609
0
     "%s: unable to grab read/write lock for reading.",
1610
0
     function );
1611
1612
0
    return( -1 );
1613
0
  }
1614
0
#endif
1615
0
  result = libfsntfs_internal_file_entry_get_standard_information_attribute(
1616
0
            internal_file_entry,
1617
0
            &standard_information_attribute,
1618
0
            error );
1619
1620
0
  if( result == -1 )
1621
0
  {
1622
0
    libcerror_error_set(
1623
0
     error,
1624
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1625
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1626
0
     "%s: unable to retrieve standard information attribute.",
1627
0
     function );
1628
1629
0
    result = -1;
1630
0
  }
1631
0
  else if( result != 0 )
1632
0
  {
1633
0
    if( libfsntfs_internal_attribute_get_value(
1634
0
         (libfsntfs_internal_attribute_t *) standard_information_attribute,
1635
0
         (intptr_t **) &standard_information_values,
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 value from standard information attribute.",
1643
0
       function );
1644
1645
0
      result = -1;
1646
0
    }
1647
0
    else if( libfsntfs_standard_information_values_get_creation_time(
1648
0
              standard_information_values,
1649
0
              filetime,
1650
0
              error ) != 1 )
1651
0
    {
1652
0
      libcerror_error_set(
1653
0
       error,
1654
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1655
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1656
0
       "%s: unable to retrieve creation time from standard information attribute.",
1657
0
       function );
1658
1659
0
      result = -1;
1660
0
    }
1661
0
  }
1662
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1663
0
  if( libcthreads_read_write_lock_release_for_read(
1664
0
       internal_file_entry->read_write_lock,
1665
0
       error ) != 1 )
1666
0
  {
1667
0
    libcerror_error_set(
1668
0
     error,
1669
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1670
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1671
0
     "%s: unable to release read/write lock for reading.",
1672
0
     function );
1673
1674
0
    return( -1 );
1675
0
  }
1676
0
#endif
1677
0
  return( result );
1678
0
}
1679
1680
/* Retrieves the (file) modification (last written) date and time
1681
 * This value is retrieved from the $STANDARD_INFORMATION attribute
1682
 * Returns 1 if successful, 0 if not available or -1 on error
1683
 */
1684
int libfsntfs_file_entry_get_modification_time(
1685
     libfsntfs_file_entry_t *file_entry,
1686
     uint64_t *filetime,
1687
     libcerror_error_t **error )
1688
0
{
1689
0
  libfsntfs_attribute_t *standard_information_attribute                = NULL;
1690
0
  libfsntfs_internal_file_entry_t *internal_file_entry                 = NULL;
1691
0
  libfsntfs_standard_information_values_t *standard_information_values = NULL;
1692
0
  static char *function                                                = "libfsntfs_file_entry_get_modification_time";
1693
0
  int result                                                           = 0;
1694
1695
0
  if( file_entry == NULL )
1696
0
  {
1697
0
    libcerror_error_set(
1698
0
     error,
1699
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1700
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1701
0
     "%s: invalid file entry.",
1702
0
     function );
1703
1704
0
    return( -1 );
1705
0
  }
1706
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1707
1708
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1709
0
  if( libcthreads_read_write_lock_grab_for_read(
1710
0
       internal_file_entry->read_write_lock,
1711
0
       error ) != 1 )
1712
0
  {
1713
0
    libcerror_error_set(
1714
0
     error,
1715
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1716
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1717
0
     "%s: unable to grab read/write lock for reading.",
1718
0
     function );
1719
1720
0
    return( -1 );
1721
0
  }
1722
0
#endif
1723
0
  result = libfsntfs_internal_file_entry_get_standard_information_attribute(
1724
0
            internal_file_entry,
1725
0
            &standard_information_attribute,
1726
0
            error );
1727
1728
0
  if( result == -1 )
1729
0
  {
1730
0
    libcerror_error_set(
1731
0
     error,
1732
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1733
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1734
0
     "%s: unable to retrieve standard information attribute.",
1735
0
     function );
1736
1737
0
    result = -1;
1738
0
  }
1739
0
  else if( result != 0 )
1740
0
  {
1741
0
    if( libfsntfs_internal_attribute_get_value(
1742
0
         (libfsntfs_internal_attribute_t *) standard_information_attribute,
1743
0
         (intptr_t **) &standard_information_values,
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 standard information attribute value.",
1751
0
       function );
1752
1753
0
      result = -1;
1754
0
    }
1755
0
    else if( libfsntfs_standard_information_values_get_modification_time(
1756
0
              standard_information_values,
1757
0
              filetime,
1758
0
              error ) != 1 )
1759
0
    {
1760
0
      libcerror_error_set(
1761
0
       error,
1762
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1763
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1764
0
       "%s: unable to retrieve modification time from standard information attribute.",
1765
0
       function );
1766
1767
0
      result = -1;
1768
0
    }
1769
0
  }
1770
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1771
0
  if( libcthreads_read_write_lock_release_for_read(
1772
0
       internal_file_entry->read_write_lock,
1773
0
       error ) != 1 )
1774
0
  {
1775
0
    libcerror_error_set(
1776
0
     error,
1777
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1778
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1779
0
     "%s: unable to release read/write lock for reading.",
1780
0
     function );
1781
1782
0
    return( -1 );
1783
0
  }
1784
0
#endif
1785
0
  return( result );
1786
0
}
1787
1788
/* Retrieves the access date and time
1789
 * This value is retrieved from the $STANDARD_INFORMATION attribute
1790
 * Returns 1 if successful, 0 if not available or -1 on error
1791
 */
1792
int libfsntfs_file_entry_get_access_time(
1793
     libfsntfs_file_entry_t *file_entry,
1794
     uint64_t *filetime,
1795
     libcerror_error_t **error )
1796
0
{
1797
0
  libfsntfs_attribute_t *standard_information_attribute                = NULL;
1798
0
  libfsntfs_internal_file_entry_t *internal_file_entry                 = NULL;
1799
0
  libfsntfs_standard_information_values_t *standard_information_values = NULL;
1800
0
  static char *function                                                = "libfsntfs_file_entry_get_access_time";
1801
0
  int result                                                           = 0;
1802
1803
0
  if( file_entry == NULL )
1804
0
  {
1805
0
    libcerror_error_set(
1806
0
     error,
1807
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1808
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1809
0
     "%s: invalid file entry.",
1810
0
     function );
1811
1812
0
    return( -1 );
1813
0
  }
1814
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1815
1816
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1817
0
  if( libcthreads_read_write_lock_grab_for_read(
1818
0
       internal_file_entry->read_write_lock,
1819
0
       error ) != 1 )
1820
0
  {
1821
0
    libcerror_error_set(
1822
0
     error,
1823
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1824
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1825
0
     "%s: unable to grab read/write lock for reading.",
1826
0
     function );
1827
1828
0
    return( -1 );
1829
0
  }
1830
0
#endif
1831
0
  result = libfsntfs_internal_file_entry_get_standard_information_attribute(
1832
0
            internal_file_entry,
1833
0
            &standard_information_attribute,
1834
0
            error );
1835
1836
0
  if( result == -1 )
1837
0
  {
1838
0
    libcerror_error_set(
1839
0
     error,
1840
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1841
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1842
0
     "%s: unable to retrieve standard information attribute.",
1843
0
     function );
1844
1845
0
    result = -1;
1846
0
  }
1847
0
  else if( result != 0 )
1848
0
  {
1849
0
    if( libfsntfs_internal_attribute_get_value(
1850
0
         (libfsntfs_internal_attribute_t *) standard_information_attribute,
1851
0
         (intptr_t **) &standard_information_values,
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 standard information attribute value.",
1859
0
       function );
1860
1861
0
      result = -1;
1862
0
    }
1863
0
    else if( libfsntfs_standard_information_values_get_access_time(
1864
0
              standard_information_values,
1865
0
              filetime,
1866
0
              error ) != 1 )
1867
0
    {
1868
0
      libcerror_error_set(
1869
0
       error,
1870
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1871
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1872
0
       "%s: unable to retrieve access time from standard information attribute.",
1873
0
       function );
1874
1875
0
      result = -1;
1876
0
    }
1877
0
  }
1878
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1879
0
  if( libcthreads_read_write_lock_release_for_read(
1880
0
       internal_file_entry->read_write_lock,
1881
0
       error ) != 1 )
1882
0
  {
1883
0
    libcerror_error_set(
1884
0
     error,
1885
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1886
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1887
0
     "%s: unable to release read/write lock for reading.",
1888
0
     function );
1889
1890
0
    return( -1 );
1891
0
  }
1892
0
#endif
1893
0
  return( result );
1894
0
}
1895
1896
/* Retrieves the (file system entry) modification date and time
1897
 * This value is retrieved from the $STANDARD_INFORMATION attribute
1898
 * Returns 1 if successful, 0 if not available or -1 on error
1899
 */
1900
int libfsntfs_file_entry_get_entry_modification_time(
1901
     libfsntfs_file_entry_t *file_entry,
1902
     uint64_t *filetime,
1903
     libcerror_error_t **error )
1904
0
{
1905
0
  libfsntfs_attribute_t *standard_information_attribute                = NULL;
1906
0
  libfsntfs_internal_file_entry_t *internal_file_entry                 = NULL;
1907
0
  libfsntfs_standard_information_values_t *standard_information_values = NULL;
1908
0
  static char *function                                                = "libfsntfs_file_entry_get_entry_modification_time";
1909
0
  int result                                                           = 0;
1910
1911
0
  if( file_entry == NULL )
1912
0
  {
1913
0
    libcerror_error_set(
1914
0
     error,
1915
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1916
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1917
0
     "%s: invalid file entry.",
1918
0
     function );
1919
1920
0
    return( -1 );
1921
0
  }
1922
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
1923
1924
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1925
0
  if( libcthreads_read_write_lock_grab_for_read(
1926
0
       internal_file_entry->read_write_lock,
1927
0
       error ) != 1 )
1928
0
  {
1929
0
    libcerror_error_set(
1930
0
     error,
1931
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1932
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1933
0
     "%s: unable to grab read/write lock for reading.",
1934
0
     function );
1935
1936
0
    return( -1 );
1937
0
  }
1938
0
#endif
1939
0
  result = libfsntfs_internal_file_entry_get_standard_information_attribute(
1940
0
            internal_file_entry,
1941
0
            &standard_information_attribute,
1942
0
            error );
1943
1944
0
  if( result == -1 )
1945
0
  {
1946
0
    libcerror_error_set(
1947
0
     error,
1948
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1949
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1950
0
     "%s: unable to retrieve standard information attribute.",
1951
0
     function );
1952
1953
0
    result = -1;
1954
0
  }
1955
0
  else if( result != 0 )
1956
0
  {
1957
0
    if( libfsntfs_internal_attribute_get_value(
1958
0
         (libfsntfs_internal_attribute_t *) standard_information_attribute,
1959
0
         (intptr_t **) &standard_information_values,
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 standard information attribute value.",
1967
0
       function );
1968
1969
0
      result = -1;
1970
0
    }
1971
0
    else if( libfsntfs_standard_information_values_get_entry_modification_time(
1972
0
              standard_information_values,
1973
0
              filetime,
1974
0
              error ) != 1 )
1975
0
    {
1976
0
      libcerror_error_set(
1977
0
       error,
1978
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1979
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1980
0
       "%s: unable to retrieve entry modification time from standard information attribute.",
1981
0
       function );
1982
1983
0
      result = -1;
1984
0
    }
1985
0
  }
1986
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
1987
0
  if( libcthreads_read_write_lock_release_for_read(
1988
0
       internal_file_entry->read_write_lock,
1989
0
       error ) != 1 )
1990
0
  {
1991
0
    libcerror_error_set(
1992
0
     error,
1993
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1994
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1995
0
     "%s: unable to release read/write lock for reading.",
1996
0
     function );
1997
1998
0
    return( -1 );
1999
0
  }
2000
0
#endif
2001
0
  return( result );
2002
0
}
2003
2004
/* Retrieves the file attribute flags
2005
 * This value is retrieved from the $STANDARD_INFORMATION attribute
2006
 * Returns 1 if successful, 0 if not available or -1 on error
2007
 */
2008
int libfsntfs_file_entry_get_file_attribute_flags(
2009
     libfsntfs_file_entry_t *file_entry,
2010
     uint32_t *file_attribute_flags,
2011
     libcerror_error_t **error )
2012
0
{
2013
0
  libfsntfs_attribute_t *standard_information_attribute                = NULL;
2014
0
  libfsntfs_internal_file_entry_t *internal_file_entry                 = NULL;
2015
0
  libfsntfs_standard_information_values_t *standard_information_values = NULL;
2016
0
  static char *function                                                = "libfsntfs_file_entry_get_file_attribute_flags";
2017
0
  int result                                                           = 0;
2018
2019
0
  if( file_entry == NULL )
2020
0
  {
2021
0
    libcerror_error_set(
2022
0
     error,
2023
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2024
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2025
0
     "%s: invalid file entry.",
2026
0
     function );
2027
2028
0
    return( -1 );
2029
0
  }
2030
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2031
2032
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2033
0
  if( libcthreads_read_write_lock_grab_for_read(
2034
0
       internal_file_entry->read_write_lock,
2035
0
       error ) != 1 )
2036
0
  {
2037
0
    libcerror_error_set(
2038
0
     error,
2039
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2040
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2041
0
     "%s: unable to grab read/write lock for reading.",
2042
0
     function );
2043
2044
0
    return( -1 );
2045
0
  }
2046
0
#endif
2047
0
  result = libfsntfs_internal_file_entry_get_standard_information_attribute(
2048
0
            internal_file_entry,
2049
0
            &standard_information_attribute,
2050
0
            error );
2051
2052
0
  if( result == -1 )
2053
0
  {
2054
0
    libcerror_error_set(
2055
0
     error,
2056
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2057
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2058
0
     "%s: unable to retrieve standard information attribute.",
2059
0
     function );
2060
2061
0
    result = -1;
2062
0
  }
2063
0
  else if( result != 0 )
2064
0
  {
2065
0
    if( libfsntfs_internal_attribute_get_value(
2066
0
         (libfsntfs_internal_attribute_t *) standard_information_attribute,
2067
0
         (intptr_t **) &standard_information_values,
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 standard information attribute value.",
2075
0
       function );
2076
2077
0
      result = -1;
2078
0
    }
2079
0
    else if( libfsntfs_standard_information_values_get_file_attribute_flags(
2080
0
              standard_information_values,
2081
0
              file_attribute_flags,
2082
0
              error ) != 1 )
2083
0
    {
2084
0
      libcerror_error_set(
2085
0
       error,
2086
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2087
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2088
0
       "%s: unable to retrieve file attribute flags from standard information attribute.",
2089
0
       function );
2090
2091
0
      result = -1;
2092
0
    }
2093
0
  }
2094
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2095
0
  if( libcthreads_read_write_lock_release_for_read(
2096
0
       internal_file_entry->read_write_lock,
2097
0
       error ) != 1 )
2098
0
  {
2099
0
    libcerror_error_set(
2100
0
     error,
2101
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2102
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2103
0
     "%s: unable to release read/write lock for reading.",
2104
0
     function );
2105
2106
0
    return( -1 );
2107
0
  }
2108
0
#endif
2109
0
  return( result );
2110
0
}
2111
2112
/* Retrieves the size of the UTF-8 encoded name
2113
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
2114
 * The returned size includes the end of string character
2115
 * This value is retrieved from the directory entry $FILE_NAME attribute
2116
 * Returns 1 if successful, 0 if not available or -1 on error
2117
 */
2118
int libfsntfs_file_entry_get_utf8_name_size(
2119
     libfsntfs_file_entry_t *file_entry,
2120
     size_t *utf8_string_size,
2121
     libcerror_error_t **error )
2122
0
{
2123
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2124
0
  static char *function                                = "libfsntfs_file_entry_get_utf8_name_size";
2125
0
  int result                                           = 0;
2126
2127
0
  if( file_entry == NULL )
2128
0
  {
2129
0
    libcerror_error_set(
2130
0
     error,
2131
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2132
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2133
0
     "%s: invalid file entry.",
2134
0
     function );
2135
2136
0
    return( -1 );
2137
0
  }
2138
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2139
2140
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2141
0
  if( libcthreads_read_write_lock_grab_for_read(
2142
0
       internal_file_entry->read_write_lock,
2143
0
       error ) != 1 )
2144
0
  {
2145
0
    libcerror_error_set(
2146
0
     error,
2147
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2148
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2149
0
     "%s: unable to grab read/write lock for reading.",
2150
0
     function );
2151
2152
0
    return( -1 );
2153
0
  }
2154
0
#endif
2155
0
  if( internal_file_entry->directory_entry != NULL )
2156
0
  {
2157
0
    result = libfsntfs_directory_entry_get_utf8_name_size(
2158
0
              internal_file_entry->directory_entry,
2159
0
              utf8_string_size,
2160
0
              error );
2161
2162
0
    if( result != 1 )
2163
0
    {
2164
0
      libcerror_error_set(
2165
0
       error,
2166
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2167
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2168
0
       "%s: unable to retrieve size of UTF-8 name from directory entry.",
2169
0
       function );
2170
2171
0
      result = -1;
2172
0
    }
2173
0
  }
2174
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2175
0
  if( libcthreads_read_write_lock_release_for_read(
2176
0
       internal_file_entry->read_write_lock,
2177
0
       error ) != 1 )
2178
0
  {
2179
0
    libcerror_error_set(
2180
0
     error,
2181
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2182
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2183
0
     "%s: unable to release read/write lock for reading.",
2184
0
     function );
2185
2186
0
    return( -1 );
2187
0
  }
2188
0
#endif
2189
0
  return( result );
2190
0
}
2191
2192
/* Retrieves the UTF-8 encoded name
2193
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
2194
 * The size should include the end of string character
2195
 * This value is retrieved from the directory entry $FILE_NAME attribute
2196
 * Returns 1 if successful, 0 if not available or -1 on error
2197
 */
2198
int libfsntfs_file_entry_get_utf8_name(
2199
     libfsntfs_file_entry_t *file_entry,
2200
     uint8_t *utf8_string,
2201
     size_t utf8_string_size,
2202
     libcerror_error_t **error )
2203
0
{
2204
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2205
0
  static char *function                                = "libfsntfs_file_entry_get_utf8_name";
2206
0
  int result                                           = 0;
2207
2208
0
  if( file_entry == NULL )
2209
0
  {
2210
0
    libcerror_error_set(
2211
0
     error,
2212
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2213
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2214
0
     "%s: invalid file entry.",
2215
0
     function );
2216
2217
0
    return( -1 );
2218
0
  }
2219
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2220
2221
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2222
0
  if( libcthreads_read_write_lock_grab_for_read(
2223
0
       internal_file_entry->read_write_lock,
2224
0
       error ) != 1 )
2225
0
  {
2226
0
    libcerror_error_set(
2227
0
     error,
2228
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2229
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2230
0
     "%s: unable to grab read/write lock for reading.",
2231
0
     function );
2232
2233
0
    return( -1 );
2234
0
  }
2235
0
#endif
2236
0
  if( internal_file_entry->directory_entry != NULL )
2237
0
  {
2238
0
    result = libfsntfs_directory_entry_get_utf8_name(
2239
0
              internal_file_entry->directory_entry,
2240
0
              utf8_string,
2241
0
              utf8_string_size,
2242
0
              error );
2243
2244
0
    if( result != 1 )
2245
0
    {
2246
0
      libcerror_error_set(
2247
0
       error,
2248
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2249
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2250
0
       "%s: unable to retrieve UTF-8 name from directory entry.",
2251
0
       function );
2252
2253
0
      result = -1;
2254
0
    }
2255
0
  }
2256
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2257
0
  if( libcthreads_read_write_lock_release_for_read(
2258
0
       internal_file_entry->read_write_lock,
2259
0
       error ) != 1 )
2260
0
  {
2261
0
    libcerror_error_set(
2262
0
     error,
2263
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2264
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2265
0
     "%s: unable to release read/write lock for reading.",
2266
0
     function );
2267
2268
0
    return( -1 );
2269
0
  }
2270
0
#endif
2271
0
  return( result );
2272
0
}
2273
2274
/* Retrieves the size of the UTF-16 encoded name
2275
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
2276
 * The returned size includes the end of string character
2277
 * This value is retrieved from the directory entry $FILE_NAME attribute
2278
 * Returns 1 if successful, 0 if not available or -1 on error
2279
 */
2280
int libfsntfs_file_entry_get_utf16_name_size(
2281
     libfsntfs_file_entry_t *file_entry,
2282
     size_t *utf16_string_size,
2283
     libcerror_error_t **error )
2284
0
{
2285
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2286
0
  static char *function                                = "libfsntfs_file_entry_get_utf16_name_size";
2287
0
  int result                                           = 0;
2288
2289
0
  if( file_entry == NULL )
2290
0
  {
2291
0
    libcerror_error_set(
2292
0
     error,
2293
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2294
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2295
0
     "%s: invalid file entry.",
2296
0
     function );
2297
2298
0
    return( -1 );
2299
0
  }
2300
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2301
2302
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2303
0
  if( libcthreads_read_write_lock_grab_for_read(
2304
0
       internal_file_entry->read_write_lock,
2305
0
       error ) != 1 )
2306
0
  {
2307
0
    libcerror_error_set(
2308
0
     error,
2309
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2310
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2311
0
     "%s: unable to grab read/write lock for reading.",
2312
0
     function );
2313
2314
0
    return( -1 );
2315
0
  }
2316
0
#endif
2317
0
  if( internal_file_entry->directory_entry != NULL )
2318
0
  {
2319
0
    result = libfsntfs_directory_entry_get_utf16_name_size(
2320
0
              internal_file_entry->directory_entry,
2321
0
              utf16_string_size,
2322
0
              error );
2323
2324
0
    if( result != 1 )
2325
0
    {
2326
0
      libcerror_error_set(
2327
0
       error,
2328
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2329
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2330
0
       "%s: unable to retrieve size of UTF-16 name from directory.",
2331
0
       function );
2332
2333
0
      result = -1;
2334
0
    }
2335
0
  }
2336
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2337
0
  if( libcthreads_read_write_lock_release_for_read(
2338
0
       internal_file_entry->read_write_lock,
2339
0
       error ) != 1 )
2340
0
  {
2341
0
    libcerror_error_set(
2342
0
     error,
2343
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2344
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2345
0
     "%s: unable to release read/write lock for reading.",
2346
0
     function );
2347
2348
0
    return( -1 );
2349
0
  }
2350
0
#endif
2351
0
  return( result );
2352
0
}
2353
2354
/* Retrieves the UTF-16 encoded name
2355
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
2356
 * The size should include the end of string character
2357
 * This value is retrieved from the directory entry $FILE_NAME attribute
2358
 * Returns 1 if successful, 0 if not available or -1 on error
2359
 */
2360
int libfsntfs_file_entry_get_utf16_name(
2361
     libfsntfs_file_entry_t *file_entry,
2362
     uint16_t *utf16_string,
2363
     size_t utf16_string_size,
2364
     libcerror_error_t **error )
2365
0
{
2366
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2367
0
  static char *function                                = "libfsntfs_file_entry_get_utf16_name";
2368
0
  int result                                           = 0;
2369
2370
0
  if( file_entry == NULL )
2371
0
  {
2372
0
    libcerror_error_set(
2373
0
     error,
2374
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2375
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2376
0
     "%s: invalid file entry.",
2377
0
     function );
2378
2379
0
    return( -1 );
2380
0
  }
2381
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2382
2383
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2384
0
  if( libcthreads_read_write_lock_grab_for_read(
2385
0
       internal_file_entry->read_write_lock,
2386
0
       error ) != 1 )
2387
0
  {
2388
0
    libcerror_error_set(
2389
0
     error,
2390
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2391
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2392
0
     "%s: unable to grab read/write lock for reading.",
2393
0
     function );
2394
2395
0
    return( -1 );
2396
0
  }
2397
0
#endif
2398
0
  if( internal_file_entry->directory_entry != NULL )
2399
0
  {
2400
0
    result = libfsntfs_directory_entry_get_utf16_name(
2401
0
              internal_file_entry->directory_entry,
2402
0
              utf16_string,
2403
0
              utf16_string_size,
2404
0
              error );
2405
2406
0
    if( result != 1 )
2407
0
    {
2408
0
      libcerror_error_set(
2409
0
       error,
2410
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2411
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2412
0
       "%s: unable to retrieve UTF-16 name from directory entry.",
2413
0
       function );
2414
2415
0
      result = -1;
2416
0
    }
2417
0
  }
2418
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2419
0
  if( libcthreads_read_write_lock_release_for_read(
2420
0
       internal_file_entry->read_write_lock,
2421
0
       error ) != 1 )
2422
0
  {
2423
0
    libcerror_error_set(
2424
0
     error,
2425
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2426
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2427
0
     "%s: unable to release read/write lock for reading.",
2428
0
     function );
2429
2430
0
    return( -1 );
2431
0
  }
2432
0
#endif
2433
0
  return( result );
2434
0
}
2435
2436
/* Retrieves the $FILE_NAME attribute index
2437
 * Returns 1 if successful, 0 if not available or -1 on error
2438
 */
2439
int libfsntfs_file_entry_get_name_attribute_index(
2440
     libfsntfs_file_entry_t *file_entry,
2441
     int *attribute_index,
2442
     libcerror_error_t **error )
2443
0
{
2444
0
  uint8_t lookup_name_root[ 2 ]                        = { '.', 0 };
2445
2446
0
  libfsntfs_attribute_t *attribute                     = NULL;
2447
0
  libfsntfs_file_name_values_t *file_name_values       = NULL;
2448
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2449
0
  uint8_t *lookup_name                                 = NULL;
2450
0
  static char *function                                = "libfsntfs_file_entry_get_name_attribute_index";
2451
0
  size_t lookup_name_size                              = 0;
2452
0
  uint32_t attribute_type                              = 0;
2453
0
  uint8_t lookup_name_space                            = 0;
2454
0
  int number_of_attributes                             = 0;
2455
0
  int safe_attribute_index                             = 0;
2456
2457
0
  if( file_entry == NULL )
2458
0
  {
2459
0
    libcerror_error_set(
2460
0
     error,
2461
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2462
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2463
0
     "%s: invalid file entry.",
2464
0
     function );
2465
2466
0
    return( -1 );
2467
0
  }
2468
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2469
2470
0
  if( attribute_index == NULL )
2471
0
  {
2472
0
    libcerror_error_set(
2473
0
     error,
2474
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2475
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2476
0
     "%s: invalid attribute index",
2477
0
     function );
2478
2479
0
    return( -1 );
2480
0
  }
2481
/* TODO add thread lock suport */
2482
2483
0
  if( internal_file_entry->directory_entry == NULL )
2484
0
  {
2485
0
    lookup_name       = lookup_name_root;
2486
0
    lookup_name_size  = 2;
2487
0
    lookup_name_space = LIBFSNTFS_FILE_NAME_SPACE_DOS_WINDOWS;
2488
0
  }
2489
0
  else
2490
0
  {
2491
0
    if( internal_file_entry->directory_entry->file_name_values == NULL )
2492
0
    {
2493
0
      libcerror_error_set(
2494
0
       error,
2495
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2496
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2497
0
       "%s: invalid file entry - invalid directory entry - missing file name values.",
2498
0
       function );
2499
2500
0
      return( -1 );
2501
0
    }
2502
0
    lookup_name       = internal_file_entry->directory_entry->file_name_values->name;
2503
0
    lookup_name_size  = internal_file_entry->directory_entry->file_name_values->name_size;
2504
0
    lookup_name_space = internal_file_entry->directory_entry->file_name_values->name_space;
2505
0
  }
2506
0
  if( libfsntfs_mft_entry_get_number_of_attributes(
2507
0
       internal_file_entry->mft_entry,
2508
0
       &number_of_attributes,
2509
0
       error ) != 1 )
2510
0
  {
2511
0
    libcerror_error_set(
2512
0
     error,
2513
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2514
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2515
0
     "%s: unable to retrieve number of attributes.",
2516
0
     function );
2517
2518
0
    return( -1 );
2519
0
  }
2520
0
  for( safe_attribute_index = 0;
2521
0
       safe_attribute_index < number_of_attributes;
2522
0
       safe_attribute_index++ )
2523
0
  {
2524
0
    if( libfsntfs_internal_file_entry_get_attribute_by_index(
2525
0
         internal_file_entry,
2526
0
         internal_file_entry->mft_entry,
2527
0
         safe_attribute_index,
2528
0
         &attribute,
2529
0
         error ) != 1 )
2530
0
    {
2531
0
      libcerror_error_set(
2532
0
       error,
2533
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2534
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2535
0
       "%s: unable to retrieve attribute: %d.",
2536
0
       function,
2537
0
       safe_attribute_index );
2538
2539
0
      return( -1 );
2540
0
    }
2541
0
    if( libfsntfs_attribute_get_type(
2542
0
         attribute,
2543
0
         &attribute_type,
2544
0
         error ) != 1 )
2545
0
    {
2546
0
      libcerror_error_set(
2547
0
       error,
2548
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2549
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2550
0
       "%s: unable to retrieve attribute: %d type.",
2551
0
       function,
2552
0
       safe_attribute_index );
2553
2554
0
      return( -1 );
2555
0
    }
2556
0
    if( attribute_type != LIBFSNTFS_ATTRIBUTE_TYPE_FILE_NAME )
2557
0
    {
2558
0
      continue;
2559
0
    }
2560
0
    if( libfsntfs_internal_attribute_get_value(
2561
0
         (libfsntfs_internal_attribute_t *) attribute,
2562
0
         (intptr_t **) &file_name_values,
2563
0
         error ) != 1 )
2564
0
    {
2565
0
      libcerror_error_set(
2566
0
       error,
2567
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2568
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2569
0
       "%s: unable to retrieve attribute: %d value.",
2570
0
       function,
2571
0
       safe_attribute_index );
2572
2573
0
      return( -1 );
2574
0
    }
2575
0
    if( ( lookup_name_space == file_name_values->name_space )
2576
0
     && ( lookup_name_size == file_name_values->name_size )
2577
0
     && ( memory_compare(
2578
0
           lookup_name,
2579
0
           file_name_values->name,
2580
0
           file_name_values->name_size ) == 0 ) )
2581
0
    {
2582
0
      *attribute_index = safe_attribute_index;
2583
2584
0
      return( 1 );
2585
0
    }
2586
0
  }
2587
0
  return( 0 );
2588
0
}
2589
2590
/* Retrieves the size of the UTF-8 encoded name for a specific $FILE_NAME attribute
2591
 * The returned size includes the end of string character
2592
 * Returns 1 if successful or -1 on error
2593
 */
2594
int libfsntfs_file_entry_get_utf8_name_size_by_attribute_index(
2595
     libfsntfs_file_entry_t *file_entry,
2596
     int attribute_index,
2597
     size_t *utf8_string_size,
2598
     libcerror_error_t **error )
2599
0
{
2600
0
  libfsntfs_attribute_t *attribute                     = NULL;
2601
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2602
0
  static char *function                                = "libfsntfs_file_entry_get_utf8_name_size_by_attribute_index";
2603
0
  int result                                           = 1;
2604
2605
0
  if( file_entry == NULL )
2606
0
  {
2607
0
    libcerror_error_set(
2608
0
     error,
2609
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2610
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2611
0
     "%s: invalid file entry.",
2612
0
     function );
2613
2614
0
    return( -1 );
2615
0
  }
2616
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2617
2618
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2619
0
  if( libcthreads_read_write_lock_grab_for_write(
2620
0
       internal_file_entry->read_write_lock,
2621
0
       error ) != 1 )
2622
0
  {
2623
0
    libcerror_error_set(
2624
0
     error,
2625
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2626
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2627
0
     "%s: unable to grab read/write lock for writing.",
2628
0
     function );
2629
2630
0
    return( -1 );
2631
0
  }
2632
0
#endif
2633
0
  if( libfsntfs_internal_file_entry_get_attribute_by_index(
2634
0
       internal_file_entry,
2635
0
       internal_file_entry->mft_entry,
2636
0
       attribute_index,
2637
0
       &attribute,
2638
0
       error ) != 1 )
2639
0
  {
2640
0
    libcerror_error_set(
2641
0
     error,
2642
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2643
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2644
0
     "%s: unable to retrieve attribute: %d.",
2645
0
     function,
2646
0
     attribute_index );
2647
2648
0
    result = -1;
2649
0
  }
2650
0
  else if( libfsntfs_file_name_attribute_get_utf8_name_size(
2651
0
            attribute,
2652
0
            utf8_string_size,
2653
0
            error ) != 1 )
2654
0
  {
2655
0
    libcerror_error_set(
2656
0
     error,
2657
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2658
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2659
0
     "%s: unable to retrieve size of UTF-8 name from $FILE_NAME attribute.",
2660
0
     function );
2661
2662
0
    result = -1;
2663
0
  }
2664
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2665
0
  if( libcthreads_read_write_lock_release_for_write(
2666
0
       internal_file_entry->read_write_lock,
2667
0
       error ) != 1 )
2668
0
  {
2669
0
    libcerror_error_set(
2670
0
     error,
2671
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2672
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2673
0
     "%s: unable to release read/write lock for writing.",
2674
0
     function );
2675
2676
0
    return( -1 );
2677
0
  }
2678
0
#endif
2679
0
  return( result );
2680
0
}
2681
2682
/* Retrieves the UTF-8 encoded name for a specific $FILE_NAME attribute
2683
 * This function uses UTF-8 RFC 2279 (or 6-byte UTF-8) to support characters outside Unicode
2684
 * The size should include the end of string character
2685
 * Returns 1 if successful or -1 on error
2686
 */
2687
int libfsntfs_file_entry_get_utf8_name_by_attribute_index(
2688
     libfsntfs_file_entry_t *file_entry,
2689
     int attribute_index,
2690
     uint8_t *utf8_string,
2691
     size_t utf8_string_size,
2692
     libcerror_error_t **error )
2693
0
{
2694
0
  libfsntfs_attribute_t *attribute                     = NULL;
2695
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2696
0
  static char *function                                = "libfsntfs_file_entry_get_utf8_name_by_attribute_index";
2697
0
  int result                                           = 1;
2698
2699
0
  if( file_entry == NULL )
2700
0
  {
2701
0
    libcerror_error_set(
2702
0
     error,
2703
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2704
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2705
0
     "%s: invalid file entry.",
2706
0
     function );
2707
2708
0
    return( -1 );
2709
0
  }
2710
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2711
2712
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2713
0
  if( libcthreads_read_write_lock_grab_for_write(
2714
0
       internal_file_entry->read_write_lock,
2715
0
       error ) != 1 )
2716
0
  {
2717
0
    libcerror_error_set(
2718
0
     error,
2719
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2720
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2721
0
     "%s: unable to grab read/write lock for writing.",
2722
0
     function );
2723
2724
0
    return( -1 );
2725
0
  }
2726
0
#endif
2727
0
  if( libfsntfs_internal_file_entry_get_attribute_by_index(
2728
0
       internal_file_entry,
2729
0
       internal_file_entry->mft_entry,
2730
0
       attribute_index,
2731
0
       &attribute,
2732
0
       error ) != 1 )
2733
0
  {
2734
0
    libcerror_error_set(
2735
0
     error,
2736
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2737
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2738
0
     "%s: unable to retrieve attribute: %d.",
2739
0
     function,
2740
0
     attribute_index );
2741
2742
0
    result = -1;
2743
0
  }
2744
0
  else if( libfsntfs_file_name_attribute_get_utf8_name(
2745
0
            attribute,
2746
0
            utf8_string,
2747
0
            utf8_string_size,
2748
0
            error ) != 1 )
2749
0
  {
2750
0
    libcerror_error_set(
2751
0
     error,
2752
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2753
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2754
0
     "%s: unable to retrieve UTF-8 name from $FILE_NAME attribute.",
2755
0
     function );
2756
2757
0
    result = -1;
2758
0
  }
2759
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2760
0
  if( libcthreads_read_write_lock_release_for_write(
2761
0
       internal_file_entry->read_write_lock,
2762
0
       error ) != 1 )
2763
0
  {
2764
0
    libcerror_error_set(
2765
0
     error,
2766
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2767
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2768
0
     "%s: unable to release read/write lock for writing.",
2769
0
     function );
2770
2771
0
    return( -1 );
2772
0
  }
2773
0
#endif
2774
0
  return( result );
2775
0
}
2776
2777
/* Retrieves the size of the UTF-16 encoded name for a specific $FILE_NAME attribute
2778
 * This function uses UCS-2 (with surrogates) to support characters outside Unicode
2779
 * The returned size includes the end of string character
2780
 * Returns 1 if successful or -1 on error
2781
 */
2782
int libfsntfs_file_entry_get_utf16_name_size_by_attribute_index(
2783
     libfsntfs_file_entry_t *file_entry,
2784
     int attribute_index,
2785
     size_t *utf16_string_size,
2786
     libcerror_error_t **error )
2787
0
{
2788
0
  libfsntfs_attribute_t *attribute                     = NULL;
2789
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2790
0
  static char *function                                = "libfsntfs_file_entry_get_utf16_name_size_by_attribute_index";
2791
0
  int result                                           = 1;
2792
2793
0
  if( file_entry == NULL )
2794
0
  {
2795
0
    libcerror_error_set(
2796
0
     error,
2797
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2798
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2799
0
     "%s: invalid file entry.",
2800
0
     function );
2801
2802
0
    return( -1 );
2803
0
  }
2804
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2805
2806
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2807
0
  if( libcthreads_read_write_lock_grab_for_write(
2808
0
       internal_file_entry->read_write_lock,
2809
0
       error ) != 1 )
2810
0
  {
2811
0
    libcerror_error_set(
2812
0
     error,
2813
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2814
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2815
0
     "%s: unable to grab read/write lock for writing.",
2816
0
     function );
2817
2818
0
    return( -1 );
2819
0
  }
2820
0
#endif
2821
0
  if( libfsntfs_internal_file_entry_get_attribute_by_index(
2822
0
       internal_file_entry,
2823
0
       internal_file_entry->mft_entry,
2824
0
       attribute_index,
2825
0
       &attribute,
2826
0
       error ) != 1 )
2827
0
  {
2828
0
    libcerror_error_set(
2829
0
     error,
2830
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2831
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2832
0
     "%s: unable to retrieve attribute: %d.",
2833
0
     function,
2834
0
     attribute_index );
2835
2836
0
    result = -1;
2837
0
  }
2838
0
  else if( libfsntfs_file_name_attribute_get_utf16_name_size(
2839
0
            attribute,
2840
0
            utf16_string_size,
2841
0
            error ) != 1 )
2842
0
  {
2843
0
    libcerror_error_set(
2844
0
     error,
2845
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2846
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2847
0
     "%s: unable to retrieve size of UTF-16 name from $FILE_NAME attribute.",
2848
0
     function );
2849
2850
0
    result = -1;
2851
0
  }
2852
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2853
0
  if( libcthreads_read_write_lock_release_for_write(
2854
0
       internal_file_entry->read_write_lock,
2855
0
       error ) != 1 )
2856
0
  {
2857
0
    libcerror_error_set(
2858
0
     error,
2859
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2860
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2861
0
     "%s: unable to release read/write lock for writing.",
2862
0
     function );
2863
2864
0
    return( -1 );
2865
0
  }
2866
0
#endif
2867
0
  return( result );
2868
0
}
2869
2870
/* Retrieves the UTF-16 encoded name for a specific $FILE_NAME attribute
2871
 * The size should include the end of string character
2872
 * Returns 1 if successful or -1 on error
2873
 */
2874
int libfsntfs_file_entry_get_utf16_name_by_attribute_index(
2875
     libfsntfs_file_entry_t *file_entry,
2876
     int attribute_index,
2877
     uint16_t *utf16_string,
2878
     size_t utf16_string_size,
2879
     libcerror_error_t **error )
2880
0
{
2881
0
  libfsntfs_attribute_t *attribute                     = NULL;
2882
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
2883
0
  static char *function                                = "libfsntfs_file_entry_get_utf16_name_by_attribute_index";
2884
0
  int result                                           = 1;
2885
2886
0
  if( file_entry == NULL )
2887
0
  {
2888
0
    libcerror_error_set(
2889
0
     error,
2890
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2891
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2892
0
     "%s: invalid file entry.",
2893
0
     function );
2894
2895
0
    return( -1 );
2896
0
  }
2897
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
2898
2899
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2900
0
  if( libcthreads_read_write_lock_grab_for_write(
2901
0
       internal_file_entry->read_write_lock,
2902
0
       error ) != 1 )
2903
0
  {
2904
0
    libcerror_error_set(
2905
0
     error,
2906
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2907
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2908
0
     "%s: unable to grab read/write lock for writing.",
2909
0
     function );
2910
2911
0
    return( -1 );
2912
0
  }
2913
0
#endif
2914
0
  if( libfsntfs_internal_file_entry_get_attribute_by_index(
2915
0
       internal_file_entry,
2916
0
       internal_file_entry->mft_entry,
2917
0
       attribute_index,
2918
0
       &attribute,
2919
0
       error ) != 1 )
2920
0
  {
2921
0
    libcerror_error_set(
2922
0
     error,
2923
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2924
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2925
0
     "%s: unable to retrieve attribute: %d.",
2926
0
     function,
2927
0
     attribute_index );
2928
2929
0
    result = -1;
2930
0
  }
2931
0
  else if( libfsntfs_file_name_attribute_get_utf16_name(
2932
0
            attribute,
2933
0
            utf16_string,
2934
0
            utf16_string_size,
2935
0
            error ) != 1 )
2936
0
  {
2937
0
    libcerror_error_set(
2938
0
     error,
2939
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2940
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2941
0
     "%s: unable to retrieve UTF-16 name from $FILE_NAME attribute.",
2942
0
     function );
2943
2944
0
    result = -1;
2945
0
  }
2946
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
2947
0
  if( libcthreads_read_write_lock_release_for_write(
2948
0
       internal_file_entry->read_write_lock,
2949
0
       error ) != 1 )
2950
0
  {
2951
0
    libcerror_error_set(
2952
0
     error,
2953
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2954
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2955
0
     "%s: unable to release read/write lock for writing.",
2956
0
     function );
2957
2958
0
    return( -1 );
2959
0
  }
2960
0
#endif
2961
0
  return( result );
2962
0
}
2963
2964
/* Retrieves the path hint for a specific $FILE_NAME attribute
2965
 * Returns 1 if successful or -1 on error
2966
 */
2967
int libfsntfs_internal_file_entry_get_path_hint(
2968
     libfsntfs_internal_file_entry_t *internal_file_entry,
2969
     int attribute_index,
2970
     libfsntfs_path_hint_t **path_hint,
2971
     libcerror_error_t **error )
2972
0
{
2973
0
  libfsntfs_attribute_t *attribute               = NULL;
2974
0
  libfsntfs_file_name_values_t *file_name_values = NULL;
2975
0
  libfsntfs_path_hint_t *parent_path_hint        = NULL;
2976
0
  libfsntfs_path_hint_t *safe_path_hint          = NULL;
2977
0
  uint8_t *parent_path                           = NULL;
2978
0
  static char *function                          = "libfsntfs_internal_file_entry_get_path_hint";
2979
0
  size_t name_size                               = 0;
2980
0
  size_t parent_path_size                        = 0;
2981
0
  uint64_t file_reference                        = 0;
2982
0
  uint64_t mft_entry_index                       = 0;
2983
0
  uint64_t parent_file_reference                 = 0;
2984
0
  uint64_t parent_mft_entry_index                = 0;
2985
0
  int result                                     = 0;
2986
2987
0
  if( internal_file_entry == NULL )
2988
0
  {
2989
0
    libcerror_error_set(
2990
0
     error,
2991
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2992
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2993
0
     "%s: invalid file entry.",
2994
0
     function );
2995
2996
0
    return( -1 );
2997
0
  }
2998
0
  if( path_hint == NULL )
2999
0
  {
3000
0
    libcerror_error_set(
3001
0
     error,
3002
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3003
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3004
0
     "%s: invalid path hint.",
3005
0
     function );
3006
3007
0
    return( -1 );
3008
0
  }
3009
/* TODO cache path hint in attribute */
3010
0
  if( libfsntfs_internal_file_entry_get_attribute_by_index(
3011
0
       internal_file_entry,
3012
0
       internal_file_entry->mft_entry,
3013
0
       attribute_index,
3014
0
       &attribute,
3015
0
       error ) != 1 )
3016
0
  {
3017
0
    libcerror_error_set(
3018
0
     error,
3019
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3020
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3021
0
     "%s: unable to retrieve attribute: %d.",
3022
0
     function,
3023
0
     attribute_index );
3024
3025
0
    goto on_error;
3026
0
  }
3027
0
  if( attribute == NULL )
3028
0
  {
3029
0
    libcerror_error_set(
3030
0
     error,
3031
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3032
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3033
0
     "%s: missing attribute?: %d.",
3034
0
     function,
3035
0
     attribute_index );
3036
3037
0
    goto on_error;
3038
0
  }
3039
0
  if( ( (libfsntfs_internal_attribute_t *) attribute )->path_hint == NULL )
3040
0
  {
3041
0
    if( libfsntfs_mft_entry_get_file_reference(
3042
0
         internal_file_entry->mft_entry,
3043
0
         &file_reference,
3044
0
         error ) != 1 )
3045
0
    {
3046
0
      libcerror_error_set(
3047
0
       error,
3048
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3049
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3050
0
       "%s: unable to retrieve file reference from MFT entry.",
3051
0
       function );
3052
3053
0
      goto on_error;
3054
0
    }
3055
0
    mft_entry_index = file_reference & 0xffffffffffffUL;
3056
3057
0
    if( libfsntfs_file_name_attribute_get_parent_file_reference(
3058
0
         attribute,
3059
0
         &parent_file_reference,
3060
0
         error ) != 1 )
3061
0
    {
3062
0
      libcerror_error_set(
3063
0
       error,
3064
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3065
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3066
0
       "%s: unable to retrieve parent reference from $FILE_NAME attribute.",
3067
0
       function );
3068
3069
0
      result = -1;
3070
0
    }
3071
0
    parent_mft_entry_index = parent_file_reference & 0xffffffffffffUL;
3072
3073
0
    parent_path      = NULL;
3074
0
    parent_path_size = 0;
3075
3076
0
    if( ( mft_entry_index != LIBFSNTFS_MFT_ENTRY_INDEX_ROOT_DIRECTORY )
3077
0
     && ( parent_mft_entry_index == LIBFSNTFS_MFT_ENTRY_INDEX_ROOT_DIRECTORY ) )
3078
0
    {
3079
0
      parent_path      = (uint8_t *) "";
3080
0
      parent_path_size = 1;
3081
0
    }
3082
0
    else if( ( parent_mft_entry_index != 0 )
3083
0
          && ( parent_mft_entry_index != mft_entry_index ) )
3084
0
    {
3085
0
      result = libfsntfs_file_system_get_path_hint(
3086
0
                internal_file_entry->file_system,
3087
0
                internal_file_entry->file_io_handle,
3088
0
                parent_file_reference,
3089
0
                &parent_path_hint,
3090
0
                0,
3091
0
                error );
3092
3093
0
      if( result == -1 )
3094
0
      {
3095
0
        libcerror_error_set(
3096
0
         error,
3097
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3098
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3099
0
         "%s: unable to retrieve path hint for MFT entry: %" PRIu64 ".",
3100
0
         function,
3101
0
         parent_mft_entry_index );
3102
3103
0
        goto on_error;
3104
0
      }
3105
0
      else if( result == 0 )
3106
0
      {
3107
0
        parent_path      = (uint8_t *) "$Orphan";
3108
0
        parent_path_size = 8;
3109
0
      }
3110
0
      else
3111
0
      {
3112
0
        parent_path      = parent_path_hint->path;
3113
0
        parent_path_size = parent_path_hint->path_size;
3114
0
      }
3115
0
    }
3116
0
    if( libfsntfs_file_name_attribute_get_utf8_name_size(
3117
0
         attribute,
3118
0
         &name_size,
3119
0
         error ) != 1 )
3120
0
    {
3121
0
      libcerror_error_set(
3122
0
       error,
3123
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3124
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3125
0
       "%s: unable to retrieve size of UTF-8 name from $FILE_NAME attribute.",
3126
0
       function );
3127
3128
0
      goto on_error;
3129
0
    }
3130
0
    if( libfsntfs_path_hint_initialize(
3131
0
         &safe_path_hint,
3132
0
         error ) != 1 )
3133
0
    {
3134
0
      libcerror_error_set(
3135
0
       error,
3136
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3137
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3138
0
       "%s: unable to create path hint.",
3139
0
       function );
3140
3141
0
      goto on_error;
3142
0
    }
3143
0
    safe_path_hint->file_reference = file_reference;
3144
0
    safe_path_hint->path_size      = parent_path_size + name_size;
3145
3146
0
    safe_path_hint->path = (uint8_t *) memory_allocate(
3147
0
                sizeof( uint8_t ) * safe_path_hint->path_size );
3148
3149
0
    if( safe_path_hint->path == NULL )
3150
0
    {
3151
0
      libcerror_error_set(
3152
0
       error,
3153
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
3154
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
3155
0
       "%s: unable to create path.",
3156
0
       function );
3157
3158
0
      goto on_error;
3159
0
    }
3160
0
    if( ( parent_path != NULL )
3161
0
     && ( parent_path_size > 0 ) )
3162
0
    {
3163
0
      if( memory_copy(
3164
0
           safe_path_hint->path,
3165
0
           parent_path,
3166
0
           parent_path_size ) == NULL )
3167
0
      {
3168
0
        libcerror_error_set(
3169
0
         error,
3170
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
3171
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
3172
0
         "%s: unable to copy parent path to path.",
3173
0
         function );
3174
3175
0
        goto on_error;
3176
0
      }
3177
0
      safe_path_hint->path[ parent_path_size - 1 ] = '\\';
3178
0
    }
3179
0
    if( name_size > 0 )
3180
0
    {
3181
0
      if( libfsntfs_file_name_attribute_get_utf8_name(
3182
0
           attribute,
3183
0
           &( safe_path_hint->path[ parent_path_size ] ),
3184
0
           name_size,
3185
0
           error ) != 1 )
3186
0
      {
3187
0
        libcerror_error_set(
3188
0
         error,
3189
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3190
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3191
0
         "%s: unable to retrieve UTF-8 name from $FILE_NAME attribute.",
3192
0
         function );
3193
3194
0
        goto on_error;
3195
0
      }
3196
0
    }
3197
0
    if( mft_entry_index == LIBFSNTFS_MFT_ENTRY_INDEX_ROOT_DIRECTORY )
3198
0
    {
3199
0
      safe_path_hint->path[ 0 ] = '\\';
3200
0
    }
3201
0
    ( (libfsntfs_internal_attribute_t *) attribute )->path_hint = safe_path_hint;
3202
0
  }
3203
0
  *path_hint = ( (libfsntfs_internal_attribute_t *) attribute )->path_hint;
3204
3205
0
  return( 1 );
3206
3207
0
on_error:
3208
0
  if( safe_path_hint != NULL )
3209
0
  {
3210
0
    libfsntfs_path_hint_free(
3211
0
     &safe_path_hint,
3212
0
     NULL );
3213
0
  }
3214
0
  if( file_name_values != NULL )
3215
0
  {
3216
0
    libfsntfs_file_name_values_free(
3217
0
     &file_name_values,
3218
0
     NULL );
3219
0
  }
3220
0
  return( -1 );
3221
0
}
3222
3223
/* Retrieves the size of the UTF-8 encoded path hint for a specific $FILE_NAME attribute
3224
 * The returned size includes the end of string character
3225
 * Returns 1 if successful, 0 if not available or -1 on error
3226
 */
3227
int libfsntfs_file_entry_get_utf8_path_hint_size(
3228
     libfsntfs_file_entry_t *file_entry,
3229
     int attribute_index,
3230
     size_t *utf8_string_size,
3231
     libcerror_error_t **error )
3232
0
{
3233
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
3234
0
  libfsntfs_path_hint_t *path_hint                     = NULL;
3235
0
  static char *function                                = "libfsntfs_file_entry_get_utf8_path_hint_size";
3236
0
  int result                                           = 1;
3237
3238
0
  if( file_entry == NULL )
3239
0
  {
3240
0
    libcerror_error_set(
3241
0
     error,
3242
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3243
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3244
0
     "%s: invalid file entry.",
3245
0
     function );
3246
3247
0
    return( -1 );
3248
0
  }
3249
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
3250
3251
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3252
0
  if( libcthreads_read_write_lock_grab_for_read(
3253
0
       internal_file_entry->read_write_lock,
3254
0
       error ) != 1 )
3255
0
  {
3256
0
    libcerror_error_set(
3257
0
     error,
3258
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3259
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3260
0
     "%s: unable to grab read/write lock for reading.",
3261
0
     function );
3262
3263
0
    return( -1 );
3264
0
  }
3265
0
#endif
3266
0
  if( libfsntfs_internal_file_entry_get_path_hint(
3267
0
       internal_file_entry,
3268
0
       attribute_index,
3269
0
       &path_hint,
3270
0
       error ) != 1 )
3271
0
  {
3272
0
    libcerror_error_set(
3273
0
     error,
3274
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3275
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3276
0
     "%s: unable to retrieve path hint.",
3277
0
     function );
3278
3279
0
    result = -1;
3280
0
  }
3281
0
  else
3282
0
  {
3283
0
    if( libfsntfs_path_hint_get_utf8_path_size(
3284
0
         path_hint,
3285
0
         utf8_string_size,
3286
0
         error ) != 1 )
3287
0
    {
3288
0
      libcerror_error_set(
3289
0
       error,
3290
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3291
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3292
0
       "%s: unable to retrieve size of UTF-8 path hint.",
3293
0
       function );
3294
3295
0
      result = -1;
3296
0
    }
3297
0
  }
3298
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3299
0
  if( libcthreads_read_write_lock_release_for_read(
3300
0
       internal_file_entry->read_write_lock,
3301
0
       error ) != 1 )
3302
0
  {
3303
0
    libcerror_error_set(
3304
0
     error,
3305
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3306
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3307
0
     "%s: unable to release read/write lock for reading.",
3308
0
     function );
3309
3310
0
    return( -1 );
3311
0
  }
3312
0
#endif
3313
0
  return( result );
3314
0
}
3315
3316
/* Retrieves the UTF-8 encoded path hint
3317
 * The size should include the end of string character
3318
 * Returns 1 if successful, 0 if not available or -1 on error
3319
 */
3320
int libfsntfs_file_entry_get_utf8_path_hint(
3321
     libfsntfs_file_entry_t *file_entry,
3322
     int attribute_index,
3323
     uint8_t *utf8_string,
3324
     size_t utf8_string_size,
3325
     libcerror_error_t **error )
3326
0
{
3327
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
3328
0
  libfsntfs_path_hint_t *path_hint                     = NULL;
3329
0
  static char *function                                = "libfsntfs_file_entry_get_utf8_path_hint";
3330
0
  int result                                           = 1;
3331
3332
0
  if( file_entry == NULL )
3333
0
  {
3334
0
    libcerror_error_set(
3335
0
     error,
3336
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3337
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3338
0
     "%s: invalid file entry.",
3339
0
     function );
3340
3341
0
    return( -1 );
3342
0
  }
3343
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
3344
3345
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3346
0
  if( libcthreads_read_write_lock_grab_for_read(
3347
0
       internal_file_entry->read_write_lock,
3348
0
       error ) != 1 )
3349
0
  {
3350
0
    libcerror_error_set(
3351
0
     error,
3352
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3353
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3354
0
     "%s: unable to grab read/write lock for reading.",
3355
0
     function );
3356
3357
0
    return( -1 );
3358
0
  }
3359
0
#endif
3360
0
  if( libfsntfs_internal_file_entry_get_path_hint(
3361
0
       internal_file_entry,
3362
0
       attribute_index,
3363
0
       &path_hint,
3364
0
       error ) != 1 )
3365
0
  {
3366
0
    libcerror_error_set(
3367
0
     error,
3368
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3369
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3370
0
     "%s: unable to retrieve path hint.",
3371
0
     function );
3372
3373
0
    result = -1;
3374
0
  }
3375
0
  else
3376
0
  {
3377
0
    if( libfsntfs_path_hint_get_utf8_path(
3378
0
         path_hint,
3379
0
         utf8_string,
3380
0
         utf8_string_size,
3381
0
         error ) != 1 )
3382
0
    {
3383
0
      libcerror_error_set(
3384
0
       error,
3385
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3386
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3387
0
       "%s: unable to retrieve UTF-8 path hint.",
3388
0
       function );
3389
3390
0
      result = -1;
3391
0
    }
3392
0
  }
3393
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3394
0
  if( libcthreads_read_write_lock_release_for_read(
3395
0
       internal_file_entry->read_write_lock,
3396
0
       error ) != 1 )
3397
0
  {
3398
0
    libcerror_error_set(
3399
0
     error,
3400
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3401
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3402
0
     "%s: unable to release read/write lock for reading.",
3403
0
     function );
3404
3405
0
    return( -1 );
3406
0
  }
3407
0
#endif
3408
0
  return( result );
3409
0
}
3410
3411
/* Retrieves the size of the UTF-16 encoded path hint for a specific $FILE_NAME attribute
3412
 * The returned size includes the end of string character
3413
 * Returns 1 if successful, 0 if not available or -1 on error
3414
 */
3415
int libfsntfs_file_entry_get_utf16_path_hint_size(
3416
     libfsntfs_file_entry_t *file_entry,
3417
     int attribute_index,
3418
     size_t *utf16_string_size,
3419
     libcerror_error_t **error )
3420
0
{
3421
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
3422
0
  libfsntfs_path_hint_t *path_hint                     = NULL;
3423
0
  static char *function                                = "libfsntfs_file_entry_get_utf16_path_hint_size";
3424
0
  int result                                           = 1;
3425
3426
0
  if( file_entry == NULL )
3427
0
  {
3428
0
    libcerror_error_set(
3429
0
     error,
3430
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3431
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3432
0
     "%s: invalid file entry.",
3433
0
     function );
3434
3435
0
    return( -1 );
3436
0
  }
3437
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
3438
3439
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3440
0
  if( libcthreads_read_write_lock_grab_for_read(
3441
0
       internal_file_entry->read_write_lock,
3442
0
       error ) != 1 )
3443
0
  {
3444
0
    libcerror_error_set(
3445
0
     error,
3446
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3447
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3448
0
     "%s: unable to grab read/write lock for reading.",
3449
0
     function );
3450
3451
0
    return( -1 );
3452
0
  }
3453
0
#endif
3454
0
  if( libfsntfs_internal_file_entry_get_path_hint(
3455
0
       internal_file_entry,
3456
0
       attribute_index,
3457
0
       &path_hint,
3458
0
       error ) != 1 )
3459
0
  {
3460
0
    libcerror_error_set(
3461
0
     error,
3462
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3463
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3464
0
     "%s: unable to retrieve path hint.",
3465
0
     function );
3466
3467
0
    result = -1;
3468
0
  }
3469
0
  else
3470
0
  {
3471
0
    if( libfsntfs_path_hint_get_utf16_path_size(
3472
0
         path_hint,
3473
0
         utf16_string_size,
3474
0
         error ) != 1 )
3475
0
    {
3476
0
      libcerror_error_set(
3477
0
       error,
3478
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3479
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3480
0
       "%s: unable to retrieve size of UTF-16 path hint.",
3481
0
       function );
3482
3483
0
      result = -1;
3484
0
    }
3485
0
  }
3486
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3487
0
  if( libcthreads_read_write_lock_release_for_read(
3488
0
       internal_file_entry->read_write_lock,
3489
0
       error ) != 1 )
3490
0
  {
3491
0
    libcerror_error_set(
3492
0
     error,
3493
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3494
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3495
0
     "%s: unable to release read/write lock for reading.",
3496
0
     function );
3497
3498
0
    return( -1 );
3499
0
  }
3500
0
#endif
3501
0
  return( result );
3502
0
}
3503
3504
/* Retrieves the UTF-16 encoded path hint
3505
 * The size should include the end of string character
3506
 * Returns 1 if successful, 0 if not available or -1 on error
3507
 */
3508
int libfsntfs_file_entry_get_utf16_path_hint(
3509
     libfsntfs_file_entry_t *file_entry,
3510
     int attribute_index,
3511
     uint16_t *utf16_string,
3512
     size_t utf16_string_size,
3513
     libcerror_error_t **error )
3514
0
{
3515
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
3516
0
  libfsntfs_path_hint_t *path_hint                     = NULL;
3517
0
  static char *function                                = "libfsntfs_file_entry_get_utf16_path_hint";
3518
0
  int result                                           = 1;
3519
3520
0
  if( file_entry == NULL )
3521
0
  {
3522
0
    libcerror_error_set(
3523
0
     error,
3524
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3525
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3526
0
     "%s: invalid file entry.",
3527
0
     function );
3528
3529
0
    return( -1 );
3530
0
  }
3531
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
3532
3533
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3534
0
  if( libcthreads_read_write_lock_grab_for_read(
3535
0
       internal_file_entry->read_write_lock,
3536
0
       error ) != 1 )
3537
0
  {
3538
0
    libcerror_error_set(
3539
0
     error,
3540
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3541
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3542
0
     "%s: unable to grab read/write lock for reading.",
3543
0
     function );
3544
3545
0
    return( -1 );
3546
0
  }
3547
0
#endif
3548
0
  if( libfsntfs_internal_file_entry_get_path_hint(
3549
0
       internal_file_entry,
3550
0
       attribute_index,
3551
0
       &path_hint,
3552
0
       error ) != 1 )
3553
0
  {
3554
0
    libcerror_error_set(
3555
0
     error,
3556
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3557
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3558
0
     "%s: unable to retrieve path hint.",
3559
0
     function );
3560
3561
0
    result = -1;
3562
0
  }
3563
0
  else
3564
0
  {
3565
0
    if( libfsntfs_path_hint_get_utf16_path(
3566
0
         path_hint,
3567
0
         utf16_string,
3568
0
         utf16_string_size,
3569
0
         error ) != 1 )
3570
0
    {
3571
0
      libcerror_error_set(
3572
0
       error,
3573
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3574
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3575
0
       "%s: unable to retrieve UTF-16 path hint.",
3576
0
       function );
3577
3578
0
      result = -1;
3579
0
    }
3580
0
  }
3581
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3582
0
  if( libcthreads_read_write_lock_release_for_read(
3583
0
       internal_file_entry->read_write_lock,
3584
0
       error ) != 1 )
3585
0
  {
3586
0
    libcerror_error_set(
3587
0
     error,
3588
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3589
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3590
0
     "%s: unable to release read/write lock for reading.",
3591
0
     function );
3592
3593
0
    return( -1 );
3594
0
  }
3595
0
#endif
3596
0
  return( result );
3597
0
}
3598
3599
/* Retrieves the size of the UTF-8 encoded symbolic link target
3600
 * The returned size includes the end of string character
3601
 * This value is retrieved from a symbolic link $REPARSE_POINT attribute
3602
 * Returns 1 if successful, 0 if not available or -1 on error
3603
 */
3604
int libfsntfs_file_entry_get_utf8_symbolic_link_target_size(
3605
     libfsntfs_file_entry_t *file_entry,
3606
     size_t *utf8_string_size,
3607
     libcerror_error_t **error )
3608
0
{
3609
0
  libfsntfs_attribute_t *reparse_point_attribute       = NULL;
3610
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
3611
0
  static char *function                                = "libfsntfs_file_entry_get_utf8_symbolic_link_target_size";
3612
0
  int result                                           = 0;
3613
3614
0
  if( file_entry == NULL )
3615
0
  {
3616
0
    libcerror_error_set(
3617
0
     error,
3618
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3619
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3620
0
     "%s: invalid file entry.",
3621
0
     function );
3622
3623
0
    return( -1 );
3624
0
  }
3625
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
3626
3627
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3628
0
  if( libcthreads_read_write_lock_grab_for_write(
3629
0
       internal_file_entry->read_write_lock,
3630
0
       error ) != 1 )
3631
0
  {
3632
0
    libcerror_error_set(
3633
0
     error,
3634
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3635
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3636
0
     "%s: unable to grab read/write lock for writing.",
3637
0
     function );
3638
3639
0
    return( -1 );
3640
0
  }
3641
0
#endif
3642
0
  result = libfsntfs_internal_file_entry_get_reparse_point_attribute(
3643
0
            internal_file_entry,
3644
0
            internal_file_entry->mft_entry,
3645
0
            &reparse_point_attribute,
3646
0
            error );
3647
3648
0
  if( result == -1 )
3649
0
  {
3650
0
    libcerror_error_set(
3651
0
     error,
3652
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3653
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3654
0
     "%s: unable to retrieve reparse point attribute.",
3655
0
     function );
3656
3657
0
    result = -1;
3658
0
  }
3659
0
  else if( result != 0 )
3660
0
  {
3661
0
    result = libfsntfs_reparse_point_attribute_get_utf8_substitute_name_size(
3662
0
              reparse_point_attribute,
3663
0
              utf8_string_size,
3664
0
              error );
3665
3666
0
    if( result == -1 )
3667
0
    {
3668
0
      libcerror_error_set(
3669
0
       error,
3670
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3671
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3672
0
       "%s: unable to retrieve size of UTF-8 substitute name from reparse point attribute.",
3673
0
       function );
3674
3675
0
      result = -1;
3676
0
    }
3677
0
  }
3678
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3679
0
  if( libcthreads_read_write_lock_release_for_write(
3680
0
       internal_file_entry->read_write_lock,
3681
0
       error ) != 1 )
3682
0
  {
3683
0
    libcerror_error_set(
3684
0
     error,
3685
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3686
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3687
0
     "%s: unable to release read/write lock for writing.",
3688
0
     function );
3689
3690
0
    return( -1 );
3691
0
  }
3692
0
#endif
3693
0
  return( result );
3694
0
}
3695
3696
/* Retrieves the UTF-8 encoded symbolic link target
3697
 * The size should include the end of string character
3698
 * This value is retrieved from a symbolic link $REPARSE_POINT attribute
3699
 * Returns 1 if successful, 0 if not available or -1 on error
3700
 */
3701
int libfsntfs_file_entry_get_utf8_symbolic_link_target(
3702
     libfsntfs_file_entry_t *file_entry,
3703
     uint8_t *utf8_string,
3704
     size_t utf8_string_size,
3705
     libcerror_error_t **error )
3706
0
{
3707
0
  libfsntfs_attribute_t *reparse_point_attribute       = NULL;
3708
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
3709
0
  static char *function                                = "libfsntfs_file_entry_get_utf8_symbolic_link_target";
3710
0
  int result                                           = 0;
3711
3712
0
  if( file_entry == NULL )
3713
0
  {
3714
0
    libcerror_error_set(
3715
0
     error,
3716
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3717
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3718
0
     "%s: invalid file entry.",
3719
0
     function );
3720
3721
0
    return( -1 );
3722
0
  }
3723
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
3724
3725
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3726
0
  if( libcthreads_read_write_lock_grab_for_write(
3727
0
       internal_file_entry->read_write_lock,
3728
0
       error ) != 1 )
3729
0
  {
3730
0
    libcerror_error_set(
3731
0
     error,
3732
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3733
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3734
0
     "%s: unable to grab read/write lock for writing.",
3735
0
     function );
3736
3737
0
    return( -1 );
3738
0
  }
3739
0
#endif
3740
0
  result = libfsntfs_internal_file_entry_get_reparse_point_attribute(
3741
0
            internal_file_entry,
3742
0
            internal_file_entry->mft_entry,
3743
0
            &reparse_point_attribute,
3744
0
            error );
3745
3746
0
  if( result == -1 )
3747
0
  {
3748
0
    libcerror_error_set(
3749
0
     error,
3750
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3751
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3752
0
     "%s: unable to retrieve reparse point attribute.",
3753
0
     function );
3754
3755
0
    result = -1;
3756
0
  }
3757
0
  else if( result != 0 )
3758
0
  {
3759
0
    result = libfsntfs_reparse_point_attribute_get_utf8_substitute_name(
3760
0
              reparse_point_attribute,
3761
0
              utf8_string,
3762
0
              utf8_string_size,
3763
0
              error );
3764
3765
0
    if( result == -1 )
3766
0
    {
3767
0
      libcerror_error_set(
3768
0
       error,
3769
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3770
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3771
0
       "%s: unable to retrieve UTF-8 substitute name from reparse point attribute.",
3772
0
       function );
3773
3774
0
      result = -1;
3775
0
    }
3776
0
  }
3777
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3778
0
  if( libcthreads_read_write_lock_release_for_write(
3779
0
       internal_file_entry->read_write_lock,
3780
0
       error ) != 1 )
3781
0
  {
3782
0
    libcerror_error_set(
3783
0
     error,
3784
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3785
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3786
0
     "%s: unable to release read/write lock for writing.",
3787
0
     function );
3788
3789
0
    return( -1 );
3790
0
  }
3791
0
#endif
3792
0
  return( result );
3793
0
}
3794
3795
/* Retrieves the size of the UTF-16 encoded symbolic link target
3796
 * The returned size includes the end of string character
3797
 * This value is retrieved from a symbolic link $REPARSE_POINT attribute
3798
 * Returns 1 if successful, 0 if not available or -1 on error
3799
 */
3800
int libfsntfs_file_entry_get_utf16_symbolic_link_target_size(
3801
     libfsntfs_file_entry_t *file_entry,
3802
     size_t *utf16_string_size,
3803
     libcerror_error_t **error )
3804
0
{
3805
0
  libfsntfs_attribute_t *reparse_point_attribute       = NULL;
3806
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
3807
0
  static char *function                                = "libfsntfs_file_entry_get_utf16_symbolic_link_target_size";
3808
0
  int result                                           = 0;
3809
3810
0
  if( file_entry == NULL )
3811
0
  {
3812
0
    libcerror_error_set(
3813
0
     error,
3814
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3815
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3816
0
     "%s: invalid file entry.",
3817
0
     function );
3818
3819
0
    return( -1 );
3820
0
  }
3821
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
3822
3823
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3824
0
  if( libcthreads_read_write_lock_grab_for_write(
3825
0
       internal_file_entry->read_write_lock,
3826
0
       error ) != 1 )
3827
0
  {
3828
0
    libcerror_error_set(
3829
0
     error,
3830
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3831
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3832
0
     "%s: unable to grab read/write lock for writing.",
3833
0
     function );
3834
3835
0
    return( -1 );
3836
0
  }
3837
0
#endif
3838
0
  result = libfsntfs_internal_file_entry_get_reparse_point_attribute(
3839
0
            internal_file_entry,
3840
0
            internal_file_entry->mft_entry,
3841
0
            &reparse_point_attribute,
3842
0
            error );
3843
3844
0
  if( result == -1 )
3845
0
  {
3846
0
    libcerror_error_set(
3847
0
     error,
3848
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3849
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3850
0
     "%s: unable to retrieve reparse point attribute.",
3851
0
     function );
3852
3853
0
    result = -1;
3854
0
  }
3855
0
  else if( result != 0 )
3856
0
  {
3857
0
    result = libfsntfs_reparse_point_attribute_get_utf16_substitute_name_size(
3858
0
              reparse_point_attribute,
3859
0
              utf16_string_size,
3860
0
              error );
3861
3862
0
    if( result == -1 )
3863
0
    {
3864
0
      libcerror_error_set(
3865
0
       error,
3866
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3867
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3868
0
       "%s: unable to retrieve size of UTF-16 substitute name from reparse point attribute.",
3869
0
       function );
3870
3871
0
      result = -1;
3872
0
    }
3873
0
  }
3874
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3875
0
  if( libcthreads_read_write_lock_release_for_write(
3876
0
       internal_file_entry->read_write_lock,
3877
0
       error ) != 1 )
3878
0
  {
3879
0
    libcerror_error_set(
3880
0
     error,
3881
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3882
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3883
0
     "%s: unable to release read/write lock for writing.",
3884
0
     function );
3885
3886
0
    return( -1 );
3887
0
  }
3888
0
#endif
3889
0
  return( result );
3890
0
}
3891
3892
/* Retrieves the UTF-16 encoded symbolic link target
3893
 * The size should include the end of string character
3894
 * This value is retrieved from a symbolic link $REPARSE_POINT attribute
3895
 * Returns 1 if successful, 0 if not available or -1 on error
3896
 */
3897
int libfsntfs_file_entry_get_utf16_symbolic_link_target(
3898
     libfsntfs_file_entry_t *file_entry,
3899
     uint16_t *utf16_string,
3900
     size_t utf16_string_size,
3901
     libcerror_error_t **error )
3902
0
{
3903
0
  libfsntfs_attribute_t *reparse_point_attribute       = NULL;
3904
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
3905
0
  static char *function                                = "libfsntfs_file_entry_get_utf16_symbolic_link_target";
3906
0
  int result                                           = 0;
3907
3908
0
  if( file_entry == NULL )
3909
0
  {
3910
0
    libcerror_error_set(
3911
0
     error,
3912
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3913
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3914
0
     "%s: invalid file entry.",
3915
0
     function );
3916
3917
0
    return( -1 );
3918
0
  }
3919
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
3920
3921
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3922
0
  if( libcthreads_read_write_lock_grab_for_write(
3923
0
       internal_file_entry->read_write_lock,
3924
0
       error ) != 1 )
3925
0
  {
3926
0
    libcerror_error_set(
3927
0
     error,
3928
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3929
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3930
0
     "%s: unable to grab read/write lock for writing.",
3931
0
     function );
3932
3933
0
    return( -1 );
3934
0
  }
3935
0
#endif
3936
0
  result = libfsntfs_internal_file_entry_get_reparse_point_attribute(
3937
0
            internal_file_entry,
3938
0
            internal_file_entry->mft_entry,
3939
0
            &reparse_point_attribute,
3940
0
            error );
3941
3942
0
  if( result == -1 )
3943
0
  {
3944
0
    libcerror_error_set(
3945
0
     error,
3946
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3947
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3948
0
     "%s: unable to retrieve reparse point attribute.",
3949
0
     function );
3950
3951
0
    result = -1;
3952
0
  }
3953
0
  else if( result != 0 )
3954
0
  {
3955
0
    result = libfsntfs_reparse_point_attribute_get_utf16_substitute_name(
3956
0
              reparse_point_attribute,
3957
0
              utf16_string,
3958
0
              utf16_string_size,
3959
0
              error );
3960
3961
0
    if( result == -1 )
3962
0
    {
3963
0
      libcerror_error_set(
3964
0
       error,
3965
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3966
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3967
0
       "%s: unable to retrieve UTF-16 substitute name from reparse point attribute.",
3968
0
       function );
3969
3970
0
      result = -1;
3971
0
    }
3972
0
  }
3973
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
3974
0
  if( libcthreads_read_write_lock_release_for_write(
3975
0
       internal_file_entry->read_write_lock,
3976
0
       error ) != 1 )
3977
0
  {
3978
0
    libcerror_error_set(
3979
0
     error,
3980
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3981
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3982
0
     "%s: unable to release read/write lock for writing.",
3983
0
     function );
3984
3985
0
    return( -1 );
3986
0
  }
3987
0
#endif
3988
0
  return( result );
3989
0
}
3990
3991
/* Retrieves the security descriptor (data) size
3992
 * Returns 1 if successful, 0 if not available or -1 on error
3993
 */
3994
int libfsntfs_file_entry_get_security_descriptor_size(
3995
     libfsntfs_file_entry_t *file_entry,
3996
     size_t *data_size,
3997
     libcerror_error_t **error )
3998
0
{
3999
0
  libfsntfs_attribute_t *security_descriptor_attribute                 = NULL;
4000
0
  libfsntfs_attribute_t *standard_information_attribute                = NULL;
4001
0
  libfsntfs_internal_file_entry_t *internal_file_entry                 = NULL;
4002
0
  libfsntfs_security_descriptor_values_t *security_descriptor_values   = NULL;
4003
0
  libfsntfs_standard_information_values_t *standard_information_values = NULL;
4004
0
  static char *function                                                = "libfsntfs_file_entry_get_security_descriptor_size";
4005
0
  uint32_t security_descriptor_identifier                              = 0;
4006
0
  int result                                                           = 0;
4007
4008
0
  if( file_entry == NULL )
4009
0
  {
4010
0
    libcerror_error_set(
4011
0
     error,
4012
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4013
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4014
0
     "%s: invalid file entry.",
4015
0
     function );
4016
4017
0
    return( -1 );
4018
0
  }
4019
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
4020
4021
/* TODO add thread lock suport */
4022
4023
0
  result = libfsntfs_internal_file_entry_get_security_descriptor_attribute(
4024
0
            internal_file_entry,
4025
0
            &security_descriptor_attribute,
4026
0
            error );
4027
4028
0
  if( result == -1 )
4029
0
  {
4030
0
    libcerror_error_set(
4031
0
     error,
4032
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4033
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4034
0
     "%s: unable to retrieve security descriptor attribute.",
4035
0
     function );
4036
4037
0
    return( -1 );
4038
0
  }
4039
0
  else if( result != 0 )
4040
0
  {
4041
0
    if( libfsntfs_internal_attribute_get_value(
4042
0
         (libfsntfs_internal_attribute_t *) security_descriptor_attribute,
4043
0
         (intptr_t **) &security_descriptor_values,
4044
0
         error ) != 1 )
4045
0
    {
4046
0
      libcerror_error_set(
4047
0
       error,
4048
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4049
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4050
0
       "%s: unable to retrieve security descriptor attribute value.",
4051
0
       function );
4052
4053
0
      goto on_error;
4054
0
    }
4055
0
  }
4056
0
  else
4057
0
  {
4058
0
    result = libfsntfs_internal_file_entry_get_standard_information_attribute(
4059
0
              internal_file_entry,
4060
0
              &standard_information_attribute,
4061
0
              error );
4062
4063
0
    if( result == -1 )
4064
0
    {
4065
0
      libcerror_error_set(
4066
0
       error,
4067
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4068
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4069
0
       "%s: unable to retrieve standard information attribute.",
4070
0
       function );
4071
4072
0
      return( -1 );
4073
0
    }
4074
0
    else if( result == 0 )
4075
0
    {
4076
0
      return( 0 );
4077
0
    }
4078
0
    if( internal_file_entry->security_descriptor_values == NULL )
4079
0
    {
4080
0
      if( libfsntfs_internal_attribute_get_value(
4081
0
           (libfsntfs_internal_attribute_t *) standard_information_attribute,
4082
0
           (intptr_t **) &standard_information_values,
4083
0
           error ) != 1 )
4084
0
      {
4085
0
        libcerror_error_set(
4086
0
         error,
4087
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4088
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4089
0
         "%s: unable to retrieve standard information attribute value.",
4090
0
         function );
4091
4092
0
        goto on_error;
4093
0
      }
4094
0
      if( libfsntfs_standard_information_values_get_security_descriptor_identifier(
4095
0
           standard_information_values,
4096
0
           &security_descriptor_identifier,
4097
0
           error ) != 1 )
4098
0
      {
4099
0
        libcerror_error_set(
4100
0
         error,
4101
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4102
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4103
0
         "%s: unable to retrieve security descriptor identifier from standard information attribute.",
4104
0
         function );
4105
4106
0
        goto on_error;
4107
0
      }
4108
0
      result = libfsntfs_file_system_get_security_descriptor_values_by_identifier(
4109
0
                internal_file_entry->file_system,
4110
0
                internal_file_entry->file_io_handle,
4111
0
                security_descriptor_identifier,
4112
0
                &( internal_file_entry->security_descriptor_values ),
4113
0
                error );
4114
4115
0
      if( result == -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 security descriptor from index for identifier: %" PRIu32 ".",
4122
0
         function,
4123
0
         security_descriptor_identifier );
4124
4125
0
        goto on_error;
4126
0
      }
4127
0
      else if( result == 0 )
4128
0
      {
4129
0
        return( 0 );
4130
0
      }
4131
      /* file_entry takes over management of security_descriptor_values
4132
       */
4133
0
    }
4134
0
    security_descriptor_values = internal_file_entry->security_descriptor_values;
4135
0
  }
4136
0
  result = libfsntfs_security_descriptor_values_get_data_size(
4137
0
            security_descriptor_values,
4138
0
            data_size,
4139
0
            error );
4140
4141
0
  if( result == -1 )
4142
0
  {
4143
0
    libcerror_error_set(
4144
0
     error,
4145
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4146
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4147
0
     "%s: unable to retrieve security descriptor data size.",
4148
0
     function );
4149
4150
0
    goto on_error;
4151
0
  }
4152
0
  return( result );
4153
4154
0
on_error:
4155
0
  if( internal_file_entry->security_descriptor_values != NULL )
4156
0
  {
4157
0
    libfsntfs_security_descriptor_values_free(
4158
0
     &( internal_file_entry->security_descriptor_values ),
4159
0
     NULL );
4160
0
  }
4161
0
  return( -1 );
4162
0
}
4163
4164
/* Retrieves the security descriptor (data)
4165
 * Returns 1 if successful, 0 if not available or -1 on error
4166
 */
4167
int libfsntfs_file_entry_get_security_descriptor(
4168
     libfsntfs_file_entry_t *file_entry,
4169
     uint8_t *data,
4170
     size_t data_size,
4171
     libcerror_error_t **error )
4172
0
{
4173
0
  libfsntfs_attribute_t *security_descriptor_attribute                 = NULL;
4174
0
  libfsntfs_attribute_t *standard_information_attribute                = NULL;
4175
0
  libfsntfs_internal_file_entry_t *internal_file_entry                 = NULL;
4176
0
  libfsntfs_security_descriptor_values_t *security_descriptor_values   = NULL;
4177
0
  libfsntfs_standard_information_values_t *standard_information_values = NULL;
4178
0
  static char *function                                                = "libfsntfs_file_entry_get_security_descriptor";
4179
0
  uint32_t security_descriptor_identifier                              = 0;
4180
0
  int result                                                           = 0;
4181
4182
0
  if( file_entry == NULL )
4183
0
  {
4184
0
    libcerror_error_set(
4185
0
     error,
4186
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4187
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4188
0
     "%s: invalid file entry.",
4189
0
     function );
4190
4191
0
    return( -1 );
4192
0
  }
4193
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
4194
4195
/* TODO add thread lock suport */
4196
4197
0
  result = libfsntfs_internal_file_entry_get_security_descriptor_attribute(
4198
0
            internal_file_entry,
4199
0
            &security_descriptor_attribute,
4200
0
            error );
4201
4202
0
  if( result == -1 )
4203
0
  {
4204
0
    libcerror_error_set(
4205
0
     error,
4206
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4207
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4208
0
     "%s: unable to retrieve security descriptor attribute.",
4209
0
     function );
4210
4211
0
    return( -1 );
4212
0
  }
4213
0
  else if( result != 0 )
4214
0
  {
4215
0
    if( libfsntfs_internal_attribute_get_value(
4216
0
         (libfsntfs_internal_attribute_t *) security_descriptor_attribute,
4217
0
         (intptr_t **) &security_descriptor_values,
4218
0
         error ) != 1 )
4219
0
    {
4220
0
      libcerror_error_set(
4221
0
       error,
4222
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4223
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4224
0
       "%s: unable to retrieve security descriptor attribute value.",
4225
0
       function );
4226
4227
0
      goto on_error;
4228
0
    }
4229
0
  }
4230
0
  else
4231
0
  {
4232
0
    result = libfsntfs_internal_file_entry_get_standard_information_attribute(
4233
0
              internal_file_entry,
4234
0
              &standard_information_attribute,
4235
0
              error );
4236
4237
0
    if( result == -1 )
4238
0
    {
4239
0
      libcerror_error_set(
4240
0
       error,
4241
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4242
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4243
0
       "%s: unable to retrieve standard information attribute.",
4244
0
       function );
4245
4246
0
      return( -1 );
4247
0
    }
4248
0
    else if( result == 0 )
4249
0
    {
4250
0
      return( 0 );
4251
0
    }
4252
0
    if( internal_file_entry->security_descriptor_values == NULL )
4253
0
    {
4254
0
      if( libfsntfs_internal_attribute_get_value(
4255
0
           (libfsntfs_internal_attribute_t *) standard_information_attribute,
4256
0
           (intptr_t **) &standard_information_values,
4257
0
           error ) != 1 )
4258
0
      {
4259
0
        libcerror_error_set(
4260
0
         error,
4261
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4262
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4263
0
         "%s: unable to retrieve standard information attribute value.",
4264
0
         function );
4265
4266
0
        goto on_error;
4267
0
      }
4268
0
      if( libfsntfs_standard_information_values_get_security_descriptor_identifier(
4269
0
           standard_information_values,
4270
0
           &security_descriptor_identifier,
4271
0
           error ) != 1 )
4272
0
      {
4273
0
        libcerror_error_set(
4274
0
         error,
4275
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4276
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4277
0
         "%s: unable to retrieve security descriptor identifier from standard information attribute.",
4278
0
         function );
4279
4280
0
        goto on_error;
4281
0
      }
4282
0
      result = libfsntfs_file_system_get_security_descriptor_values_by_identifier(
4283
0
                internal_file_entry->file_system,
4284
0
                internal_file_entry->file_io_handle,
4285
0
                security_descriptor_identifier,
4286
0
                &( internal_file_entry->security_descriptor_values ),
4287
0
                error );
4288
4289
0
      if( result == -1 )
4290
0
      {
4291
0
        libcerror_error_set(
4292
0
         error,
4293
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4294
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4295
0
         "%s: unable to retrieve security descriptor from index for identifier: %" PRIu32 ".",
4296
0
         function,
4297
0
         security_descriptor_identifier );
4298
4299
0
        goto on_error;
4300
0
      }
4301
0
      else if( result == 0 )
4302
0
      {
4303
0
        return( 0 );
4304
0
      }
4305
      /* file_entry takes over management of security_descriptor_values
4306
       */
4307
0
    }
4308
0
    security_descriptor_values = internal_file_entry->security_descriptor_values;
4309
0
  }
4310
0
  result = libfsntfs_security_descriptor_values_get_data(
4311
0
            security_descriptor_values,
4312
0
            data,
4313
0
            data_size,
4314
0
            error );
4315
4316
0
  if( result == -1 )
4317
0
  {
4318
0
    libcerror_error_set(
4319
0
     error,
4320
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4321
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4322
0
     "%s: unable to retrieve security descriptor data.",
4323
0
     function );
4324
4325
0
    goto on_error;
4326
0
  }
4327
0
  return( result );
4328
4329
0
on_error:
4330
0
  if( internal_file_entry->security_descriptor_values != NULL )
4331
0
  {
4332
0
    libfsntfs_security_descriptor_values_free(
4333
0
     &( internal_file_entry->security_descriptor_values ),
4334
0
     NULL );
4335
0
  }
4336
0
  return( -1 );
4337
0
}
4338
4339
/* Retrieves the number of attributes
4340
 * Returns 1 if successful or -1 on error
4341
 */
4342
int libfsntfs_file_entry_get_number_of_attributes(
4343
     libfsntfs_file_entry_t *file_entry,
4344
     int *number_of_attributes,
4345
     libcerror_error_t **error )
4346
0
{
4347
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
4348
0
  static char *function                                = "libfsntfs_file_entry_get_number_of_attributes";
4349
0
  int result                                           = 1;
4350
4351
0
  if( file_entry == NULL )
4352
0
  {
4353
0
    libcerror_error_set(
4354
0
     error,
4355
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4356
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4357
0
     "%s: invalid file entry.",
4358
0
     function );
4359
4360
0
    return( -1 );
4361
0
  }
4362
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
4363
4364
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4365
0
  if( libcthreads_read_write_lock_grab_for_read(
4366
0
       internal_file_entry->read_write_lock,
4367
0
       error ) != 1 )
4368
0
  {
4369
0
    libcerror_error_set(
4370
0
     error,
4371
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4372
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4373
0
     "%s: unable to grab read/write lock for reading.",
4374
0
     function );
4375
4376
0
    return( -1 );
4377
0
  }
4378
0
#endif
4379
0
  if( libfsntfs_mft_entry_get_number_of_attributes(
4380
0
       internal_file_entry->mft_entry,
4381
0
       number_of_attributes,
4382
0
       error ) != 1 )
4383
0
  {
4384
0
    libcerror_error_set(
4385
0
     error,
4386
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4387
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4388
0
     "%s: unable to retrieve number of attributes.",
4389
0
     function );
4390
4391
0
    result = -1;
4392
0
  }
4393
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4394
0
  if( libcthreads_read_write_lock_release_for_read(
4395
0
       internal_file_entry->read_write_lock,
4396
0
       error ) != 1 )
4397
0
  {
4398
0
    libcerror_error_set(
4399
0
     error,
4400
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4401
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4402
0
     "%s: unable to release read/write lock for reading.",
4403
0
     function );
4404
4405
0
    return( -1 );
4406
0
  }
4407
0
#endif
4408
0
  return( result );
4409
0
}
4410
4411
/* Retrieves the attribute for the specific index
4412
 * Returns 1 if successful or -1 on error
4413
 */
4414
int libfsntfs_file_entry_get_attribute_by_index(
4415
     libfsntfs_file_entry_t *file_entry,
4416
     int attribute_index,
4417
     libfsntfs_attribute_t **attribute,
4418
     libcerror_error_t **error )
4419
0
{
4420
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
4421
0
  static char *function                                = "libfsntfs_file_entry_get_attribute_by_index";
4422
0
  int result                                           = 1;
4423
4424
0
  if( file_entry == NULL )
4425
0
  {
4426
0
    libcerror_error_set(
4427
0
     error,
4428
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4429
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4430
0
     "%s: invalid file entry.",
4431
0
     function );
4432
4433
0
    return( -1 );
4434
0
  }
4435
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
4436
4437
0
  if( attribute == NULL )
4438
0
  {
4439
0
    libcerror_error_set(
4440
0
     error,
4441
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4442
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4443
0
     "%s: invalid attribute.",
4444
0
     function );
4445
4446
0
    return( -1 );
4447
0
  }
4448
0
  if( *attribute != NULL )
4449
0
  {
4450
0
    libcerror_error_set(
4451
0
     error,
4452
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4453
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
4454
0
     "%s: invalid attribute value already set.",
4455
0
     function );
4456
4457
0
    return( -1 );
4458
0
  }
4459
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4460
0
  if( libcthreads_read_write_lock_grab_for_write(
4461
0
       internal_file_entry->read_write_lock,
4462
0
       error ) != 1 )
4463
0
  {
4464
0
    libcerror_error_set(
4465
0
     error,
4466
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4467
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4468
0
     "%s: unable to grab read/write lock for writing.",
4469
0
     function );
4470
4471
0
    return( -1 );
4472
0
  }
4473
0
#endif
4474
0
  if( libfsntfs_internal_file_entry_get_attribute_by_index(
4475
0
       internal_file_entry,
4476
0
       internal_file_entry->mft_entry,
4477
0
       attribute_index,
4478
0
       attribute,
4479
0
       error ) != 1 )
4480
0
  {
4481
0
    libcerror_error_set(
4482
0
     error,
4483
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4484
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4485
0
     "%s: unable to retrieve attribute: %d.",
4486
0
     function,
4487
0
     attribute_index );
4488
4489
0
    result = -1;
4490
0
  }
4491
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4492
0
  if( libcthreads_read_write_lock_release_for_write(
4493
0
       internal_file_entry->read_write_lock,
4494
0
       error ) != 1 )
4495
0
  {
4496
0
    libcerror_error_set(
4497
0
     error,
4498
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4499
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4500
0
     "%s: unable to release read/write lock for writing.",
4501
0
     function );
4502
4503
0
    return( -1 );
4504
0
  }
4505
0
#endif
4506
0
  return( result );
4507
0
}
4508
4509
/* Determines if the file entry has the directory entries ($I30) index
4510
 * Returns 1 if the file entry has a directory entries index, 0 if not or -1 on error
4511
 */
4512
int libfsntfs_file_entry_has_directory_entries_index(
4513
     libfsntfs_file_entry_t *file_entry,
4514
     libcerror_error_t **error )
4515
0
{
4516
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
4517
0
  static char *function                                = "libfsntfs_file_entry_has_directory_entries_index";
4518
0
  int result                                           = 0;
4519
4520
0
  if( file_entry == NULL )
4521
0
  {
4522
0
    libcerror_error_set(
4523
0
     error,
4524
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4525
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4526
0
     "%s: invalid file entry.",
4527
0
     function );
4528
4529
0
    return( -1 );
4530
0
  }
4531
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
4532
4533
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4534
0
  if( libcthreads_read_write_lock_grab_for_read(
4535
0
       internal_file_entry->read_write_lock,
4536
0
       error ) != 1 )
4537
0
  {
4538
0
    libcerror_error_set(
4539
0
     error,
4540
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4541
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4542
0
     "%s: unable to grab read/write lock for reading.",
4543
0
     function );
4544
4545
0
    return( -1 );
4546
0
  }
4547
0
#endif
4548
0
  result = libfsntfs_mft_entry_has_directory_entries_index(
4549
0
            internal_file_entry->mft_entry,
4550
0
            error );
4551
4552
0
  if( result == -1 )
4553
0
  {
4554
0
    libcerror_error_set(
4555
0
     error,
4556
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4557
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4558
0
     "%s: unable to determine if MFT entry has an directory entries index.",
4559
0
     function );
4560
4561
0
    result = -1;
4562
0
  }
4563
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4564
0
  if( libcthreads_read_write_lock_release_for_read(
4565
0
       internal_file_entry->read_write_lock,
4566
0
       error ) != 1 )
4567
0
  {
4568
0
    libcerror_error_set(
4569
0
     error,
4570
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4571
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4572
0
     "%s: unable to release read/write lock for reading.",
4573
0
     function );
4574
4575
0
    return( -1 );
4576
0
  }
4577
0
#endif
4578
0
  return( result );
4579
0
}
4580
4581
/* Determines if the file entry has a default data stream (nameless $DATA attribute)
4582
 * Returns 1 if the file entry has a default data stream, 0 if not or -1 on error
4583
 */
4584
int libfsntfs_file_entry_has_default_data_stream(
4585
     libfsntfs_file_entry_t *file_entry,
4586
     libcerror_error_t **error )
4587
0
{
4588
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
4589
0
  static char *function                                = "libfsntfs_file_entry_has_default_data_stream";
4590
0
  int result                                           = 0;
4591
4592
0
  if( file_entry == NULL )
4593
0
  {
4594
0
    libcerror_error_set(
4595
0
     error,
4596
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4597
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4598
0
     "%s: invalid file entry.",
4599
0
     function );
4600
4601
0
    return( -1 );
4602
0
  }
4603
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
4604
4605
0
  if( internal_file_entry->mft_entry == NULL )
4606
0
  {
4607
0
    libcerror_error_set(
4608
0
     error,
4609
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4610
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4611
0
     "%s: invalid file entry - missing MFT entry.",
4612
0
     function );
4613
4614
0
    return( -1 );
4615
0
  }
4616
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4617
0
  if( libcthreads_read_write_lock_grab_for_read(
4618
0
       internal_file_entry->read_write_lock,
4619
0
       error ) != 1 )
4620
0
  {
4621
0
    libcerror_error_set(
4622
0
     error,
4623
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4624
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4625
0
     "%s: unable to grab read/write lock for reading.",
4626
0
     function );
4627
4628
0
    return( -1 );
4629
0
  }
4630
0
#endif
4631
0
  if( internal_file_entry->mft_entry->data_attribute != NULL )
4632
0
  {
4633
0
    result = 1;
4634
0
  }
4635
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4636
0
  if( libcthreads_read_write_lock_release_for_read(
4637
0
       internal_file_entry->read_write_lock,
4638
0
       error ) != 1 )
4639
0
  {
4640
0
    libcerror_error_set(
4641
0
     error,
4642
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4643
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4644
0
     "%s: unable to release read/write lock for reading.",
4645
0
     function );
4646
4647
0
    return( -1 );
4648
0
  }
4649
0
#endif
4650
0
  return( result );
4651
0
}
4652
4653
/* Determines if the file entry is a symbolic link
4654
 * Returns 1 if the file entry is a symbolic link, 0 if not or -1 on error
4655
 */
4656
int libfsntfs_file_entry_is_symbolic_link(
4657
     libfsntfs_file_entry_t *file_entry,
4658
     libcerror_error_t **error )
4659
0
{
4660
0
  libfsntfs_attribute_t *reparse_point_attribute       = NULL;
4661
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
4662
0
  static char *function                                = "libfsntfs_file_entry_is_symbolic_link";
4663
0
  uint32_t reparse_point_tag                           = 0;
4664
0
  int result                                           = 0;
4665
4666
0
  if( file_entry == NULL )
4667
0
  {
4668
0
    libcerror_error_set(
4669
0
     error,
4670
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4671
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4672
0
     "%s: invalid file entry.",
4673
0
     function );
4674
4675
0
    return( -1 );
4676
0
  }
4677
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
4678
4679
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4680
0
  if( libcthreads_read_write_lock_grab_for_read(
4681
0
       internal_file_entry->read_write_lock,
4682
0
       error ) != 1 )
4683
0
  {
4684
0
    libcerror_error_set(
4685
0
     error,
4686
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4687
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4688
0
     "%s: unable to grab read/write lock for reading.",
4689
0
     function );
4690
4691
0
    return( -1 );
4692
0
  }
4693
0
#endif
4694
0
  result = libfsntfs_internal_file_entry_get_reparse_point_attribute(
4695
0
            internal_file_entry,
4696
0
            internal_file_entry->mft_entry,
4697
0
            &reparse_point_attribute,
4698
0
            error );
4699
4700
0
  if( result == -1 )
4701
0
  {
4702
0
    libcerror_error_set(
4703
0
     error,
4704
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4705
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4706
0
     "%s: unable to retrieve reparse point attribute.",
4707
0
     function );
4708
4709
0
    result = -1;
4710
0
  }
4711
0
  else if( result != 0 )
4712
0
  {
4713
0
    if( libfsntfs_reparse_point_attribute_get_tag(
4714
0
         reparse_point_attribute,
4715
0
         &reparse_point_tag,
4716
0
         error ) != 1 )
4717
0
    {
4718
0
      libcerror_error_set(
4719
0
       error,
4720
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4721
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4722
0
       "%s: unable to retrieve tag from reparse point attribute.",
4723
0
       function );
4724
4725
0
      result = -1;
4726
0
    }
4727
0
    if( reparse_point_tag == 0xa000000cUL )
4728
0
    {
4729
0
      result = 1;
4730
0
    }
4731
0
    else
4732
0
    {
4733
0
      result = 0;
4734
0
    }
4735
0
  }
4736
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4737
0
  if( libcthreads_read_write_lock_release_for_read(
4738
0
       internal_file_entry->read_write_lock,
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_SET_FAILED,
4745
0
     "%s: unable to release read/write lock for reading.",
4746
0
     function );
4747
4748
0
    return( -1 );
4749
0
  }
4750
0
#endif
4751
0
  return( result );
4752
0
}
4753
4754
/* Retrieves the number of alternate data streams
4755
 * Returns 1 if successful or -1 on error
4756
 */
4757
int libfsntfs_file_entry_get_number_of_alternate_data_streams(
4758
     libfsntfs_file_entry_t *file_entry,
4759
     int *number_of_alternate_data_streams,
4760
     libcerror_error_t **error )
4761
0
{
4762
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
4763
0
  static char *function                                = "libfsntfs_file_entry_get_number_of_alternate_data_streams";
4764
0
  int result                                           = 1;
4765
4766
0
  if( file_entry == NULL )
4767
0
  {
4768
0
    libcerror_error_set(
4769
0
     error,
4770
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4771
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4772
0
     "%s: invalid file entry.",
4773
0
     function );
4774
4775
0
    return( -1 );
4776
0
  }
4777
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
4778
4779
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4780
0
  if( libcthreads_read_write_lock_grab_for_read(
4781
0
       internal_file_entry->read_write_lock,
4782
0
       error ) != 1 )
4783
0
  {
4784
0
    libcerror_error_set(
4785
0
     error,
4786
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4787
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4788
0
     "%s: unable to grab read/write lock for reading.",
4789
0
     function );
4790
4791
0
    return( -1 );
4792
0
  }
4793
0
#endif
4794
0
  if( libfsntfs_mft_entry_get_number_of_alternate_data_attributes(
4795
0
       internal_file_entry->mft_entry,
4796
0
       number_of_alternate_data_streams,
4797
0
       error ) != 1 )
4798
0
  {
4799
0
    libcerror_error_set(
4800
0
     error,
4801
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4802
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4803
0
     "%s: unable to retrieve number of alternate data attributes.",
4804
0
     function );
4805
4806
0
    result = -1;
4807
0
  }
4808
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4809
0
  if( libcthreads_read_write_lock_release_for_read(
4810
0
       internal_file_entry->read_write_lock,
4811
0
       error ) != 1 )
4812
0
  {
4813
0
    libcerror_error_set(
4814
0
     error,
4815
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4816
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4817
0
     "%s: unable to release read/write lock for reading.",
4818
0
     function );
4819
4820
0
    return( -1 );
4821
0
  }
4822
0
#endif
4823
0
  return( result );
4824
0
}
4825
4826
/* Retrieves the alternate data stream for the specific index
4827
 * Returns 1 if successful or -1 on error
4828
 */
4829
int libfsntfs_file_entry_get_alternate_data_stream_by_index(
4830
     libfsntfs_file_entry_t *file_entry,
4831
     int alternate_data_stream_index,
4832
     libfsntfs_data_stream_t **alternate_data_stream,
4833
     libcerror_error_t **error )
4834
0
{
4835
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
4836
0
  libfsntfs_mft_attribute_t *data_attribute            = NULL;
4837
0
  static char *function                                = "libfsntfs_file_entry_get_alternate_data_stream_by_index";
4838
0
  int result                                           = 1;
4839
4840
0
  if( file_entry == NULL )
4841
0
  {
4842
0
    libcerror_error_set(
4843
0
     error,
4844
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4845
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4846
0
     "%s: invalid file entry.",
4847
0
     function );
4848
4849
0
    return( -1 );
4850
0
  }
4851
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
4852
4853
0
  if( alternate_data_stream == NULL )
4854
0
  {
4855
0
    libcerror_error_set(
4856
0
     error,
4857
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4858
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4859
0
     "%s: invalid alternate data stream.",
4860
0
     function );
4861
4862
0
    return( -1 );
4863
0
  }
4864
0
  if( *alternate_data_stream != NULL )
4865
0
  {
4866
0
    libcerror_error_set(
4867
0
     error,
4868
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4869
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
4870
0
     "%s: invalid alternate data stream value already set.",
4871
0
     function );
4872
4873
0
    return( -1 );
4874
0
  }
4875
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4876
0
  if( libcthreads_read_write_lock_grab_for_read(
4877
0
       internal_file_entry->read_write_lock,
4878
0
       error ) != 1 )
4879
0
  {
4880
0
    libcerror_error_set(
4881
0
     error,
4882
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4883
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4884
0
     "%s: unable to grab read/write lock for reading.",
4885
0
     function );
4886
4887
0
    return( -1 );
4888
0
  }
4889
0
#endif
4890
0
  if( libfsntfs_mft_entry_get_alternate_data_attribute_by_index(
4891
0
       internal_file_entry->mft_entry,
4892
0
       alternate_data_stream_index,
4893
0
       &data_attribute,
4894
0
       error ) != 1 )
4895
0
  {
4896
0
    libcerror_error_set(
4897
0
     error,
4898
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4899
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4900
0
     "%s: unable to retrieve alternate data attribute: %d.",
4901
0
     function,
4902
0
     alternate_data_stream_index );
4903
4904
0
    result = -1;
4905
0
  }
4906
0
  if( result == 1 )
4907
0
  {
4908
0
    if( libfsntfs_data_stream_initialize(
4909
0
         alternate_data_stream,
4910
0
         internal_file_entry->io_handle,
4911
0
         internal_file_entry->file_io_handle,
4912
0
         data_attribute,
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_INITIALIZE_FAILED,
4919
0
       "%s: unable to create alternate data stream: %d.",
4920
0
       function,
4921
0
       alternate_data_stream_index );
4922
4923
0
      result = -1;
4924
0
    }
4925
0
  }
4926
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4927
0
  if( libcthreads_read_write_lock_release_for_read(
4928
0
       internal_file_entry->read_write_lock,
4929
0
       error ) != 1 )
4930
0
  {
4931
0
    libcerror_error_set(
4932
0
     error,
4933
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4934
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4935
0
     "%s: unable to release read/write lock for reading.",
4936
0
     function );
4937
4938
0
    return( -1 );
4939
0
  }
4940
0
#endif
4941
0
  return( result );
4942
0
}
4943
4944
/* Determines if there is an alternate data stream for an UTF-8 encoded name
4945
 * Returns 1 if available, 0 if not or -1 on error
4946
 */
4947
int libfsntfs_file_entry_has_alternate_data_stream_by_utf8_name(
4948
     libfsntfs_file_entry_t *file_entry,
4949
     const uint8_t *utf8_string,
4950
     size_t utf8_string_length,
4951
     libcerror_error_t **error )
4952
0
{
4953
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
4954
0
  libfsntfs_mft_attribute_t *data_attribute            = NULL;
4955
0
  static char *function                                = "libfsntfs_file_entry_has_alternate_data_stream_by_utf8_name";
4956
0
  int result                                           = 0;
4957
4958
0
  if( file_entry == NULL )
4959
0
  {
4960
0
    libcerror_error_set(
4961
0
     error,
4962
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4963
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4964
0
     "%s: invalid file entry.",
4965
0
     function );
4966
4967
0
    return( -1 );
4968
0
  }
4969
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
4970
4971
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
4972
0
  if( libcthreads_read_write_lock_grab_for_read(
4973
0
       internal_file_entry->read_write_lock,
4974
0
       error ) != 1 )
4975
0
  {
4976
0
    libcerror_error_set(
4977
0
     error,
4978
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4979
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4980
0
     "%s: unable to grab read/write lock for reading.",
4981
0
     function );
4982
4983
0
    return( -1 );
4984
0
  }
4985
0
#endif
4986
0
  result = libfsntfs_mft_entry_get_alternate_data_attribute_by_utf8_name(
4987
0
            internal_file_entry->mft_entry,
4988
0
            utf8_string,
4989
0
            utf8_string_length,
4990
0
            &data_attribute,
4991
0
            error );
4992
4993
0
  if( result == -1 )
4994
0
  {
4995
0
    libcerror_error_set(
4996
0
     error,
4997
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4998
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4999
0
     "%s: unable to retrieve alternate data attribute.",
5000
0
     function );
5001
5002
0
    result = -1;
5003
0
  }
5004
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5005
0
  if( libcthreads_read_write_lock_release_for_read(
5006
0
       internal_file_entry->read_write_lock,
5007
0
       error ) != 1 )
5008
0
  {
5009
0
    libcerror_error_set(
5010
0
     error,
5011
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5012
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5013
0
     "%s: unable to release read/write lock for reading.",
5014
0
     function );
5015
5016
0
    return( -1 );
5017
0
  }
5018
0
#endif
5019
0
  return( result );
5020
0
}
5021
5022
/* Determines if there is an alternate data stream for an UTF-8 encoded name
5023
 * Returns 1 if available, 0 if not or -1 on error
5024
 */
5025
int libfsntfs_file_entry_has_alternate_data_stream_by_utf16_name(
5026
     libfsntfs_file_entry_t *file_entry,
5027
     const uint16_t *utf16_string,
5028
     size_t utf16_string_length,
5029
     libcerror_error_t **error )
5030
0
{
5031
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5032
0
  libfsntfs_mft_attribute_t *data_attribute            = NULL;
5033
0
  static char *function                                = "libfsntfs_file_entry_has_alternate_data_stream_by_utf16_name";
5034
0
  int result                                           = 0;
5035
5036
0
  if( file_entry == NULL )
5037
0
  {
5038
0
    libcerror_error_set(
5039
0
     error,
5040
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5041
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5042
0
     "%s: invalid file entry.",
5043
0
     function );
5044
5045
0
    return( -1 );
5046
0
  }
5047
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5048
5049
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5050
0
  if( libcthreads_read_write_lock_grab_for_read(
5051
0
       internal_file_entry->read_write_lock,
5052
0
       error ) != 1 )
5053
0
  {
5054
0
    libcerror_error_set(
5055
0
     error,
5056
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5057
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5058
0
     "%s: unable to grab read/write lock for reading.",
5059
0
     function );
5060
5061
0
    return( -1 );
5062
0
  }
5063
0
#endif
5064
0
  result = libfsntfs_mft_entry_get_alternate_data_attribute_by_utf16_name(
5065
0
            internal_file_entry->mft_entry,
5066
0
            utf16_string,
5067
0
            utf16_string_length,
5068
0
            &data_attribute,
5069
0
            error );
5070
5071
0
  if( result == -1 )
5072
0
  {
5073
0
    libcerror_error_set(
5074
0
     error,
5075
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5076
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5077
0
     "%s: unable to retrieve alternate data attribute.",
5078
0
     function );
5079
5080
0
    result = -1;
5081
0
  }
5082
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5083
0
  if( libcthreads_read_write_lock_release_for_read(
5084
0
       internal_file_entry->read_write_lock,
5085
0
       error ) != 1 )
5086
0
  {
5087
0
    libcerror_error_set(
5088
0
     error,
5089
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5090
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5091
0
     "%s: unable to release read/write lock for reading.",
5092
0
     function );
5093
5094
0
    return( -1 );
5095
0
  }
5096
0
#endif
5097
0
  return( result );
5098
0
}
5099
5100
/* Retrieves the alternate data stream for an UTF-8 encoded name
5101
 * Returns 1 if successful, 0 if no such file entry or -1 on error
5102
 */
5103
int libfsntfs_file_entry_get_alternate_data_stream_by_utf8_name(
5104
     libfsntfs_file_entry_t *file_entry,
5105
     const uint8_t *utf8_string,
5106
     size_t utf8_string_length,
5107
     libfsntfs_data_stream_t **alternate_data_stream,
5108
     libcerror_error_t **error )
5109
0
{
5110
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5111
0
  libfsntfs_mft_attribute_t *data_attribute            = NULL;
5112
0
  static char *function                                = "libfsntfs_file_entry_get_alternate_data_stream_by_utf8_name";
5113
0
  int result                                           = 0;
5114
5115
0
  if( file_entry == NULL )
5116
0
  {
5117
0
    libcerror_error_set(
5118
0
     error,
5119
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5120
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5121
0
     "%s: invalid file entry.",
5122
0
     function );
5123
5124
0
    return( -1 );
5125
0
  }
5126
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5127
5128
0
  if( alternate_data_stream == NULL )
5129
0
  {
5130
0
    libcerror_error_set(
5131
0
     error,
5132
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5133
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5134
0
     "%s: invalid alternate data stream.",
5135
0
     function );
5136
5137
0
    return( -1 );
5138
0
  }
5139
0
  if( *alternate_data_stream != NULL )
5140
0
  {
5141
0
    libcerror_error_set(
5142
0
     error,
5143
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5144
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
5145
0
     "%s: invalid alternate data stream value already set.",
5146
0
     function );
5147
5148
0
    return( -1 );
5149
0
  }
5150
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5151
0
  if( libcthreads_read_write_lock_grab_for_read(
5152
0
       internal_file_entry->read_write_lock,
5153
0
       error ) != 1 )
5154
0
  {
5155
0
    libcerror_error_set(
5156
0
     error,
5157
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5158
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5159
0
     "%s: unable to grab read/write lock for reading.",
5160
0
     function );
5161
5162
0
    return( -1 );
5163
0
  }
5164
0
#endif
5165
0
  result = libfsntfs_mft_entry_get_alternate_data_attribute_by_utf8_name(
5166
0
            internal_file_entry->mft_entry,
5167
0
            utf8_string,
5168
0
            utf8_string_length,
5169
0
            &data_attribute,
5170
0
            error );
5171
5172
0
  if( result == -1 )
5173
0
  {
5174
0
    libcerror_error_set(
5175
0
     error,
5176
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5177
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5178
0
     "%s: unable to retrieve alternate data attribute.",
5179
0
     function );
5180
5181
0
    result = -1;
5182
0
  }
5183
0
  else if( result != 0 )
5184
0
  {
5185
0
    if( libfsntfs_data_stream_initialize(
5186
0
         alternate_data_stream,
5187
0
         internal_file_entry->io_handle,
5188
0
         internal_file_entry->file_io_handle,
5189
0
         data_attribute,
5190
0
         error ) != 1 )
5191
0
    {
5192
0
      libcerror_error_set(
5193
0
       error,
5194
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5195
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5196
0
       "%s: unable to create alternate data stream.",
5197
0
       function );
5198
5199
0
      result = -1;
5200
0
    }
5201
0
  }
5202
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5203
0
  if( libcthreads_read_write_lock_release_for_read(
5204
0
       internal_file_entry->read_write_lock,
5205
0
       error ) != 1 )
5206
0
  {
5207
0
    libcerror_error_set(
5208
0
     error,
5209
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5210
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5211
0
     "%s: unable to release read/write lock for reading.",
5212
0
     function );
5213
5214
0
    return( -1 );
5215
0
  }
5216
0
#endif
5217
0
  return( result );
5218
0
}
5219
5220
/* Retrieves the alternate data stream for an UTF-16 encoded name
5221
 * Returns 1 if successful, 0 if no such file entry or -1 on error
5222
 */
5223
int libfsntfs_file_entry_get_alternate_data_stream_by_utf16_name(
5224
     libfsntfs_file_entry_t *file_entry,
5225
     const uint16_t *utf16_string,
5226
     size_t utf16_string_length,
5227
     libfsntfs_data_stream_t **alternate_data_stream,
5228
     libcerror_error_t **error )
5229
0
{
5230
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5231
0
  libfsntfs_mft_attribute_t *data_attribute            = NULL;
5232
0
  static char *function                                = "libfsntfs_file_entry_get_alternate_data_stream_by_utf16_name";
5233
0
  int result                                           = 0;
5234
5235
0
  if( file_entry == NULL )
5236
0
  {
5237
0
    libcerror_error_set(
5238
0
     error,
5239
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5240
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5241
0
     "%s: invalid file entry.",
5242
0
     function );
5243
5244
0
    return( -1 );
5245
0
  }
5246
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5247
5248
0
  if( alternate_data_stream == NULL )
5249
0
  {
5250
0
    libcerror_error_set(
5251
0
     error,
5252
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5253
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5254
0
     "%s: invalid alternate data stream.",
5255
0
     function );
5256
5257
0
    return( -1 );
5258
0
  }
5259
0
  if( *alternate_data_stream != NULL )
5260
0
  {
5261
0
    libcerror_error_set(
5262
0
     error,
5263
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5264
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
5265
0
     "%s: invalid alternate data stream value already set.",
5266
0
     function );
5267
5268
0
    return( -1 );
5269
0
  }
5270
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5271
0
  if( libcthreads_read_write_lock_grab_for_read(
5272
0
       internal_file_entry->read_write_lock,
5273
0
       error ) != 1 )
5274
0
  {
5275
0
    libcerror_error_set(
5276
0
     error,
5277
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5278
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5279
0
     "%s: unable to grab read/write lock for reading.",
5280
0
     function );
5281
5282
0
    return( -1 );
5283
0
  }
5284
0
#endif
5285
0
  result = libfsntfs_mft_entry_get_alternate_data_attribute_by_utf16_name(
5286
0
            internal_file_entry->mft_entry,
5287
0
            utf16_string,
5288
0
            utf16_string_length,
5289
0
            &data_attribute,
5290
0
            error );
5291
5292
0
  if( result == -1 )
5293
0
  {
5294
0
    libcerror_error_set(
5295
0
     error,
5296
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5297
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5298
0
     "%s: unable to retrieve alternate data attribute.",
5299
0
     function );
5300
5301
0
    result = -1;
5302
0
  }
5303
0
  else if( result != 0 )
5304
0
  {
5305
0
    if( libfsntfs_data_stream_initialize(
5306
0
         alternate_data_stream,
5307
0
         internal_file_entry->io_handle,
5308
0
         internal_file_entry->file_io_handle,
5309
0
         data_attribute,
5310
0
         error ) != 1 )
5311
0
    {
5312
0
      libcerror_error_set(
5313
0
       error,
5314
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5315
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5316
0
       "%s: unable to create alternate data stream.",
5317
0
       function );
5318
5319
0
      result = -1;
5320
0
    }
5321
0
  }
5322
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5323
0
  if( libcthreads_read_write_lock_release_for_read(
5324
0
       internal_file_entry->read_write_lock,
5325
0
       error ) != 1 )
5326
0
  {
5327
0
    libcerror_error_set(
5328
0
     error,
5329
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5330
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5331
0
     "%s: unable to release read/write lock for reading.",
5332
0
     function );
5333
5334
0
    return( -1 );
5335
0
  }
5336
0
#endif
5337
0
  return( result );
5338
0
}
5339
5340
/* Retrieves the number of sub file entries
5341
 * Returns 1 if successful or -1 on error
5342
 */
5343
int libfsntfs_file_entry_get_number_of_sub_file_entries(
5344
     libfsntfs_file_entry_t *file_entry,
5345
     int *number_of_sub_file_entries,
5346
     libcerror_error_t **error )
5347
263
{
5348
263
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5349
263
  static char *function                                = "libfsntfs_file_entry_get_number_of_sub_file_entries";
5350
263
  int result                                           = 1;
5351
263
  int safe_number_of_sub_file_entries                  = 0;
5352
5353
263
  if( file_entry == NULL )
5354
0
  {
5355
0
    libcerror_error_set(
5356
0
     error,
5357
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5358
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5359
0
     "%s: invalid file entry.",
5360
0
     function );
5361
5362
0
    return( -1 );
5363
0
  }
5364
263
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5365
5366
263
  if( number_of_sub_file_entries == NULL )
5367
0
  {
5368
0
    libcerror_error_set(
5369
0
     error,
5370
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5371
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5372
0
     "%s: invalid number of sub file entries.",
5373
0
     function );
5374
5375
0
    return( -1 );
5376
0
  }
5377
263
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5378
263
  if( libcthreads_read_write_lock_grab_for_read(
5379
263
       internal_file_entry->read_write_lock,
5380
263
       error ) != 1 )
5381
0
  {
5382
0
    libcerror_error_set(
5383
0
     error,
5384
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5385
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5386
0
     "%s: unable to grab read/write lock for reading.",
5387
0
     function );
5388
5389
0
    return( -1 );
5390
0
  }
5391
263
#endif
5392
263
  if( internal_file_entry->directory_entries_tree != NULL )
5393
138
  {
5394
138
    if( libfsntfs_directory_entries_tree_get_number_of_entries(
5395
138
         internal_file_entry->directory_entries_tree,
5396
138
         &safe_number_of_sub_file_entries,
5397
138
         error ) != 1 )
5398
0
    {
5399
0
      libcerror_error_set(
5400
0
       error,
5401
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5402
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5403
0
       "%s: unable to retrieve number of entries from directory entries tree.",
5404
0
       function );
5405
5406
0
      result = -1;
5407
0
    }
5408
138
  }
5409
263
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5410
263
  if( libcthreads_read_write_lock_release_for_read(
5411
263
       internal_file_entry->read_write_lock,
5412
263
       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
263
#endif
5424
263
  if( result == 1 )
5425
263
  {
5426
263
    *number_of_sub_file_entries = safe_number_of_sub_file_entries;
5427
263
  }
5428
263
  return( result );
5429
263
}
5430
5431
/* Retrieves the sub file entry for the specific index
5432
 * Returns 1 if successful or -1 on error
5433
 */
5434
int libfsntfs_file_entry_get_sub_file_entry_by_index(
5435
     libfsntfs_file_entry_t *file_entry,
5436
     int sub_file_entry_index,
5437
     libfsntfs_file_entry_t **sub_file_entry,
5438
     libcerror_error_t **error )
5439
36
{
5440
36
  libfsntfs_directory_entry_t *sub_directory_entry     = NULL;
5441
36
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5442
36
  static char *function                                = "libfsntfs_file_entry_get_sub_file_entry_by_index";
5443
36
  uint64_t mft_entry_index                             = 0;
5444
36
  int result                                           = 1;
5445
5446
36
  if( file_entry == NULL )
5447
0
  {
5448
0
    libcerror_error_set(
5449
0
     error,
5450
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5451
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5452
0
     "%s: invalid file entry.",
5453
0
     function );
5454
5455
0
    return( -1 );
5456
0
  }
5457
36
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5458
5459
36
  if( sub_file_entry == NULL )
5460
0
  {
5461
0
    libcerror_error_set(
5462
0
     error,
5463
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5464
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5465
0
     "%s: invalid sub file entry.",
5466
0
     function );
5467
5468
0
    return( -1 );
5469
0
  }
5470
36
  if( *sub_file_entry != NULL )
5471
0
  {
5472
0
    libcerror_error_set(
5473
0
     error,
5474
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5475
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
5476
0
     "%s: invalid sub file entry value already set.",
5477
0
     function );
5478
5479
0
    return( -1 );
5480
0
  }
5481
36
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5482
36
  if( libcthreads_read_write_lock_grab_for_read(
5483
36
       internal_file_entry->read_write_lock,
5484
36
       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 grab read/write lock for reading.",
5491
0
     function );
5492
5493
0
    return( -1 );
5494
0
  }
5495
36
#endif
5496
36
  if( libfsntfs_directory_entries_tree_get_entry_by_index(
5497
36
       internal_file_entry->directory_entries_tree,
5498
36
       internal_file_entry->file_io_handle,
5499
36
       sub_file_entry_index,
5500
36
       &sub_directory_entry,
5501
36
       error ) != 1 )
5502
0
  {
5503
0
    libcerror_error_set(
5504
0
     error,
5505
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5506
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5507
0
     "%s: unable to retrieve entry: %d from directory entries tree.",
5508
0
     function,
5509
0
     sub_file_entry_index );
5510
5511
0
    result = -1;
5512
0
  }
5513
36
  else
5514
36
  {
5515
36
    if( libfsntfs_directory_entry_get_mft_entry_index(
5516
36
         sub_directory_entry,
5517
36
         &mft_entry_index,
5518
36
         error ) != 1 )
5519
3
    {
5520
3
      libcerror_error_set(
5521
3
       error,
5522
3
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5523
3
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5524
3
       "%s: unable to retrieve MFT entry index.",
5525
3
       function );
5526
5527
3
      result = -1;
5528
3
    }
5529
    /* sub_file_entry takes over management of sub_directory_entry
5530
     */
5531
33
    else if( libfsntfs_file_entry_initialize(
5532
33
        sub_file_entry,
5533
33
        internal_file_entry->io_handle,
5534
33
        internal_file_entry->file_io_handle,
5535
33
        internal_file_entry->file_system,
5536
33
        mft_entry_index,
5537
33
        sub_directory_entry,
5538
33
        internal_file_entry->flags,
5539
33
        error ) != 1 )
5540
9
    {
5541
9
      libcerror_error_set(
5542
9
       error,
5543
9
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5544
9
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5545
9
       "%s: unable to create sub file entry: %d with MFT entry: %" PRIu64 ".",
5546
9
       function,
5547
9
       sub_file_entry_index,
5548
9
       mft_entry_index );
5549
5550
9
      result = -1;
5551
9
    }
5552
36
  }
5553
36
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5554
36
  if( libcthreads_read_write_lock_release_for_read(
5555
36
       internal_file_entry->read_write_lock,
5556
36
       error ) != 1 )
5557
0
  {
5558
0
    libcerror_error_set(
5559
0
     error,
5560
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5561
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5562
0
     "%s: unable to release read/write lock for reading.",
5563
0
     function );
5564
5565
0
    result = -1;
5566
0
  }
5567
36
#endif
5568
36
  if( result == -1 )
5569
12
  {
5570
12
    if( sub_directory_entry != NULL )
5571
12
    {
5572
12
      libfsntfs_directory_entry_free(
5573
12
       &sub_directory_entry,
5574
12
       NULL );
5575
12
    }
5576
12
  }
5577
36
  return( result );
5578
36
}
5579
5580
/* Retrieves the sub file entry for an UTF-8 encoded name
5581
 * Returns 1 if successful, 0 if no such file entry or -1 on error
5582
 */
5583
int libfsntfs_file_entry_get_sub_file_entry_by_utf8_name(
5584
     libfsntfs_file_entry_t *file_entry,
5585
     const uint8_t *utf8_string,
5586
     size_t utf8_string_length,
5587
     libfsntfs_file_entry_t **sub_file_entry,
5588
     libcerror_error_t **error )
5589
0
{
5590
0
  libfsntfs_directory_entry_t *sub_directory_entry     = NULL;
5591
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5592
0
  static char *function                                = "libfsntfs_file_entry_get_sub_file_entry_by_utf8_name";
5593
0
  uint64_t mft_entry_index                             = 0;
5594
0
  int result                                           = 0;
5595
5596
0
  if( file_entry == NULL )
5597
0
  {
5598
0
    libcerror_error_set(
5599
0
     error,
5600
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5601
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5602
0
     "%s: invalid file entry.",
5603
0
     function );
5604
5605
0
    return( -1 );
5606
0
  }
5607
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5608
5609
0
  if( sub_file_entry == NULL )
5610
0
  {
5611
0
    libcerror_error_set(
5612
0
     error,
5613
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5614
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5615
0
     "%s: invalid sub file entry.",
5616
0
     function );
5617
5618
0
    return( -1 );
5619
0
  }
5620
0
  if( *sub_file_entry != NULL )
5621
0
  {
5622
0
    libcerror_error_set(
5623
0
     error,
5624
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5625
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
5626
0
     "%s: invalid sub file entry value already set.",
5627
0
     function );
5628
5629
0
    return( -1 );
5630
0
  }
5631
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5632
0
  if( libcthreads_read_write_lock_grab_for_read(
5633
0
       internal_file_entry->read_write_lock,
5634
0
       error ) != 1 )
5635
0
  {
5636
0
    libcerror_error_set(
5637
0
     error,
5638
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5639
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5640
0
     "%s: unable to grab read/write lock for reading.",
5641
0
     function );
5642
5643
0
    return( -1 );
5644
0
  }
5645
0
#endif
5646
0
  result = libfsntfs_directory_entries_tree_get_entry_by_utf8_name(
5647
0
            internal_file_entry->directory_entries_tree,
5648
0
            internal_file_entry->file_io_handle,
5649
0
            utf8_string,
5650
0
            utf8_string_length,
5651
0
            &sub_directory_entry,
5652
0
            error );
5653
5654
0
  if( result == -1 )
5655
0
  {
5656
0
    libcerror_error_set(
5657
0
     error,
5658
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5659
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5660
0
     "%s: unable to retrieve directory entry.",
5661
0
     function );
5662
5663
0
    result = -1;
5664
0
  }
5665
0
  else if( result != 0 )
5666
0
  {
5667
0
    if( libfsntfs_directory_entry_get_mft_entry_index(
5668
0
         sub_directory_entry,
5669
0
         &mft_entry_index,
5670
0
         error ) != 1 )
5671
0
    {
5672
0
      libcerror_error_set(
5673
0
       error,
5674
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5675
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5676
0
       "%s: unable to retrieve MFT entry index.",
5677
0
       function );
5678
5679
0
      result = -1;
5680
0
    }
5681
    /* sub_file_entry takes over management of sub_directory_entry
5682
     */
5683
0
    else if( libfsntfs_file_entry_initialize(
5684
0
              sub_file_entry,
5685
0
              internal_file_entry->io_handle,
5686
0
              internal_file_entry->file_io_handle,
5687
0
              internal_file_entry->file_system,
5688
0
              mft_entry_index,
5689
0
              sub_directory_entry,
5690
0
              internal_file_entry->flags,
5691
0
              error ) != 1 )
5692
0
    {
5693
0
      libcerror_error_set(
5694
0
       error,
5695
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5696
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5697
0
       "%s: unable to create sub file entry with MFT entry: %" PRIu64 ".",
5698
0
       function,
5699
0
       mft_entry_index );
5700
5701
0
      result = -1;
5702
0
    }
5703
0
  }
5704
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5705
0
  if( libcthreads_read_write_lock_release_for_read(
5706
0
       internal_file_entry->read_write_lock,
5707
0
       error ) != 1 )
5708
0
  {
5709
0
    libcerror_error_set(
5710
0
     error,
5711
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5712
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5713
0
     "%s: unable to release read/write lock for reading.",
5714
0
     function );
5715
5716
0
    result = -1;
5717
0
  }
5718
0
#endif
5719
0
  if( result == -1 )
5720
0
  {
5721
0
    if( sub_directory_entry != NULL )
5722
0
    {
5723
0
      libfsntfs_directory_entry_free(
5724
0
       &sub_directory_entry,
5725
0
       NULL );
5726
0
    }
5727
0
  }
5728
0
  return( result );
5729
0
}
5730
5731
/* Retrieves the sub file entry for an UTF-16 encoded name
5732
 * Returns 1 if successful, 0 if no such file entry or -1 on error
5733
 */
5734
int libfsntfs_file_entry_get_sub_file_entry_by_utf16_name(
5735
     libfsntfs_file_entry_t *file_entry,
5736
     const uint16_t *utf16_string,
5737
     size_t utf16_string_length,
5738
     libfsntfs_file_entry_t **sub_file_entry,
5739
     libcerror_error_t **error )
5740
0
{
5741
0
  libfsntfs_directory_entry_t *sub_directory_entry     = NULL;
5742
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5743
0
  static char *function                                = "libfsntfs_file_entry_get_sub_file_entry_by_utf16_name";
5744
0
  uint64_t mft_entry_index                             = 0;
5745
0
  int result                                           = 0;
5746
5747
0
  if( file_entry == NULL )
5748
0
  {
5749
0
    libcerror_error_set(
5750
0
     error,
5751
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5752
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5753
0
     "%s: invalid file entry.",
5754
0
     function );
5755
5756
0
    return( -1 );
5757
0
  }
5758
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5759
5760
0
  if( sub_file_entry == NULL )
5761
0
  {
5762
0
    libcerror_error_set(
5763
0
     error,
5764
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5765
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5766
0
     "%s: invalid sub file entry.",
5767
0
     function );
5768
5769
0
    return( -1 );
5770
0
  }
5771
0
  if( *sub_file_entry != NULL )
5772
0
  {
5773
0
    libcerror_error_set(
5774
0
     error,
5775
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5776
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
5777
0
     "%s: invalid sub file entry value already set.",
5778
0
     function );
5779
5780
0
    return( -1 );
5781
0
  }
5782
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5783
0
  if( libcthreads_read_write_lock_grab_for_read(
5784
0
       internal_file_entry->read_write_lock,
5785
0
       error ) != 1 )
5786
0
  {
5787
0
    libcerror_error_set(
5788
0
     error,
5789
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5790
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5791
0
     "%s: unable to grab read/write lock for reading.",
5792
0
     function );
5793
5794
0
    return( -1 );
5795
0
  }
5796
0
#endif
5797
0
  result = libfsntfs_directory_entries_tree_get_entry_by_utf16_name(
5798
0
            internal_file_entry->directory_entries_tree,
5799
0
            internal_file_entry->file_io_handle,
5800
0
            utf16_string,
5801
0
            utf16_string_length,
5802
0
            &sub_directory_entry,
5803
0
            error );
5804
5805
0
  if( result == -1 )
5806
0
  {
5807
0
    libcerror_error_set(
5808
0
     error,
5809
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5810
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5811
0
     "%s: unable to retrieve directory entry.",
5812
0
     function );
5813
5814
0
    result = -1;
5815
0
  }
5816
0
  else if( result != 0 )
5817
0
  {
5818
0
    if( libfsntfs_directory_entry_get_mft_entry_index(
5819
0
         sub_directory_entry,
5820
0
         &mft_entry_index,
5821
0
         error ) != 1 )
5822
0
    {
5823
0
      libcerror_error_set(
5824
0
       error,
5825
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5826
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5827
0
       "%s: unable to retrieve MFT entry index.",
5828
0
       function );
5829
5830
0
      result = -1;
5831
0
    }
5832
    /* sub_file_entry takes over management of sub_directory_entry
5833
     */
5834
0
    else if( libfsntfs_file_entry_initialize(
5835
0
              sub_file_entry,
5836
0
              internal_file_entry->io_handle,
5837
0
              internal_file_entry->file_io_handle,
5838
0
              internal_file_entry->file_system,
5839
0
              mft_entry_index,
5840
0
              sub_directory_entry,
5841
0
              internal_file_entry->flags,
5842
0
              error ) != 1 )
5843
0
    {
5844
0
      libcerror_error_set(
5845
0
       error,
5846
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5847
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5848
0
       "%s: unable to create sub file entry with MFT entry: %" PRIu64 ".",
5849
0
       function,
5850
0
       mft_entry_index );
5851
5852
0
      result = -1;
5853
0
    }
5854
0
  }
5855
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5856
0
  if( libcthreads_read_write_lock_release_for_read(
5857
0
       internal_file_entry->read_write_lock,
5858
0
       error ) != 1 )
5859
0
  {
5860
0
    libcerror_error_set(
5861
0
     error,
5862
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5863
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5864
0
     "%s: unable to release read/write lock for reading.",
5865
0
     function );
5866
5867
0
    result = -1;
5868
0
  }
5869
0
#endif
5870
0
  if( result == -1 )
5871
0
  {
5872
0
    if( sub_directory_entry != NULL )
5873
0
    {
5874
0
      libfsntfs_directory_entry_free(
5875
0
       &sub_directory_entry,
5876
0
       NULL );
5877
0
    }
5878
0
  }
5879
0
  return( result );
5880
0
}
5881
5882
/* Reads data at the current offset from the default data stream (nameless $DATA attribute)
5883
 * Returns the number of bytes read or -1 on error
5884
 */
5885
ssize_t libfsntfs_file_entry_read_buffer(
5886
         libfsntfs_file_entry_t *file_entry,
5887
         void *buffer,
5888
         size_t buffer_size,
5889
         libcerror_error_t **error )
5890
0
{
5891
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5892
0
  static char *function                                = "libfsntfs_file_entry_read_buffer";
5893
0
  ssize_t read_count                                   = 0;
5894
5895
0
  if( file_entry == NULL )
5896
0
  {
5897
0
    libcerror_error_set(
5898
0
     error,
5899
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5900
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5901
0
     "%s: invalid file entry.",
5902
0
     function );
5903
5904
0
    return( -1 );
5905
0
  }
5906
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5907
5908
0
  if( internal_file_entry->data_attribute == NULL )
5909
0
  {
5910
0
    libcerror_error_set(
5911
0
     error,
5912
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5913
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5914
0
     "%s: invalid file entry - missing data attribute.",
5915
0
     function );
5916
5917
0
    return( -1 );
5918
0
  }
5919
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5920
0
  if( libcthreads_read_write_lock_grab_for_write(
5921
0
       internal_file_entry->read_write_lock,
5922
0
       error ) != 1 )
5923
0
  {
5924
0
    libcerror_error_set(
5925
0
     error,
5926
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5927
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5928
0
     "%s: unable to grab read/write lock for writing.",
5929
0
     function );
5930
5931
0
    return( -1 );
5932
0
  }
5933
0
#endif
5934
0
  read_count = libfdata_stream_read_buffer(
5935
0
                internal_file_entry->data_cluster_block_stream,
5936
0
                (intptr_t *) internal_file_entry->file_io_handle,
5937
0
                buffer,
5938
0
                buffer_size,
5939
0
                0,
5940
0
                error );
5941
5942
0
  if( read_count < 0 )
5943
0
  {
5944
0
    libcerror_error_set(
5945
0
     error,
5946
0
     LIBCERROR_ERROR_DOMAIN_IO,
5947
0
     LIBCERROR_IO_ERROR_READ_FAILED,
5948
0
     "%s: unable to read from data cluster block stream.",
5949
0
     function );
5950
5951
0
    read_count = -1;
5952
0
  }
5953
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
5954
0
  if( libcthreads_read_write_lock_release_for_write(
5955
0
       internal_file_entry->read_write_lock,
5956
0
       error ) != 1 )
5957
0
  {
5958
0
    libcerror_error_set(
5959
0
     error,
5960
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5961
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
5962
0
     "%s: unable to release read/write lock for writing.",
5963
0
     function );
5964
5965
0
    return( -1 );
5966
0
  }
5967
0
#endif
5968
0
  return( read_count );
5969
0
}
5970
5971
/* Reads data at a specific offset from the default data stream (nameless $DATA attribute)
5972
 * Returns the number of bytes read or -1 on error
5973
 */
5974
ssize_t libfsntfs_file_entry_read_buffer_at_offset(
5975
         libfsntfs_file_entry_t *file_entry,
5976
         void *buffer,
5977
         size_t buffer_size,
5978
         off64_t offset,
5979
         libcerror_error_t **error )
5980
0
{
5981
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
5982
0
  static char *function                                = "libfsntfs_file_entry_read_buffer_at_offset";
5983
0
  ssize_t read_count                                   = 0;
5984
5985
0
  if( file_entry == NULL )
5986
0
  {
5987
0
    libcerror_error_set(
5988
0
     error,
5989
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5990
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5991
0
     "%s: invalid file entry.",
5992
0
     function );
5993
5994
0
    return( -1 );
5995
0
  }
5996
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
5997
5998
0
  if( internal_file_entry->data_attribute == NULL )
5999
0
  {
6000
0
    libcerror_error_set(
6001
0
     error,
6002
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6003
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6004
0
     "%s: invalid file entry - missing data attribute.",
6005
0
     function );
6006
6007
0
    return( -1 );
6008
0
  }
6009
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6010
0
  if( libcthreads_read_write_lock_grab_for_write(
6011
0
       internal_file_entry->read_write_lock,
6012
0
       error ) != 1 )
6013
0
  {
6014
0
    libcerror_error_set(
6015
0
     error,
6016
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6017
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6018
0
     "%s: unable to grab read/write lock for writing.",
6019
0
     function );
6020
6021
0
    return( -1 );
6022
0
  }
6023
0
#endif
6024
0
  read_count = libfdata_stream_read_buffer_at_offset(
6025
0
                internal_file_entry->data_cluster_block_stream,
6026
0
                (intptr_t *) internal_file_entry->file_io_handle,
6027
0
                buffer,
6028
0
                buffer_size,
6029
0
                offset,
6030
0
                0,
6031
0
                error );
6032
6033
0
  if( read_count < 0 )
6034
0
  {
6035
0
    libcerror_error_set(
6036
0
     error,
6037
0
     LIBCERROR_ERROR_DOMAIN_IO,
6038
0
     LIBCERROR_IO_ERROR_READ_FAILED,
6039
0
     "%s: unable to read from data cluster block stream.",
6040
0
     function );
6041
6042
0
    read_count = -1;
6043
0
  }
6044
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6045
0
  if( libcthreads_read_write_lock_release_for_write(
6046
0
       internal_file_entry->read_write_lock,
6047
0
       error ) != 1 )
6048
0
  {
6049
0
    libcerror_error_set(
6050
0
     error,
6051
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6052
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6053
0
     "%s: unable to release read/write lock for writing.",
6054
0
     function );
6055
6056
0
    return( -1 );
6057
0
  }
6058
0
#endif
6059
0
  return( read_count );
6060
0
}
6061
6062
/* Seeks a certain offset in the default data stream (nameless $DATA attribute)
6063
 * Returns the offset if seek is successful or -1 on error
6064
 */
6065
off64_t libfsntfs_file_entry_seek_offset(
6066
         libfsntfs_file_entry_t *file_entry,
6067
         off64_t offset,
6068
         int whence,
6069
         libcerror_error_t **error )
6070
0
{
6071
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
6072
0
  static char *function                                = "libfsntfs_file_entry_seek_offset";
6073
6074
0
  if( file_entry == NULL )
6075
0
  {
6076
0
    libcerror_error_set(
6077
0
     error,
6078
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6079
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6080
0
     "%s: invalid file entry.",
6081
0
     function );
6082
6083
0
    return( -1 );
6084
0
  }
6085
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
6086
6087
0
  if( internal_file_entry->data_attribute == NULL )
6088
0
  {
6089
0
    libcerror_error_set(
6090
0
     error,
6091
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6092
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6093
0
     "%s: invalid file entry - missing data attribute.",
6094
0
     function );
6095
6096
0
    return( -1 );
6097
0
  }
6098
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6099
0
  if( libcthreads_read_write_lock_grab_for_write(
6100
0
       internal_file_entry->read_write_lock,
6101
0
       error ) != 1 )
6102
0
  {
6103
0
    libcerror_error_set(
6104
0
     error,
6105
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6106
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6107
0
     "%s: unable to grab read/write lock for writing.",
6108
0
     function );
6109
6110
0
    return( -1 );
6111
0
  }
6112
0
#endif
6113
0
  offset = libfdata_stream_seek_offset(
6114
0
            internal_file_entry->data_cluster_block_stream,
6115
0
            offset,
6116
0
            whence,
6117
0
            error );
6118
6119
0
  if( offset == -1 )
6120
0
  {
6121
0
    libcerror_error_set(
6122
0
     error,
6123
0
     LIBCERROR_ERROR_DOMAIN_IO,
6124
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
6125
0
     "%s: unable to seek offset in data cluster block stream.",
6126
0
     function );
6127
6128
0
    offset = -1;
6129
0
  }
6130
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6131
0
  if( libcthreads_read_write_lock_release_for_write(
6132
0
       internal_file_entry->read_write_lock,
6133
0
       error ) != 1 )
6134
0
  {
6135
0
    libcerror_error_set(
6136
0
     error,
6137
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6138
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6139
0
     "%s: unable to release read/write lock for writing.",
6140
0
     function );
6141
6142
0
    return( -1 );
6143
0
  }
6144
0
#endif
6145
0
  return( offset );
6146
0
}
6147
6148
/* Retrieves the current offset of the default data stream (nameless $DATA attribute)
6149
 * Returns the offset if successful or -1 on error
6150
 */
6151
int libfsntfs_file_entry_get_offset(
6152
     libfsntfs_file_entry_t *file_entry,
6153
     off64_t *offset,
6154
     libcerror_error_t **error )
6155
0
{
6156
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
6157
0
  static char *function                                = "libfsntfs_file_entry_get_offset";
6158
0
  int result                                           = 1;
6159
6160
0
  if( file_entry == NULL )
6161
0
  {
6162
0
    libcerror_error_set(
6163
0
     error,
6164
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6165
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6166
0
     "%s: invalid file entry.",
6167
0
     function );
6168
6169
0
    return( -1 );
6170
0
  }
6171
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
6172
6173
0
  if( internal_file_entry->data_attribute == NULL )
6174
0
  {
6175
0
    libcerror_error_set(
6176
0
     error,
6177
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6178
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6179
0
     "%s: invalid file entry - missing data attribute.",
6180
0
     function );
6181
6182
0
    return( -1 );
6183
0
  }
6184
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6185
0
  if( libcthreads_read_write_lock_grab_for_read(
6186
0
       internal_file_entry->read_write_lock,
6187
0
       error ) != 1 )
6188
0
  {
6189
0
    libcerror_error_set(
6190
0
     error,
6191
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6192
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6193
0
     "%s: unable to grab read/write lock for reading.",
6194
0
     function );
6195
6196
0
    return( -1 );
6197
0
  }
6198
0
#endif
6199
0
  if( libfdata_stream_get_offset(
6200
0
       internal_file_entry->data_cluster_block_stream,
6201
0
       offset,
6202
0
       error ) != 1 )
6203
0
  {
6204
0
    libcerror_error_set(
6205
0
     error,
6206
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6207
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6208
0
     "%s: unable to retrieve offset from data cluster block stream.",
6209
0
     function );
6210
6211
0
    result = -1;
6212
0
  }
6213
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6214
0
  if( libcthreads_read_write_lock_release_for_read(
6215
0
       internal_file_entry->read_write_lock,
6216
0
       error ) != 1 )
6217
0
  {
6218
0
    libcerror_error_set(
6219
0
     error,
6220
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6221
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6222
0
     "%s: unable to release read/write lock for reading.",
6223
0
     function );
6224
6225
0
    return( -1 );
6226
0
  }
6227
0
#endif
6228
0
  return( result );
6229
0
}
6230
6231
/* Retrieves the size of the default data stream (nameless $DATA attribute)
6232
 * Returns 1 if successful or -1 on error
6233
 */
6234
int libfsntfs_file_entry_get_size(
6235
     libfsntfs_file_entry_t *file_entry,
6236
     size64_t *size,
6237
     libcerror_error_t **error )
6238
0
{
6239
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
6240
0
  static char *function                                = "libfsntfs_file_entry_get_size";
6241
0
  size64_t safe_size                                   = 0;
6242
0
  int result                                           = 1;
6243
6244
0
  if( file_entry == NULL )
6245
0
  {
6246
0
    libcerror_error_set(
6247
0
     error,
6248
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6249
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6250
0
     "%s: invalid file entry.",
6251
0
     function );
6252
6253
0
    return( -1 );
6254
0
  }
6255
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
6256
6257
0
  if( size == NULL )
6258
0
  {
6259
0
    libcerror_error_set(
6260
0
     error,
6261
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6262
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6263
0
     "%s: invalid size.",
6264
0
     function );
6265
6266
0
    return( -1 );
6267
0
  }
6268
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6269
0
  if( libcthreads_read_write_lock_grab_for_read(
6270
0
       internal_file_entry->read_write_lock,
6271
0
       error ) != 1 )
6272
0
  {
6273
0
    libcerror_error_set(
6274
0
     error,
6275
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6276
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6277
0
     "%s: unable to grab read/write lock for reading.",
6278
0
     function );
6279
6280
0
    return( -1 );
6281
0
  }
6282
0
#endif
6283
0
  if( internal_file_entry->data_cluster_block_stream != NULL )
6284
0
  {
6285
0
    if( libfdata_stream_get_size(
6286
0
         internal_file_entry->data_cluster_block_stream,
6287
0
         &safe_size,
6288
0
         error ) != 1 )
6289
0
    {
6290
0
      libcerror_error_set(
6291
0
       error,
6292
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6293
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6294
0
       "%s: unable to retrieve data attribute data size.",
6295
0
       function );
6296
6297
0
      result = -1;
6298
0
    }
6299
0
  }
6300
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6301
0
  if( libcthreads_read_write_lock_release_for_read(
6302
0
       internal_file_entry->read_write_lock,
6303
0
       error ) != 1 )
6304
0
  {
6305
0
    libcerror_error_set(
6306
0
     error,
6307
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6308
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6309
0
     "%s: unable to release read/write lock for reading.",
6310
0
     function );
6311
6312
0
    return( -1 );
6313
0
  }
6314
0
#endif
6315
0
  if( result == 1 )
6316
0
  {
6317
0
    *size = safe_size;
6318
0
  }
6319
0
  return( result );
6320
0
}
6321
6322
/* Retrieves the number of extents (decoded data runs) of the default data stream (nameless $DATA attribute)
6323
 * Returns 1 if successful or -1 on error
6324
 */
6325
int libfsntfs_file_entry_get_number_of_extents(
6326
     libfsntfs_file_entry_t *file_entry,
6327
     int *number_of_extents,
6328
     libcerror_error_t **error )
6329
0
{
6330
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
6331
0
  static char *function                                = "libfsntfs_file_entry_get_number_of_extents";
6332
0
  int result                                           = 1;
6333
0
  int safe_number_of_extents                           = 0;
6334
6335
0
  if( file_entry == NULL )
6336
0
  {
6337
0
    libcerror_error_set(
6338
0
     error,
6339
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6340
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6341
0
     "%s: invalid file entry.",
6342
0
     function );
6343
6344
0
    return( -1 );
6345
0
  }
6346
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
6347
6348
0
  if( number_of_extents == NULL )
6349
0
  {
6350
0
    libcerror_error_set(
6351
0
     error,
6352
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6353
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6354
0
     "%s: invalid number of extents.",
6355
0
     function );
6356
6357
0
    return( -1 );
6358
0
  }
6359
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6360
0
  if( libcthreads_read_write_lock_grab_for_read(
6361
0
       internal_file_entry->read_write_lock,
6362
0
       error ) != 1 )
6363
0
  {
6364
0
    libcerror_error_set(
6365
0
     error,
6366
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6367
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6368
0
     "%s: unable to grab read/write lock for reading.",
6369
0
     function );
6370
6371
0
    return( -1 );
6372
0
  }
6373
0
#endif
6374
0
  if( internal_file_entry->extents_array != NULL )
6375
0
  {
6376
0
    if( libcdata_array_get_number_of_entries(
6377
0
         internal_file_entry->extents_array,
6378
0
         &safe_number_of_extents,
6379
0
         error ) != 1 )
6380
0
    {
6381
0
      libcerror_error_set(
6382
0
       error,
6383
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6384
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6385
0
       "%s: unable to retrieve number of extents.",
6386
0
       function );
6387
6388
0
      result = -1;
6389
0
    }
6390
0
  }
6391
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6392
0
  if( libcthreads_read_write_lock_release_for_read(
6393
0
       internal_file_entry->read_write_lock,
6394
0
       error ) != 1 )
6395
0
  {
6396
0
    libcerror_error_set(
6397
0
     error,
6398
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6399
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6400
0
     "%s: unable to release read/write lock for reading.",
6401
0
     function );
6402
6403
0
    return( -1 );
6404
0
  }
6405
0
#endif
6406
0
  if( result == 1 )
6407
0
  {
6408
0
    *number_of_extents = safe_number_of_extents;
6409
0
  }
6410
0
  return( result );
6411
0
}
6412
6413
/* Retrieves a specific extent (decoded data run) of the default data stream (nameless $DATA attribute)
6414
 * Returns 1 if successful or -1 on error
6415
 */
6416
int libfsntfs_file_entry_get_extent_by_index(
6417
     libfsntfs_file_entry_t *file_entry,
6418
     int extent_index,
6419
     off64_t *extent_offset,
6420
     size64_t *extent_size,
6421
     uint32_t *extent_flags,
6422
     libcerror_error_t **error )
6423
0
{
6424
0
  libfsntfs_extent_t *data_extent                      = NULL;
6425
0
  libfsntfs_internal_file_entry_t *internal_file_entry = NULL;
6426
0
  static char *function                                = "libfsntfs_file_entry_get_extent_by_index";
6427
0
  int result                                           = 1;
6428
6429
0
  if( file_entry == NULL )
6430
0
  {
6431
0
    libcerror_error_set(
6432
0
     error,
6433
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6434
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6435
0
     "%s: invalid file entry.",
6436
0
     function );
6437
6438
0
    return( -1 );
6439
0
  }
6440
0
  internal_file_entry = (libfsntfs_internal_file_entry_t *) file_entry;
6441
6442
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6443
0
  if( libcthreads_read_write_lock_grab_for_read(
6444
0
       internal_file_entry->read_write_lock,
6445
0
       error ) != 1 )
6446
0
  {
6447
0
    libcerror_error_set(
6448
0
     error,
6449
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6450
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6451
0
     "%s: unable to grab read/write lock for reading.",
6452
0
     function );
6453
6454
0
    return( -1 );
6455
0
  }
6456
0
#endif
6457
0
  if( libcdata_array_get_entry_by_index(
6458
0
       internal_file_entry->extents_array,
6459
0
       extent_index,
6460
0
       (intptr_t **) &data_extent,
6461
0
       error ) != 1 )
6462
0
  {
6463
0
    libcerror_error_set(
6464
0
     error,
6465
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6466
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6467
0
     "%s: unable to retrieve extent: %d.",
6468
0
     function,
6469
0
     extent_index );
6470
6471
0
    result = -1;
6472
0
  }
6473
0
  if( result == 1 )
6474
0
  {
6475
0
    if( libfsntfs_extent_get_values(
6476
0
         data_extent,
6477
0
         extent_offset,
6478
0
         extent_size,
6479
0
         extent_flags,
6480
0
         error ) != 1 )
6481
0
    {
6482
0
      libcerror_error_set(
6483
0
       error,
6484
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6485
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6486
0
       "%s: unable to retrieve extent: %d values.",
6487
0
       function,
6488
0
       extent_index );
6489
6490
0
      result = -1;
6491
0
    }
6492
0
  }
6493
0
#if defined( HAVE_LIBFSNTFS_MULTI_THREAD_SUPPORT )
6494
0
  if( libcthreads_read_write_lock_release_for_read(
6495
0
       internal_file_entry->read_write_lock,
6496
0
       error ) != 1 )
6497
0
  {
6498
0
    libcerror_error_set(
6499
0
     error,
6500
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6501
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6502
0
     "%s: unable to release read/write lock for reading.",
6503
0
     function );
6504
6505
0
    return( -1 );
6506
0
  }
6507
0
#endif
6508
0
  return( result );
6509
0
}
6510