Coverage Report

Created: 2025-12-05 07:13

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