Coverage Report

Created: 2023-06-07 06:53

/src/libfsxfs/libfsxfs/libfsxfs_file_entry.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * File entry functions
3
 *
4
 * Copyright (C) 2020-2023, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <types.h>
25
26
#include "libfsxfs_attributes.h"
27
#include "libfsxfs_data_stream.h"
28
#include "libfsxfs_definitions.h"
29
#include "libfsxfs_directory.h"
30
#include "libfsxfs_directory_entry.h"
31
#include "libfsxfs_extended_attribute.h"
32
#include "libfsxfs_file_entry.h"
33
#include "libfsxfs_inode.h"
34
#include "libfsxfs_libbfio.h"
35
#include "libfsxfs_libcerror.h"
36
#include "libfsxfs_libcnotify.h"
37
#include "libfsxfs_libcthreads.h"
38
#include "libfsxfs_libfdata.h"
39
#include "libfsxfs_libfdatetime.h"
40
#include "libfsxfs_libuna.h"
41
#include "libfsxfs_types.h"
42
43
/* Creates a file entry
44
 * Make sure the value file_entry is referencing, is set to NULL
45
 * Returns 1 if successful or -1 on error
46
 */
47
int libfsxfs_file_entry_initialize(
48
     libfsxfs_file_entry_t **file_entry,
49
     libfsxfs_io_handle_t *io_handle,
50
     libbfio_handle_t *file_io_handle,
51
     libfsxfs_file_system_t *file_system,
52
     uint64_t inode_number,
53
     libfsxfs_inode_t *inode,
54
     libfsxfs_directory_entry_t *directory_entry,
55
     libcerror_error_t **error )
56
1.74k
{
57
1.74k
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
58
1.74k
  static char *function                               = "libfsxfs_file_entry_initialize";
59
60
1.74k
  if( file_entry == NULL )
61
0
  {
62
0
    libcerror_error_set(
63
0
     error,
64
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
65
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
66
0
     "%s: invalid file entry.",
67
0
     function );
68
69
0
    return( -1 );
70
0
  }
71
1.74k
  if( *file_entry != NULL )
72
0
  {
73
0
    libcerror_error_set(
74
0
     error,
75
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
76
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
77
0
     "%s: invalid file entry value already set.",
78
0
     function );
79
80
0
    return( -1 );
81
0
  }
82
1.74k
  if( inode == NULL )
83
0
  {
84
0
    libcerror_error_set(
85
0
     error,
86
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
87
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
88
0
     "%s: invalid inode.",
89
0
     function );
90
91
0
    return( -1 );
92
0
  }
93
1.74k
  internal_file_entry = memory_allocate_structure(
94
1.74k
                         libfsxfs_internal_file_entry_t );
95
96
1.74k
  if( internal_file_entry == NULL )
97
0
  {
98
0
    libcerror_error_set(
99
0
     error,
100
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
101
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
102
0
     "%s: unable to create file entry.",
103
0
     function );
104
105
0
    goto on_error;
106
0
  }
107
1.74k
  if( memory_set(
108
1.74k
       internal_file_entry,
109
1.74k
       0,
110
1.74k
       sizeof( libfsxfs_internal_file_entry_t ) ) == NULL )
111
0
  {
112
0
    libcerror_error_set(
113
0
     error,
114
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
115
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
116
0
     "%s: unable to clear file entry.",
117
0
     function );
118
119
0
    memory_free(
120
0
     internal_file_entry );
121
122
0
    return( -1 );
123
0
  }
124
1.74k
  if( ( ( inode->file_mode & 0xf000 ) == LIBFSXFS_FILE_TYPE_REGULAR_FILE )
125
1.74k
   || ( ( inode->file_mode & 0xf000 ) == LIBFSXFS_FILE_TYPE_SYMBOLIC_LINK ) )
126
646
  {
127
646
    if( libfsxfs_inode_get_data_size(
128
646
         inode,
129
646
         &( internal_file_entry->data_size ),
130
646
         error ) != 1 )
131
0
    {
132
0
      libcerror_error_set(
133
0
       error,
134
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
135
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
136
0
       "%s: unable to retrieve data size from inode.",
137
0
       function );
138
139
0
      goto on_error;
140
0
    }
141
646
    if( libfsxfs_data_stream_initialize(
142
646
         &( internal_file_entry->data_stream ),
143
646
         io_handle,
144
646
         inode,
145
646
         internal_file_entry->data_size,
146
646
         error ) != 1 )
147
203
    {
148
203
      libcerror_error_set(
149
203
       error,
150
203
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
151
203
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
152
203
       "%s: unable to create data stream.",
153
203
       function );
154
155
203
      goto on_error;
156
203
    }
157
646
  }
158
1.53k
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
159
1.53k
  if( libcthreads_read_write_lock_initialize(
160
1.53k
       &( internal_file_entry->read_write_lock ),
161
1.53k
       error ) != 1 )
162
0
  {
163
0
    libcerror_error_set(
164
0
     error,
165
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
166
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
167
0
     "%s: unable to initialize read/write lock.",
168
0
     function );
169
170
0
    goto on_error;
171
0
  }
172
1.53k
#endif
173
1.53k
  internal_file_entry->io_handle       = io_handle;
174
1.53k
  internal_file_entry->file_io_handle  = file_io_handle;
175
1.53k
  internal_file_entry->file_system     = file_system;
176
1.53k
  internal_file_entry->inode_number    = inode_number;
177
1.53k
  internal_file_entry->inode           = inode;
178
1.53k
  internal_file_entry->directory_entry = directory_entry;
179
180
1.53k
  *file_entry = (libfsxfs_file_entry_t *) internal_file_entry;
181
182
1.53k
  return( 1 );
183
184
203
on_error:
185
203
  if( internal_file_entry != NULL )
186
203
  {
187
203
    memory_free(
188
203
     internal_file_entry );
189
203
  }
190
203
  return( -1 );
191
1.53k
}
192
193
/* Frees a file entry
194
 * Returns 1 if successful or -1 on error
195
 */
196
int libfsxfs_file_entry_free(
197
     libfsxfs_file_entry_t **file_entry,
198
     libcerror_error_t **error )
199
1.69k
{
200
1.69k
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
201
1.69k
  static char *function                               = "libfsxfs_file_entry_free";
202
1.69k
  int result                                          = 1;
203
204
1.69k
  if( file_entry == NULL )
205
0
  {
206
0
    libcerror_error_set(
207
0
     error,
208
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
209
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
210
0
     "%s: invalid file entry.",
211
0
     function );
212
213
0
    return( -1 );
214
0
  }
215
1.69k
  if( *file_entry != NULL )
216
1.53k
  {
217
1.53k
    internal_file_entry = (libfsxfs_internal_file_entry_t *) *file_entry;
218
1.53k
    *file_entry         = NULL;
219
220
1.53k
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
221
1.53k
    if( libcthreads_read_write_lock_free(
222
1.53k
         &( internal_file_entry->read_write_lock ),
223
1.53k
         error ) != 1 )
224
0
    {
225
0
      libcerror_error_set(
226
0
       error,
227
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
228
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
229
0
       "%s: unable to free read/write lock.",
230
0
       function );
231
232
0
      result = -1;
233
0
    }
234
1.53k
#endif
235
    /* The io_handle and file_io_handle references are freed elsewhere
236
     */
237
1.53k
    if( libfsxfs_inode_free(
238
1.53k
         &( internal_file_entry->inode ),
239
1.53k
         error ) != 1 )
240
0
    {
241
0
      libcerror_error_set(
242
0
       error,
243
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
244
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
245
0
       "%s: unable to free inode.",
246
0
       function );
247
248
0
      result = -1;
249
0
    }
250
1.53k
    if( internal_file_entry->directory_entry != NULL )
251
455
    {
252
455
      if( libfsxfs_directory_entry_free(
253
455
           &( internal_file_entry->directory_entry ),
254
455
           error ) != 1 )
255
0
      {
256
0
        libcerror_error_set(
257
0
         error,
258
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
259
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
260
0
         "%s: unable to free directory entry.",
261
0
         function );
262
263
0
        result = -1;
264
0
      }
265
455
    }
266
1.53k
    if( internal_file_entry->extended_attributes_array != NULL )
267
0
    {
268
0
      if( libcdata_array_free(
269
0
           &( internal_file_entry->extended_attributes_array ),
270
0
           (int (*)(intptr_t **, libcerror_error_t **)) &libfsxfs_attribute_values_free,
271
0
           error ) != 1 )
272
0
      {
273
0
        libcerror_error_set(
274
0
         error,
275
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
276
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
277
0
         "%s: unable to free extended attributes array.",
278
0
         function );
279
280
0
        result = -1;
281
0
      }
282
0
    }
283
1.53k
    if( internal_file_entry->directory != NULL )
284
674
    {
285
674
      if( libfsxfs_directory_free(
286
674
           &( internal_file_entry->directory ),
287
674
           error ) != 1 )
288
0
      {
289
0
        libcerror_error_set(
290
0
         error,
291
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
292
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
293
0
         "%s: unable to free directory.",
294
0
         function );
295
296
0
        result = -1;
297
0
      }
298
674
    }
299
1.53k
    if( internal_file_entry->data_stream != NULL )
300
443
    {
301
443
      if( libfdata_stream_free(
302
443
           &( internal_file_entry->data_stream ),
303
443
           error ) != 1 )
304
0
      {
305
0
        libcerror_error_set(
306
0
         error,
307
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
308
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
309
0
         "%s: unable to free data stream.",
310
0
         function );
311
312
0
        result = -1;
313
0
      }
314
443
    }
315
1.53k
    if( internal_file_entry->symbolic_link_data != NULL )
316
213
    {
317
213
      memory_free(
318
213
       internal_file_entry->symbolic_link_data );
319
213
    }
320
1.53k
    memory_free(
321
1.53k
     internal_file_entry );
322
1.53k
  }
323
1.69k
  return( result );
324
1.69k
}
325
326
/* Determines the directory
327
 * Returns 1 if successful or -1 on error
328
 */
329
int libfsxfs_internal_file_entry_get_directory(
330
     libfsxfs_internal_file_entry_t *internal_file_entry,
331
     libcerror_error_t **error )
332
1.08k
{
333
1.08k
  static char *function = "libfsxfs_internal_file_entry_get_directory";
334
335
1.08k
  if( internal_file_entry == NULL )
336
0
  {
337
0
    libcerror_error_set(
338
0
     error,
339
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
340
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
341
0
     "%s: invalid file entry.",
342
0
     function );
343
344
0
    return( -1 );
345
0
  }
346
1.08k
  if( internal_file_entry->inode == NULL )
347
0
  {
348
0
    libcerror_error_set(
349
0
     error,
350
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
351
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
352
0
     "%s: invalid file entry - missing inode.",
353
0
     function );
354
355
0
    return( -1 );
356
0
  }
357
1.08k
  if( internal_file_entry->directory != NULL )
358
0
  {
359
0
    libcerror_error_set(
360
0
     error,
361
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
362
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
363
0
     "%s: invalid file entry - directory value already set.",
364
0
     function );
365
366
0
    return( -1 );
367
0
  }
368
1.08k
  if( ( internal_file_entry->inode->file_mode & 0xf000 ) == LIBFSXFS_FILE_TYPE_DIRECTORY )
369
1.05k
  {
370
1.05k
    if( libfsxfs_directory_initialize(
371
1.05k
         &( internal_file_entry->directory ),
372
1.05k
         error ) != 1 )
373
0
    {
374
0
      libcerror_error_set(
375
0
       error,
376
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
377
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
378
0
       "%s: unable to create directory.",
379
0
       function );
380
381
0
      goto on_error;
382
0
    }
383
1.05k
    if( libfsxfs_directory_read_file_io_handle(
384
1.05k
         internal_file_entry->directory,
385
1.05k
         internal_file_entry->io_handle,
386
1.05k
         internal_file_entry->file_io_handle,
387
1.05k
         internal_file_entry->inode,
388
1.05k
         error ) != 1 )
389
376
    {
390
376
      libcerror_error_set(
391
376
       error,
392
376
       LIBCERROR_ERROR_DOMAIN_IO,
393
376
       LIBCERROR_IO_ERROR_READ_FAILED,
394
376
       "%s: unable to read directory for inode: %" PRIu32 ".",
395
376
       function,
396
376
       internal_file_entry->inode_number );
397
398
376
      goto on_error;
399
376
    }
400
1.05k
  }
401
706
  return( 1 );
402
403
376
on_error:
404
376
  if( internal_file_entry->directory != NULL )
405
376
  {
406
376
    libfsxfs_directory_free(
407
376
     &( internal_file_entry->directory ),
408
376
     NULL );
409
376
  }
410
376
  return( -1 );
411
1.08k
}
412
413
/* Determines the symbolic link data
414
 * Returns 1 if successful or -1 on error
415
 */
416
int libfsxfs_internal_file_entry_get_symbolic_link_data(
417
     libfsxfs_internal_file_entry_t *internal_file_entry,
418
     libcerror_error_t **error )
419
697
{
420
697
  static char *function = "libfsxfs_internal_file_entry_get_symbolic_link_data";
421
697
  ssize_t read_count    = 0;
422
423
697
  if( internal_file_entry == NULL )
424
0
  {
425
0
    libcerror_error_set(
426
0
     error,
427
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
428
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
429
0
     "%s: invalid file entry.",
430
0
     function );
431
432
0
    return( -1 );
433
0
  }
434
697
  if( internal_file_entry->inode == NULL )
435
0
  {
436
0
    libcerror_error_set(
437
0
     error,
438
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
439
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
440
0
     "%s: invalid file entry - missing inode.",
441
0
     function );
442
443
0
    return( -1 );
444
0
  }
445
697
  if( internal_file_entry->symbolic_link_data != NULL )
446
0
  {
447
0
    libcerror_error_set(
448
0
     error,
449
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
450
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
451
0
     "%s: invalid file entry - symbolic link data value already set.",
452
0
     function );
453
454
0
    return( -1 );
455
0
  }
456
697
  if( ( internal_file_entry->inode->file_mode & 0xf000 ) == LIBFSXFS_FILE_TYPE_SYMBOLIC_LINK )
457
631
  {
458
631
    if( ( internal_file_entry->data_size == 0 )
459
631
     || ( internal_file_entry->data_size > (uint64_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
460
46
    {
461
46
      libcerror_error_set(
462
46
       error,
463
46
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
464
46
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
465
46
       "%s: invalid data size value out of bounds.",
466
46
       function );
467
468
46
      goto on_error;
469
46
    }
470
585
    internal_file_entry->symbolic_link_data = (uint8_t *) memory_allocate(
471
585
                                                           sizeof( uint8_t ) * (size_t) internal_file_entry->data_size );
472
473
585
    if( internal_file_entry->symbolic_link_data == NULL )
474
0
    {
475
0
      libcerror_error_set(
476
0
       error,
477
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
478
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
479
0
       "%s: unable to create symbolic link data.",
480
0
       function );
481
482
0
      goto on_error;
483
0
    }
484
585
    internal_file_entry->symbolic_link_data_size = (size_t) internal_file_entry->data_size;
485
486
585
    read_count = libfdata_stream_read_buffer_at_offset(
487
585
                  internal_file_entry->data_stream,
488
585
                  (intptr_t *) internal_file_entry->file_io_handle,
489
585
                  internal_file_entry->symbolic_link_data,
490
585
                  (size_t) internal_file_entry->data_size,
491
585
                  0,
492
585
                  0,
493
585
                  error );
494
495
585
    if( read_count != (ssize_t) internal_file_entry->data_size )
496
372
    {
497
372
      libcerror_error_set(
498
372
       error,
499
372
       LIBCERROR_ERROR_DOMAIN_IO,
500
372
       LIBCERROR_IO_ERROR_READ_FAILED,
501
372
       "%s: unable to read from data stream.",
502
372
       function );
503
504
372
      goto on_error;
505
372
    }
506
#if defined( HAVE_DEBUG_OUTPUT )
507
    if( libcnotify_verbose != 0 )
508
    {
509
      libcnotify_printf(
510
       "%s: symbolic link data:\n",
511
       function );
512
      libcnotify_print_data(
513
       internal_file_entry->symbolic_link_data,
514
       internal_file_entry->symbolic_link_data_size,
515
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
516
    }
517
#endif
518
585
  }
519
279
  return( 1 );
520
521
418
on_error:
522
418
  if( internal_file_entry->symbolic_link_data != NULL )
523
372
  {
524
372
    memory_free(
525
372
     internal_file_entry->symbolic_link_data );
526
527
372
    internal_file_entry->symbolic_link_data = NULL;
528
372
  }
529
418
  internal_file_entry->symbolic_link_data_size = 0;
530
531
418
  return( -1 );
532
697
}
533
534
/* Retrieves the inode number
535
 * Returns 1 if successful or -1 on error
536
 */
537
int libfsxfs_file_entry_get_inode_number(
538
     libfsxfs_file_entry_t *file_entry,
539
     uint64_t *inode_number,
540
     libcerror_error_t **error )
541
455
{
542
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
543
455
  static char *function                               = "libfsxfs_file_entry_get_inode_number";
544
545
455
  if( file_entry == NULL )
546
0
  {
547
0
    libcerror_error_set(
548
0
     error,
549
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
550
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
551
0
     "%s: invalid file entry.",
552
0
     function );
553
554
0
    return( -1 );
555
0
  }
556
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
557
558
455
  if( inode_number == NULL )
559
0
  {
560
0
    libcerror_error_set(
561
0
     error,
562
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
563
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
564
0
     "%s: invalid inode number.",
565
0
     function );
566
567
0
    return( -1 );
568
0
  }
569
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
570
455
  if( libcthreads_read_write_lock_grab_for_read(
571
455
       internal_file_entry->read_write_lock,
572
455
       error ) != 1 )
573
0
  {
574
0
    libcerror_error_set(
575
0
     error,
576
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
577
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
578
0
     "%s: unable to grab read/write lock for reading.",
579
0
     function );
580
581
0
    return( -1 );
582
0
  }
583
455
#endif
584
455
  *inode_number = internal_file_entry->inode_number;
585
586
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
587
455
  if( libcthreads_read_write_lock_release_for_read(
588
455
       internal_file_entry->read_write_lock,
589
455
       error ) != 1 )
590
0
  {
591
0
    libcerror_error_set(
592
0
     error,
593
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
594
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
595
0
     "%s: unable to release read/write lock for reading.",
596
0
     function );
597
598
0
    return( -1 );
599
0
  }
600
455
#endif
601
455
  return( 1 );
602
455
}
603
604
/* Retrieves the creation date and time
605
 * The timestamp is a signed 64-bit POSIX date and time value in number of nano seconds
606
 * This value is retrieved from the inode
607
 * Returns 1 if successful, 0 if not available or -1 on error
608
 */
609
int libfsxfs_file_entry_get_creation_time(
610
     libfsxfs_file_entry_t *file_entry,
611
     int64_t *posix_time,
612
     libcerror_error_t **error )
613
455
{
614
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
615
455
  static char *function                               = "libfsxfs_file_entry_get_creation_time";
616
455
  int result                                          = 1;
617
618
455
  if( file_entry == NULL )
619
0
  {
620
0
    libcerror_error_set(
621
0
     error,
622
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
623
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
624
0
     "%s: invalid file entry.",
625
0
     function );
626
627
0
    return( -1 );
628
0
  }
629
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
630
631
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
632
455
  if( libcthreads_read_write_lock_grab_for_read(
633
455
       internal_file_entry->read_write_lock,
634
455
       error ) != 1 )
635
0
  {
636
0
    libcerror_error_set(
637
0
     error,
638
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
639
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
640
0
     "%s: unable to grab read/write lock for reading.",
641
0
     function );
642
643
0
    return( -1 );
644
0
  }
645
455
#endif
646
455
  result = libfsxfs_inode_get_creation_time(
647
455
            internal_file_entry->inode,
648
455
            posix_time,
649
455
            error );
650
651
455
  if( result == -1 )
652
0
  {
653
0
    libcerror_error_set(
654
0
     error,
655
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
656
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
657
0
     "%s: unable to retrieve creation time.",
658
0
     function );
659
660
0
    result = -1;
661
0
  }
662
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
663
455
  if( libcthreads_read_write_lock_release_for_read(
664
455
       internal_file_entry->read_write_lock,
665
455
       error ) != 1 )
666
0
  {
667
0
    libcerror_error_set(
668
0
     error,
669
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
670
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
671
0
     "%s: unable to release read/write lock for reading.",
672
0
     function );
673
674
0
    return( -1 );
675
0
  }
676
455
#endif
677
455
  return( result );
678
455
}
679
680
/* Retrieves the modification date and time
681
 * The timestamp is a signed 64-bit POSIX date and time value in number of nano seconds
682
 * This value is retrieved from the inode
683
 * Returns 1 if successful or -1 on error
684
 */
685
int libfsxfs_file_entry_get_modification_time(
686
     libfsxfs_file_entry_t *file_entry,
687
     int64_t *posix_time,
688
     libcerror_error_t **error )
689
455
{
690
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
691
455
  static char *function                               = "libfsxfs_file_entry_get_modification_time";
692
455
  int result                                          = 1;
693
694
455
  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
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
706
707
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
708
455
  if( libcthreads_read_write_lock_grab_for_read(
709
455
       internal_file_entry->read_write_lock,
710
455
       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
455
#endif
722
455
  if( libfsxfs_inode_get_modification_time(
723
455
       internal_file_entry->inode,
724
455
       posix_time,
725
455
       error ) != 1 )
726
0
  {
727
0
    libcerror_error_set(
728
0
     error,
729
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
730
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
731
0
     "%s: unable to retrieve modification time.",
732
0
     function );
733
734
0
    result = -1;
735
0
  }
736
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
737
455
  if( libcthreads_read_write_lock_release_for_read(
738
455
       internal_file_entry->read_write_lock,
739
455
       error ) != 1 )
740
0
  {
741
0
    libcerror_error_set(
742
0
     error,
743
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
744
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
745
0
     "%s: unable to release read/write lock for reading.",
746
0
     function );
747
748
0
    return( -1 );
749
0
  }
750
455
#endif
751
455
  return( result );
752
455
}
753
754
/* Retrieves the access date and time
755
 * The timestamp is a signed 64-bit POSIX date and time value in number of nano seconds
756
 * This value is retrieved from the inode
757
 * Returns 1 if successful or -1 on error
758
 */
759
int libfsxfs_file_entry_get_access_time(
760
     libfsxfs_file_entry_t *file_entry,
761
     int64_t *posix_time,
762
     libcerror_error_t **error )
763
455
{
764
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
765
455
  static char *function                               = "libfsxfs_file_entry_get_access_time";
766
455
  int result                                          = 1;
767
768
455
  if( file_entry == NULL )
769
0
  {
770
0
    libcerror_error_set(
771
0
     error,
772
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
773
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
774
0
     "%s: invalid file entry.",
775
0
     function );
776
777
0
    return( -1 );
778
0
  }
779
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
780
781
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
782
455
  if( libcthreads_read_write_lock_grab_for_read(
783
455
       internal_file_entry->read_write_lock,
784
455
       error ) != 1 )
785
0
  {
786
0
    libcerror_error_set(
787
0
     error,
788
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
789
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
790
0
     "%s: unable to grab read/write lock for reading.",
791
0
     function );
792
793
0
    return( -1 );
794
0
  }
795
455
#endif
796
455
  if( libfsxfs_inode_get_access_time(
797
455
       internal_file_entry->inode,
798
455
       posix_time,
799
455
       error ) != 1 )
800
0
  {
801
0
    libcerror_error_set(
802
0
     error,
803
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
804
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
805
0
     "%s: unable to retrieve access time.",
806
0
     function );
807
808
0
    result = -1;
809
0
  }
810
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
811
455
  if( libcthreads_read_write_lock_release_for_read(
812
455
       internal_file_entry->read_write_lock,
813
455
       error ) != 1 )
814
0
  {
815
0
    libcerror_error_set(
816
0
     error,
817
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
818
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
819
0
     "%s: unable to release read/write lock for reading.",
820
0
     function );
821
822
0
    return( -1 );
823
0
  }
824
455
#endif
825
455
  return( result );
826
455
}
827
828
/* Retrieves the inode change date and time
829
 * The timestamp is a signed 64-bit POSIX date and time value in number of nano seconds
830
 * This value is retrieved from the inode
831
 * Returns 1 if successful or -1 on error
832
 */
833
int libfsxfs_file_entry_get_inode_change_time(
834
     libfsxfs_file_entry_t *file_entry,
835
     int64_t *posix_time,
836
     libcerror_error_t **error )
837
455
{
838
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
839
455
  static char *function                               = "libfsxfs_file_entry_get_inode_change_time";
840
455
  int result                                          = 1;
841
842
455
  if( file_entry == NULL )
843
0
  {
844
0
    libcerror_error_set(
845
0
     error,
846
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
847
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
848
0
     "%s: invalid file entry.",
849
0
     function );
850
851
0
    return( -1 );
852
0
  }
853
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
854
855
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
856
455
  if( libcthreads_read_write_lock_grab_for_read(
857
455
       internal_file_entry->read_write_lock,
858
455
       error ) != 1 )
859
0
  {
860
0
    libcerror_error_set(
861
0
     error,
862
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
863
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
864
0
     "%s: unable to grab read/write lock for reading.",
865
0
     function );
866
867
0
    return( -1 );
868
0
  }
869
455
#endif
870
455
  if( libfsxfs_inode_get_inode_change_time(
871
455
       internal_file_entry->inode,
872
455
       posix_time,
873
455
       error ) != 1 )
874
0
  {
875
0
    libcerror_error_set(
876
0
     error,
877
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
878
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
879
0
     "%s: unable to retrieve inode change time.",
880
0
     function );
881
882
0
    result = -1;
883
0
  }
884
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
885
455
  if( libcthreads_read_write_lock_release_for_read(
886
455
       internal_file_entry->read_write_lock,
887
455
       error ) != 1 )
888
0
  {
889
0
    libcerror_error_set(
890
0
     error,
891
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
892
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
893
0
     "%s: unable to release read/write lock for reading.",
894
0
     function );
895
896
0
    return( -1 );
897
0
  }
898
455
#endif
899
455
  return( result );
900
455
}
901
902
/* Retrieves the file mode
903
 * This value is retrieved from the inode
904
 * Returns 1 if successful or -1 on error
905
 */
906
int libfsxfs_file_entry_get_file_mode(
907
     libfsxfs_file_entry_t *file_entry,
908
     uint16_t *file_mode,
909
     libcerror_error_t **error )
910
455
{
911
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
912
455
  static char *function                               = "libfsxfs_file_entry_get_file_mode";
913
455
  int result                                          = 1;
914
915
455
  if( file_entry == NULL )
916
0
  {
917
0
    libcerror_error_set(
918
0
     error,
919
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
920
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
921
0
     "%s: invalid file entry.",
922
0
     function );
923
924
0
    return( -1 );
925
0
  }
926
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
927
928
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
929
455
  if( libcthreads_read_write_lock_grab_for_read(
930
455
       internal_file_entry->read_write_lock,
931
455
       error ) != 1 )
932
0
  {
933
0
    libcerror_error_set(
934
0
     error,
935
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
936
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
937
0
     "%s: unable to grab read/write lock for reading.",
938
0
     function );
939
940
0
    return( -1 );
941
0
  }
942
455
#endif
943
455
  if( libfsxfs_inode_get_file_mode(
944
455
       internal_file_entry->inode,
945
455
       file_mode,
946
455
       error ) != 1 )
947
0
  {
948
0
    libcerror_error_set(
949
0
     error,
950
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
951
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
952
0
     "%s: unable to retrieve file mode.",
953
0
     function );
954
955
0
    result = -1;
956
0
  }
957
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
958
455
  if( libcthreads_read_write_lock_release_for_read(
959
455
       internal_file_entry->read_write_lock,
960
455
       error ) != 1 )
961
0
  {
962
0
    libcerror_error_set(
963
0
     error,
964
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
965
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
966
0
     "%s: unable to release read/write lock for reading.",
967
0
     function );
968
969
0
    return( -1 );
970
0
  }
971
455
#endif
972
455
  return( result );
973
455
}
974
975
/* Retrieves the number of (hard) links
976
 * This value is retrieved from the inode
977
 * Returns 1 if successful or -1 on error
978
 */
979
int libfsxfs_file_entry_get_number_of_links(
980
     libfsxfs_file_entry_t *file_entry,
981
     uint32_t *number_of_links,
982
     libcerror_error_t **error )
983
455
{
984
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
985
455
  static char *function                               = "libfsxfs_file_entry_get_number_of_links";
986
455
  int result                                          = 1;
987
988
455
  if( file_entry == NULL )
989
0
  {
990
0
    libcerror_error_set(
991
0
     error,
992
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
993
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
994
0
     "%s: invalid file entry.",
995
0
     function );
996
997
0
    return( -1 );
998
0
  }
999
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1000
1001
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1002
455
  if( libcthreads_read_write_lock_grab_for_read(
1003
455
       internal_file_entry->read_write_lock,
1004
455
       error ) != 1 )
1005
0
  {
1006
0
    libcerror_error_set(
1007
0
     error,
1008
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1009
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1010
0
     "%s: unable to grab read/write lock for reading.",
1011
0
     function );
1012
1013
0
    return( -1 );
1014
0
  }
1015
455
#endif
1016
455
  if( libfsxfs_inode_get_number_of_links(
1017
455
       internal_file_entry->inode,
1018
455
       number_of_links,
1019
455
       error ) != 1 )
1020
0
  {
1021
0
    libcerror_error_set(
1022
0
     error,
1023
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1024
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1025
0
     "%s: unable to retrieve number of (hard_ links.",
1026
0
     function );
1027
1028
0
    result = -1;
1029
0
  }
1030
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1031
455
  if( libcthreads_read_write_lock_release_for_read(
1032
455
       internal_file_entry->read_write_lock,
1033
455
       error ) != 1 )
1034
0
  {
1035
0
    libcerror_error_set(
1036
0
     error,
1037
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1038
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1039
0
     "%s: unable to release read/write lock for reading.",
1040
0
     function );
1041
1042
0
    return( -1 );
1043
0
  }
1044
455
#endif
1045
455
  return( result );
1046
455
}
1047
1048
/* Retrieves the owner (user) identifier
1049
 * This value is retrieved from the inode
1050
 * Returns 1 if successful or -1 on error
1051
 */
1052
int libfsxfs_file_entry_get_owner_identifier(
1053
     libfsxfs_file_entry_t *file_entry,
1054
     uint32_t *owner_identifier,
1055
     libcerror_error_t **error )
1056
455
{
1057
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1058
455
  static char *function                               = "libfsxfs_file_entry_get_owner_identifier";
1059
455
  int result                                          = 1;
1060
1061
455
  if( file_entry == NULL )
1062
0
  {
1063
0
    libcerror_error_set(
1064
0
     error,
1065
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1066
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1067
0
     "%s: invalid file entry.",
1068
0
     function );
1069
1070
0
    return( -1 );
1071
0
  }
1072
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1073
1074
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1075
455
  if( libcthreads_read_write_lock_grab_for_read(
1076
455
       internal_file_entry->read_write_lock,
1077
455
       error ) != 1 )
1078
0
  {
1079
0
    libcerror_error_set(
1080
0
     error,
1081
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1082
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1083
0
     "%s: unable to grab read/write lock for reading.",
1084
0
     function );
1085
1086
0
    return( -1 );
1087
0
  }
1088
455
#endif
1089
455
  if( libfsxfs_inode_get_owner_identifier(
1090
455
       internal_file_entry->inode,
1091
455
       owner_identifier,
1092
455
       error ) != 1 )
1093
0
  {
1094
0
    libcerror_error_set(
1095
0
     error,
1096
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1097
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1098
0
     "%s: unable to retrieve owner identifier.",
1099
0
     function );
1100
1101
0
    result = -1;
1102
0
  }
1103
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1104
455
  if( libcthreads_read_write_lock_release_for_read(
1105
455
       internal_file_entry->read_write_lock,
1106
455
       error ) != 1 )
1107
0
  {
1108
0
    libcerror_error_set(
1109
0
     error,
1110
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1111
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1112
0
     "%s: unable to release read/write lock for reading.",
1113
0
     function );
1114
1115
0
    return( -1 );
1116
0
  }
1117
455
#endif
1118
455
  return( result );
1119
455
}
1120
1121
/* Retrieves the group identifier
1122
 * This value is retrieved from the inode
1123
 * Returns 1 if successful or -1 on error
1124
 */
1125
int libfsxfs_file_entry_get_group_identifier(
1126
     libfsxfs_file_entry_t *file_entry,
1127
     uint32_t *group_identifier,
1128
     libcerror_error_t **error )
1129
455
{
1130
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1131
455
  static char *function                               = "libfsxfs_file_entry_get_group_identifier";
1132
455
  int result                                          = 1;
1133
1134
455
  if( file_entry == NULL )
1135
0
  {
1136
0
    libcerror_error_set(
1137
0
     error,
1138
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1139
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1140
0
     "%s: invalid file entry.",
1141
0
     function );
1142
1143
0
    return( -1 );
1144
0
  }
1145
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1146
1147
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1148
455
  if( libcthreads_read_write_lock_grab_for_read(
1149
455
       internal_file_entry->read_write_lock,
1150
455
       error ) != 1 )
1151
0
  {
1152
0
    libcerror_error_set(
1153
0
     error,
1154
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1155
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1156
0
     "%s: unable to grab read/write lock for reading.",
1157
0
     function );
1158
1159
0
    return( -1 );
1160
0
  }
1161
455
#endif
1162
455
  if( libfsxfs_inode_get_group_identifier(
1163
455
       internal_file_entry->inode,
1164
455
       group_identifier,
1165
455
       error ) != 1 )
1166
0
  {
1167
0
    libcerror_error_set(
1168
0
     error,
1169
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1170
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1171
0
     "%s: unable to retrieve group identifier.",
1172
0
     function );
1173
1174
0
    result = -1;
1175
0
  }
1176
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1177
455
  if( libcthreads_read_write_lock_release_for_read(
1178
455
       internal_file_entry->read_write_lock,
1179
455
       error ) != 1 )
1180
0
  {
1181
0
    libcerror_error_set(
1182
0
     error,
1183
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1184
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1185
0
     "%s: unable to release read/write lock for reading.",
1186
0
     function );
1187
1188
0
    return( -1 );
1189
0
  }
1190
455
#endif
1191
455
  return( result );
1192
455
}
1193
1194
/* Retrieves the device identifier
1195
 * This value is retrieved from the inode
1196
 * Returns 1 if successful, 0 if not available or -1 on error
1197
 */
1198
int libfsxfs_file_entry_get_device_identifier(
1199
     libfsxfs_file_entry_t *file_entry,
1200
     uint32_t *device_identifier,
1201
     libcerror_error_t **error )
1202
455
{
1203
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1204
455
  static char *function                               = "libfsxfs_file_entry_get_device_identifier";
1205
455
  int result                                          = 0;
1206
1207
455
  if( file_entry == NULL )
1208
0
  {
1209
0
    libcerror_error_set(
1210
0
     error,
1211
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1212
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1213
0
     "%s: invalid file entry.",
1214
0
     function );
1215
1216
0
    return( -1 );
1217
0
  }
1218
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1219
1220
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1221
455
  if( libcthreads_read_write_lock_grab_for_read(
1222
455
       internal_file_entry->read_write_lock,
1223
455
       error ) != 1 )
1224
0
  {
1225
0
    libcerror_error_set(
1226
0
     error,
1227
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1228
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1229
0
     "%s: unable to grab read/write lock for reading.",
1230
0
     function );
1231
1232
0
    return( -1 );
1233
0
  }
1234
455
#endif
1235
455
  result = libfsxfs_inode_get_device_identifier(
1236
455
            internal_file_entry->inode,
1237
455
            device_identifier,
1238
455
            error );
1239
1240
455
  if( result == -1 )
1241
0
  {
1242
0
    libcerror_error_set(
1243
0
     error,
1244
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1245
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1246
0
     "%s: unable to retrieve device identifier from inode.",
1247
0
     function );
1248
1249
0
    result = -1;
1250
0
  }
1251
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1252
455
  if( libcthreads_read_write_lock_release_for_read(
1253
455
       internal_file_entry->read_write_lock,
1254
455
       error ) != 1 )
1255
0
  {
1256
0
    libcerror_error_set(
1257
0
     error,
1258
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1259
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1260
0
     "%s: unable to release read/write lock for reading.",
1261
0
     function );
1262
1263
0
    return( -1 );
1264
0
  }
1265
455
#endif
1266
455
  return( result );
1267
455
}
1268
1269
/* Retrieves the device number
1270
 * This value is retrieved from the inode
1271
 * Returns 1 if successful, 0 if not available or -1 on error
1272
 */
1273
int libfsxfs_file_entry_get_device_number(
1274
     libfsxfs_file_entry_t *file_entry,
1275
     uint32_t *major_device_number,
1276
     uint32_t *minor_device_number,
1277
     libcerror_error_t **error )
1278
455
{
1279
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1280
455
  static char *function                               = "libfsxfs_file_entry_get_device_number";
1281
455
  int result                                          = 0;
1282
1283
455
  if( file_entry == NULL )
1284
0
  {
1285
0
    libcerror_error_set(
1286
0
     error,
1287
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1288
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1289
0
     "%s: invalid file entry.",
1290
0
     function );
1291
1292
0
    return( -1 );
1293
0
  }
1294
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1295
1296
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1297
455
  if( libcthreads_read_write_lock_grab_for_read(
1298
455
       internal_file_entry->read_write_lock,
1299
455
       error ) != 1 )
1300
0
  {
1301
0
    libcerror_error_set(
1302
0
     error,
1303
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1304
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1305
0
     "%s: unable to grab read/write lock for reading.",
1306
0
     function );
1307
1308
0
    return( -1 );
1309
0
  }
1310
455
#endif
1311
455
  result = libfsxfs_inode_get_device_number(
1312
455
            internal_file_entry->inode,
1313
455
            major_device_number,
1314
455
            minor_device_number,
1315
455
            error );
1316
1317
455
  if( result == -1 )
1318
0
  {
1319
0
    libcerror_error_set(
1320
0
     error,
1321
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1322
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1323
0
     "%s: unable to retrieve device number from inode.",
1324
0
     function );
1325
1326
0
    result = -1;
1327
0
  }
1328
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1329
455
  if( libcthreads_read_write_lock_release_for_read(
1330
455
       internal_file_entry->read_write_lock,
1331
455
       error ) != 1 )
1332
0
  {
1333
0
    libcerror_error_set(
1334
0
     error,
1335
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1336
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1337
0
     "%s: unable to release read/write lock for reading.",
1338
0
     function );
1339
1340
0
    return( -1 );
1341
0
  }
1342
455
#endif
1343
455
  return( result );
1344
455
}
1345
1346
/* Retrieves the size of the UTF-8 encoded name
1347
 * The returned size includes the end of string character
1348
 * This value is retrieved from the directory entry
1349
 * Returns 1 if successful, 0 if not available or -1 on error
1350
 */
1351
int libfsxfs_file_entry_get_utf8_name_size(
1352
     libfsxfs_file_entry_t *file_entry,
1353
     size_t *utf8_string_size,
1354
     libcerror_error_t **error )
1355
455
{
1356
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1357
455
  static char *function                               = "libfsxfs_file_entry_get_utf8_name_size";
1358
455
  int result                                          = 0;
1359
1360
455
  if( file_entry == NULL )
1361
0
  {
1362
0
    libcerror_error_set(
1363
0
     error,
1364
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1365
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1366
0
     "%s: invalid file entry.",
1367
0
     function );
1368
1369
0
    return( -1 );
1370
0
  }
1371
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1372
1373
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1374
455
  if( libcthreads_read_write_lock_grab_for_read(
1375
455
       internal_file_entry->read_write_lock,
1376
455
       error ) != 1 )
1377
0
  {
1378
0
    libcerror_error_set(
1379
0
     error,
1380
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1381
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1382
0
     "%s: unable to grab read/write lock for reading.",
1383
0
     function );
1384
1385
0
    return( -1 );
1386
0
  }
1387
455
#endif
1388
455
  if( internal_file_entry->directory_entry != NULL )
1389
455
  {
1390
455
    result = libfsxfs_directory_entry_get_utf8_name_size(
1391
455
              internal_file_entry->directory_entry,
1392
455
              utf8_string_size,
1393
455
              error );
1394
1395
455
    if( result != 1 )
1396
336
    {
1397
336
      libcerror_error_set(
1398
336
       error,
1399
336
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1400
336
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1401
336
       "%s: unable to retrieve size of UTF-8 name from directory entry.",
1402
336
       function );
1403
1404
336
      result = -1;
1405
336
    }
1406
455
  }
1407
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1408
455
  if( libcthreads_read_write_lock_release_for_read(
1409
455
       internal_file_entry->read_write_lock,
1410
455
       error ) != 1 )
1411
0
  {
1412
0
    libcerror_error_set(
1413
0
     error,
1414
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1415
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1416
0
     "%s: unable to release read/write lock for reading.",
1417
0
     function );
1418
1419
0
    return( -1 );
1420
0
  }
1421
455
#endif
1422
455
  return( result );
1423
455
}
1424
1425
/* Retrieves the UTF-8 encoded name
1426
 * The size should include the end of string character
1427
 * This value is retrieved from the directory entry
1428
 * Returns 1 if successful, 0 if not available or -1 on error
1429
 */
1430
int libfsxfs_file_entry_get_utf8_name(
1431
     libfsxfs_file_entry_t *file_entry,
1432
     uint8_t *utf8_string,
1433
     size_t utf8_string_size,
1434
     libcerror_error_t **error )
1435
455
{
1436
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1437
455
  static char *function                               = "libfsxfs_file_entry_get_utf8_name";
1438
455
  int result                                          = 0;
1439
1440
455
  if( file_entry == NULL )
1441
0
  {
1442
0
    libcerror_error_set(
1443
0
     error,
1444
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1445
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1446
0
     "%s: invalid file entry.",
1447
0
     function );
1448
1449
0
    return( -1 );
1450
0
  }
1451
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1452
1453
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1454
455
  if( libcthreads_read_write_lock_grab_for_read(
1455
455
       internal_file_entry->read_write_lock,
1456
455
       error ) != 1 )
1457
0
  {
1458
0
    libcerror_error_set(
1459
0
     error,
1460
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1461
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1462
0
     "%s: unable to grab read/write lock for reading.",
1463
0
     function );
1464
1465
0
    return( -1 );
1466
0
  }
1467
455
#endif
1468
455
  if( internal_file_entry->directory_entry != NULL )
1469
455
  {
1470
455
    result = libfsxfs_directory_entry_get_utf8_name(
1471
455
              internal_file_entry->directory_entry,
1472
455
              utf8_string,
1473
455
              utf8_string_size,
1474
455
              error );
1475
1476
455
    if( result != 1 )
1477
351
    {
1478
351
      libcerror_error_set(
1479
351
       error,
1480
351
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1481
351
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1482
351
       "%s: unable to retrieve UTF-8 name from directory entry.",
1483
351
       function );
1484
1485
351
      result = -1;
1486
351
    }
1487
455
  }
1488
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1489
455
  if( libcthreads_read_write_lock_release_for_read(
1490
455
       internal_file_entry->read_write_lock,
1491
455
       error ) != 1 )
1492
0
  {
1493
0
    libcerror_error_set(
1494
0
     error,
1495
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1496
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1497
0
     "%s: unable to release read/write lock for reading.",
1498
0
     function );
1499
1500
0
    return( -1 );
1501
0
  }
1502
455
#endif
1503
455
  return( result );
1504
455
}
1505
1506
/* Retrieves the size of the UTF-16 encoded name
1507
 * The returned size includes the end of string character
1508
 * This value is retrieved from the directory entry
1509
 * Returns 1 if successful, 0 if not available or -1 on error
1510
 */
1511
int libfsxfs_file_entry_get_utf16_name_size(
1512
     libfsxfs_file_entry_t *file_entry,
1513
     size_t *utf16_string_size,
1514
     libcerror_error_t **error )
1515
0
{
1516
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1517
0
  static char *function                               = "libfsxfs_file_entry_get_utf16_name_size";
1518
0
  int result                                          = 0;
1519
1520
0
  if( file_entry == NULL )
1521
0
  {
1522
0
    libcerror_error_set(
1523
0
     error,
1524
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1525
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1526
0
     "%s: invalid file entry.",
1527
0
     function );
1528
1529
0
    return( -1 );
1530
0
  }
1531
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1532
1533
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1534
0
  if( libcthreads_read_write_lock_grab_for_read(
1535
0
       internal_file_entry->read_write_lock,
1536
0
       error ) != 1 )
1537
0
  {
1538
0
    libcerror_error_set(
1539
0
     error,
1540
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1541
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1542
0
     "%s: unable to grab read/write lock for reading.",
1543
0
     function );
1544
1545
0
    return( -1 );
1546
0
  }
1547
0
#endif
1548
0
  if( internal_file_entry->directory_entry != NULL )
1549
0
  {
1550
0
    result = libfsxfs_directory_entry_get_utf16_name_size(
1551
0
              internal_file_entry->directory_entry,
1552
0
              utf16_string_size,
1553
0
              error );
1554
1555
0
    if( result != 1 )
1556
0
    {
1557
0
      libcerror_error_set(
1558
0
       error,
1559
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1560
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1561
0
       "%s: unable to retrieve size of UTF-16 name from directory entry.",
1562
0
       function );
1563
1564
0
      result = -1;
1565
0
    }
1566
0
  }
1567
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1568
0
  if( libcthreads_read_write_lock_release_for_read(
1569
0
       internal_file_entry->read_write_lock,
1570
0
       error ) != 1 )
1571
0
  {
1572
0
    libcerror_error_set(
1573
0
     error,
1574
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1575
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1576
0
     "%s: unable to release read/write lock for reading.",
1577
0
     function );
1578
1579
0
    return( -1 );
1580
0
  }
1581
0
#endif
1582
0
  return( result );
1583
0
}
1584
1585
/* Retrieves the UTF-16 encoded name
1586
 * The size should include the end of string character
1587
 * This value is retrieved from the directory entry
1588
 * Returns 1 if successful, 0 if not available or -1 on error
1589
 */
1590
int libfsxfs_file_entry_get_utf16_name(
1591
     libfsxfs_file_entry_t *file_entry,
1592
     uint16_t *utf16_string,
1593
     size_t utf16_string_size,
1594
     libcerror_error_t **error )
1595
0
{
1596
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1597
0
  static char *function                               = "libfsxfs_file_entry_get_utf16_name";
1598
0
  int result                                          = 0;
1599
1600
0
  if( file_entry == NULL )
1601
0
  {
1602
0
    libcerror_error_set(
1603
0
     error,
1604
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1605
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1606
0
     "%s: invalid file entry.",
1607
0
     function );
1608
1609
0
    return( -1 );
1610
0
  }
1611
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1612
1613
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1614
0
  if( libcthreads_read_write_lock_grab_for_read(
1615
0
       internal_file_entry->read_write_lock,
1616
0
       error ) != 1 )
1617
0
  {
1618
0
    libcerror_error_set(
1619
0
     error,
1620
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1621
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1622
0
     "%s: unable to grab read/write lock for reading.",
1623
0
     function );
1624
1625
0
    return( -1 );
1626
0
  }
1627
0
#endif
1628
0
  if( internal_file_entry->directory_entry != NULL )
1629
0
  {
1630
0
    result = libfsxfs_directory_entry_get_utf16_name(
1631
0
              internal_file_entry->directory_entry,
1632
0
              utf16_string,
1633
0
              utf16_string_size,
1634
0
              error );
1635
1636
0
    if( result != 1 )
1637
0
    {
1638
0
      libcerror_error_set(
1639
0
       error,
1640
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1641
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1642
0
       "%s: unable to retrieve UTF-16 name from directory entry.",
1643
0
       function );
1644
1645
0
      result = -1;
1646
0
    }
1647
0
  }
1648
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1649
0
  if( libcthreads_read_write_lock_release_for_read(
1650
0
       internal_file_entry->read_write_lock,
1651
0
       error ) != 1 )
1652
0
  {
1653
0
    libcerror_error_set(
1654
0
     error,
1655
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1656
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1657
0
     "%s: unable to release read/write lock for reading.",
1658
0
     function );
1659
1660
0
    return( -1 );
1661
0
  }
1662
0
#endif
1663
0
  return( result );
1664
0
}
1665
1666
/* Retrieves the size of the UTF-8 encoded symbolic link target
1667
 * The size should include the end of string character
1668
 * Returns 1 if successful, 0 if not available or -1 on error
1669
 */
1670
int libfsxfs_file_entry_get_utf8_symbolic_link_target_size(
1671
     libfsxfs_file_entry_t *file_entry,
1672
     size_t *utf8_string_size,
1673
     libcerror_error_t **error )
1674
455
{
1675
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1676
455
  static char *function                               = "libfsxfs_file_entry_get_utf8_symbolic_link_target_size";
1677
455
  int result                                          = 0;
1678
1679
455
  if( file_entry == NULL )
1680
0
  {
1681
0
    libcerror_error_set(
1682
0
     error,
1683
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1684
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1685
0
     "%s: invalid file entry.",
1686
0
     function );
1687
1688
0
    return( -1 );
1689
0
  }
1690
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1691
1692
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1693
455
  if( libcthreads_read_write_lock_grab_for_write(
1694
455
       internal_file_entry->read_write_lock,
1695
455
       error ) != 1 )
1696
0
  {
1697
0
    libcerror_error_set(
1698
0
     error,
1699
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1700
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1701
0
     "%s: unable to grab read/write lock for writing.",
1702
0
     function );
1703
1704
0
    return( -1 );
1705
0
  }
1706
455
#endif
1707
455
  if( internal_file_entry->symbolic_link_data == NULL )
1708
455
  {
1709
455
    if( libfsxfs_internal_file_entry_get_symbolic_link_data(
1710
455
         internal_file_entry,
1711
455
         error ) != 1 )
1712
209
    {
1713
209
      libcerror_error_set(
1714
209
       error,
1715
209
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1716
209
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1717
209
       "%s: unable to determine symbolic link data.",
1718
209
       function );
1719
1720
209
      result = -1;
1721
209
    }
1722
455
  }
1723
455
  if( internal_file_entry->symbolic_link_data != NULL )
1724
213
  {
1725
213
    result = libuna_utf8_string_size_from_utf8_stream(
1726
213
              internal_file_entry->symbolic_link_data,
1727
213
              internal_file_entry->symbolic_link_data_size,
1728
213
              utf8_string_size,
1729
213
              error );
1730
1731
213
    if( result != 1 )
1732
101
    {
1733
101
      libcerror_error_set(
1734
101
       error,
1735
101
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1736
101
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1737
101
       "%s: unable to retrieve UTF-8 string size.",
1738
101
       function );
1739
1740
101
      result = -1;
1741
101
    }
1742
213
  }
1743
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1744
455
  if( libcthreads_read_write_lock_release_for_write(
1745
455
       internal_file_entry->read_write_lock,
1746
455
       error ) != 1 )
1747
0
  {
1748
0
    libcerror_error_set(
1749
0
     error,
1750
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1751
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1752
0
     "%s: unable to release read/write lock for writing.",
1753
0
     function );
1754
1755
0
    return( -1 );
1756
0
  }
1757
455
#endif
1758
455
  return( result );
1759
455
}
1760
1761
/* Retrieves the UTF-8 encoded symbolic link target
1762
 * The size should include the end of string character
1763
 * Returns 1 if successful, 0 if not available or -1 on error
1764
 */
1765
int libfsxfs_file_entry_get_utf8_symbolic_link_target(
1766
     libfsxfs_file_entry_t *file_entry,
1767
     uint8_t *utf8_string,
1768
     size_t utf8_string_size,
1769
     libcerror_error_t **error )
1770
455
{
1771
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1772
455
  static char *function                               = "libfsxfs_file_entry_get_utf8_symbolic_link_target";
1773
455
  int result                                          = 0;
1774
1775
455
  if( file_entry == NULL )
1776
0
  {
1777
0
    libcerror_error_set(
1778
0
     error,
1779
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1780
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1781
0
     "%s: invalid file entry.",
1782
0
     function );
1783
1784
0
    return( -1 );
1785
0
  }
1786
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1787
1788
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1789
455
  if( libcthreads_read_write_lock_grab_for_write(
1790
455
       internal_file_entry->read_write_lock,
1791
455
       error ) != 1 )
1792
0
  {
1793
0
    libcerror_error_set(
1794
0
     error,
1795
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1796
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1797
0
     "%s: unable to grab read/write lock for writing.",
1798
0
     function );
1799
1800
0
    return( -1 );
1801
0
  }
1802
455
#endif
1803
455
  if( internal_file_entry->symbolic_link_data == NULL )
1804
242
  {
1805
242
    if( libfsxfs_internal_file_entry_get_symbolic_link_data(
1806
242
         internal_file_entry,
1807
242
         error ) != 1 )
1808
209
    {
1809
209
      libcerror_error_set(
1810
209
       error,
1811
209
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1812
209
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1813
209
       "%s: unable to determine symbolic link data.",
1814
209
       function );
1815
1816
209
      result = -1;
1817
209
    }
1818
242
  }
1819
455
  if( internal_file_entry->symbolic_link_data != NULL )
1820
213
  {
1821
213
    result = libuna_utf8_string_copy_from_utf8_stream(
1822
213
              utf8_string,
1823
213
              utf8_string_size,
1824
213
              internal_file_entry->symbolic_link_data,
1825
213
              internal_file_entry->symbolic_link_data_size,
1826
213
              error );
1827
1828
213
    if( result != 1 )
1829
108
    {
1830
108
      libcerror_error_set(
1831
108
       error,
1832
108
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1833
108
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1834
108
       "%s: unable to retrieve UTF-8 string.",
1835
108
       function );
1836
1837
108
      result = -1;
1838
108
    }
1839
213
  }
1840
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1841
455
  if( libcthreads_read_write_lock_release_for_write(
1842
455
       internal_file_entry->read_write_lock,
1843
455
       error ) != 1 )
1844
0
  {
1845
0
    libcerror_error_set(
1846
0
     error,
1847
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1848
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1849
0
     "%s: unable to release read/write lock for writing.",
1850
0
     function );
1851
1852
0
    return( -1 );
1853
0
  }
1854
455
#endif
1855
455
  return( result );
1856
455
}
1857
1858
/* Determines the extended attributes
1859
 * Returns 1 if successful or -1 on error
1860
 */
1861
int libfsxfs_internal_file_entry_get_extended_attributes(
1862
     libfsxfs_internal_file_entry_t *internal_file_entry,
1863
     libcerror_error_t **error )
1864
0
{
1865
0
  static char *function = "libfsxfs_internal_file_entry_get_extended_attributes";
1866
1867
0
  if( internal_file_entry == NULL )
1868
0
  {
1869
0
    libcerror_error_set(
1870
0
     error,
1871
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1872
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1873
0
     "%s: invalid file entry.",
1874
0
     function );
1875
1876
0
    return( -1 );
1877
0
  }
1878
0
  if( internal_file_entry->extended_attributes_array != NULL )
1879
0
  {
1880
0
    libcerror_error_set(
1881
0
     error,
1882
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1883
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
1884
0
     "%s: invalid file entry - extended attributes array value already set.",
1885
0
     function );
1886
1887
0
    return( -1 );
1888
0
  }
1889
0
  if( libcdata_array_initialize(
1890
0
       &( internal_file_entry->extended_attributes_array ),
1891
0
       0,
1892
0
       error ) != 1 )
1893
0
  {
1894
0
    libcerror_error_set(
1895
0
     error,
1896
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1897
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1898
0
     "%s: unable to create extended attributes array.",
1899
0
     function );
1900
1901
0
    goto on_error;
1902
0
  }
1903
0
  if( libfsxfs_attributes_get_from_inode(
1904
0
       internal_file_entry->io_handle,
1905
0
       internal_file_entry->file_io_handle,
1906
0
       internal_file_entry->inode,
1907
0
       internal_file_entry->extended_attributes_array,
1908
0
       error ) != 1 )
1909
0
  {
1910
0
    libcerror_error_set(
1911
0
     error,
1912
0
     LIBCERROR_ERROR_DOMAIN_IO,
1913
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1914
0
     "%s: unable to retrieve extended attributes from inode.",
1915
0
     function );
1916
1917
0
    goto on_error;
1918
0
  }
1919
0
  return( 1 );
1920
1921
0
on_error:
1922
0
  if( internal_file_entry->extended_attributes_array != NULL )
1923
0
  {
1924
0
    libcdata_array_free(
1925
0
     &( internal_file_entry->extended_attributes_array ),
1926
0
     (int (*)(intptr_t **, libcerror_error_t **)) &libfsxfs_attribute_values_free,
1927
0
     NULL );
1928
0
  }
1929
0
  return( -1 );
1930
0
}
1931
1932
/* Retrieves the number of extended attributes
1933
 * Returns 1 if successful or -1 on error
1934
 */
1935
int libfsxfs_file_entry_get_number_of_extended_attributes(
1936
     libfsxfs_file_entry_t *file_entry,
1937
     int *number_of_extended_attributes,
1938
     libcerror_error_t **error )
1939
0
{
1940
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1941
0
  static char *function                               = "libfsxfs_file_entry_get_number_of_extended_attributes";
1942
0
  int result                                          = 1;
1943
1944
0
  if( file_entry == NULL )
1945
0
  {
1946
0
    libcerror_error_set(
1947
0
     error,
1948
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1949
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1950
0
     "%s: invalid file entry.",
1951
0
     function );
1952
1953
0
    return( -1 );
1954
0
  }
1955
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1956
1957
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1958
0
  if( libcthreads_read_write_lock_grab_for_write(
1959
0
       internal_file_entry->read_write_lock,
1960
0
       error ) != 1 )
1961
0
  {
1962
0
    libcerror_error_set(
1963
0
     error,
1964
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1965
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1966
0
     "%s: unable to grab read/write lock for writing.",
1967
0
     function );
1968
1969
0
    return( -1 );
1970
0
  }
1971
0
#endif
1972
0
  if( internal_file_entry->extended_attributes_array == NULL )
1973
0
  {
1974
0
    if( libfsxfs_internal_file_entry_get_extended_attributes(
1975
0
         internal_file_entry,
1976
0
         error ) != 1 )
1977
0
    {
1978
0
      libcerror_error_set(
1979
0
       error,
1980
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1981
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1982
0
       "%s: unable to determine extended attributes.",
1983
0
       function );
1984
1985
0
      result = -1;
1986
0
    }
1987
0
  }
1988
0
  if( internal_file_entry->extended_attributes_array != NULL )
1989
0
  {
1990
0
    if( libcdata_array_get_number_of_entries(
1991
0
         internal_file_entry->extended_attributes_array,
1992
0
         number_of_extended_attributes,
1993
0
         error ) != 1 )
1994
0
    {
1995
0
      libcerror_error_set(
1996
0
       error,
1997
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1998
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1999
0
       "%s: unable to retrieve number of entries from extended attributes array.",
2000
0
       function );
2001
2002
0
      result = -1;
2003
0
    }
2004
0
  }
2005
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2006
0
  if( libcthreads_read_write_lock_release_for_write(
2007
0
       internal_file_entry->read_write_lock,
2008
0
       error ) != 1 )
2009
0
  {
2010
0
    libcerror_error_set(
2011
0
     error,
2012
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2013
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2014
0
     "%s: unable to release read/write lock for writing.",
2015
0
     function );
2016
2017
0
    return( -1 );
2018
0
  }
2019
0
#endif
2020
0
  return( result );
2021
0
}
2022
2023
/* Retrieves the extended attribute for the specific index
2024
 * Returns 1 if successful or -1 on error
2025
 */
2026
int libfsxfs_file_entry_get_extended_attribute_by_index(
2027
     libfsxfs_file_entry_t *file_entry,
2028
     int extended_attribute_index,
2029
     libfsxfs_extended_attribute_t **extended_attribute,
2030
     libcerror_error_t **error )
2031
0
{
2032
0
  libfsxfs_attribute_values_t *attribute_values       = NULL;
2033
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
2034
0
  static char *function                               = "libfsxfs_file_entry_get_extended_attribute_by_index";
2035
0
  int result                                          = 1;
2036
2037
0
  if( file_entry == NULL )
2038
0
  {
2039
0
    libcerror_error_set(
2040
0
     error,
2041
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2042
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2043
0
     "%s: invalid file entry.",
2044
0
     function );
2045
2046
0
    return( -1 );
2047
0
  }
2048
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
2049
2050
0
  if( extended_attribute == NULL )
2051
0
  {
2052
0
    libcerror_error_set(
2053
0
     error,
2054
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2055
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2056
0
     "%s: invalid extended attribute.",
2057
0
     function );
2058
2059
0
    return( -1 );
2060
0
  }
2061
0
  if( *extended_attribute != NULL )
2062
0
  {
2063
0
    libcerror_error_set(
2064
0
     error,
2065
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2066
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2067
0
     "%s: invalid extended attribute value already set.",
2068
0
     function );
2069
2070
0
    return( -1 );
2071
0
  }
2072
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2073
0
  if( libcthreads_read_write_lock_grab_for_write(
2074
0
       internal_file_entry->read_write_lock,
2075
0
       error ) != 1 )
2076
0
  {
2077
0
    libcerror_error_set(
2078
0
     error,
2079
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2080
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2081
0
     "%s: unable to grab read/write lock for writing.",
2082
0
     function );
2083
2084
0
    return( -1 );
2085
0
  }
2086
0
#endif
2087
0
  if( internal_file_entry->extended_attributes_array == NULL )
2088
0
  {
2089
0
    if( libfsxfs_internal_file_entry_get_extended_attributes(
2090
0
         internal_file_entry,
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 determine extended attributes.",
2098
0
       function );
2099
2100
0
      result = -1;
2101
0
    }
2102
0
  }
2103
0
  if( internal_file_entry->extended_attributes_array != NULL )
2104
0
  {
2105
0
    if( libcdata_array_get_entry_by_index(
2106
0
         internal_file_entry->extended_attributes_array,
2107
0
         extended_attribute_index,
2108
0
         (intptr_t **) &attribute_values,
2109
0
         error ) != 1 )
2110
0
    {
2111
0
      libcerror_error_set(
2112
0
       error,
2113
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2114
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2115
0
       "%s: unable to retrieve attribute: %d values.",
2116
0
       function,
2117
0
       extended_attribute_index );
2118
2119
0
      result = -1;
2120
0
    }
2121
0
    else
2122
0
    {
2123
0
      if( libfsxfs_extended_attribute_initialize(
2124
0
           extended_attribute,
2125
0
           internal_file_entry->io_handle,
2126
0
           internal_file_entry->file_io_handle,
2127
0
           internal_file_entry->file_system,
2128
0
           internal_file_entry->inode,
2129
0
           attribute_values,
2130
0
           error ) != 1 )
2131
0
      {
2132
0
        libcerror_error_set(
2133
0
         error,
2134
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2135
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2136
0
         "%s: unable to create extended attribute.",
2137
0
         function );
2138
2139
0
        result = -1;
2140
0
      }
2141
0
    }
2142
0
  }
2143
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2144
0
  if( libcthreads_read_write_lock_release_for_write(
2145
0
       internal_file_entry->read_write_lock,
2146
0
       error ) != 1 )
2147
0
  {
2148
0
    libcerror_error_set(
2149
0
     error,
2150
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2151
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2152
0
     "%s: unable to release read/write lock for writing.",
2153
0
     function );
2154
2155
0
    return( -1 );
2156
0
  }
2157
0
#endif
2158
0
  return( result );
2159
0
}
2160
2161
/* Retrieves the attribute values for an UTF-8 encoded name
2162
 * Returns 1 if successful, 0 if no such file entry or -1 on error
2163
 */
2164
int libfsxfs_internal_file_entry_get_attribute_values_by_utf8_name(
2165
     libfsxfs_internal_file_entry_t *internal_file_entry,
2166
     const uint8_t *utf8_string,
2167
     size_t utf8_string_length,
2168
     libfsxfs_attribute_values_t **attribute_values,
2169
     libcerror_error_t **error )
2170
0
{
2171
0
  libfsxfs_attribute_values_t *safe_attribute_values = NULL;
2172
0
  static char *function                              = "libfsxfs_internal_file_entry_get_attribute_values_by_utf8_name";
2173
0
  int attribute_index                                = 0;
2174
0
  int number_of_attributes                           = 0;
2175
0
  int result                                         = 0;
2176
2177
0
  if( internal_file_entry == NULL )
2178
0
  {
2179
0
    libcerror_error_set(
2180
0
     error,
2181
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2182
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2183
0
     "%s: invalid file entry.",
2184
0
     function );
2185
2186
0
    return( -1 );
2187
0
  }
2188
0
  if( internal_file_entry->extended_attributes_array == NULL )
2189
0
  {
2190
0
    if( libfsxfs_internal_file_entry_get_extended_attributes(
2191
0
         internal_file_entry,
2192
0
         error ) != 1 )
2193
0
    {
2194
0
      libcerror_error_set(
2195
0
       error,
2196
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2197
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2198
0
       "%s: unable to determine extended attributes.",
2199
0
       function );
2200
2201
0
      return( -1 );
2202
0
    }
2203
0
  }
2204
0
  if( libcdata_array_get_number_of_entries(
2205
0
       internal_file_entry->extended_attributes_array,
2206
0
       &number_of_attributes,
2207
0
       error ) != 1 )
2208
0
  {
2209
0
    libcerror_error_set(
2210
0
     error,
2211
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2212
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2213
0
     "%s: unable to retrieve number of entries from extended attributes array.",
2214
0
     function );
2215
2216
0
    return( -1 );
2217
0
  }
2218
0
  for( attribute_index = 0;
2219
0
       attribute_index < number_of_attributes;
2220
0
       attribute_index++ )
2221
0
  {
2222
0
    if( libcdata_array_get_entry_by_index(
2223
0
         internal_file_entry->extended_attributes_array,
2224
0
         attribute_index,
2225
0
         (intptr_t **) &safe_attribute_values,
2226
0
         error ) != 1 )
2227
0
    {
2228
0
      libcerror_error_set(
2229
0
       error,
2230
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2231
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2232
0
       "%s: unable to retrieve attribute: %d values.",
2233
0
       function,
2234
0
       attribute_index );
2235
2236
0
      return( -1 );
2237
0
    }
2238
0
    result = libfsxfs_attribute_values_compare_name_with_utf8_string(
2239
0
              safe_attribute_values,
2240
0
              utf8_string,
2241
0
              utf8_string_length,
2242
0
              error );
2243
2244
0
    if( result == -1 )
2245
0
    {
2246
0
      libcerror_error_set(
2247
0
       error,
2248
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2249
0
       LIBCERROR_RUNTIME_ERROR_GENERIC,
2250
0
       "%s: unable to compare UTF-8 string with name of attribute: %d values.",
2251
0
       function,
2252
0
       attribute_index );
2253
2254
0
      return( -1 );
2255
0
    }
2256
0
    else if( result == LIBUNA_COMPARE_EQUAL )
2257
0
    {
2258
0
      *attribute_values = safe_attribute_values;
2259
2260
0
      return( 1 );
2261
0
    }
2262
0
  }
2263
0
  return( 0 );
2264
0
}
2265
2266
/* Retrieves the attribute values for an UTF-16 encoded name
2267
 * Returns 1 if successful, 0 if no such file entry or -1 on error
2268
 */
2269
int libfsxfs_internal_file_entry_get_attribute_values_by_utf16_name(
2270
     libfsxfs_internal_file_entry_t *internal_file_entry,
2271
     const uint16_t *utf16_string,
2272
     size_t utf16_string_length,
2273
     libfsxfs_attribute_values_t **attribute_values,
2274
     libcerror_error_t **error )
2275
0
{
2276
0
  libfsxfs_attribute_values_t *safe_attribute_values = NULL;
2277
0
  static char *function                              = "libfsxfs_internal_file_entry_get_attribute_values_by_utf16_name";
2278
0
  int attribute_index                                = 0;
2279
0
  int number_of_attributes                           = 0;
2280
0
  int result                                         = 0;
2281
2282
0
  if( internal_file_entry == NULL )
2283
0
  {
2284
0
    libcerror_error_set(
2285
0
     error,
2286
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2287
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2288
0
     "%s: invalid file entry.",
2289
0
     function );
2290
2291
0
    return( -1 );
2292
0
  }
2293
0
  if( internal_file_entry->extended_attributes_array == NULL )
2294
0
  {
2295
0
    if( libfsxfs_internal_file_entry_get_extended_attributes(
2296
0
         internal_file_entry,
2297
0
         error ) != 1 )
2298
0
    {
2299
0
      libcerror_error_set(
2300
0
       error,
2301
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2302
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2303
0
       "%s: unable to determine extended attributes.",
2304
0
       function );
2305
2306
0
      return( -1 );
2307
0
    }
2308
0
  }
2309
0
  if( libcdata_array_get_number_of_entries(
2310
0
       internal_file_entry->extended_attributes_array,
2311
0
       &number_of_attributes,
2312
0
       error ) != 1 )
2313
0
  {
2314
0
    libcerror_error_set(
2315
0
     error,
2316
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2317
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2318
0
     "%s: unable to retrieve number of entries from extended attributes array.",
2319
0
     function );
2320
2321
0
    return( -1 );
2322
0
  }
2323
0
  for( attribute_index = 0;
2324
0
       attribute_index < number_of_attributes;
2325
0
       attribute_index++ )
2326
0
  {
2327
0
    if( libcdata_array_get_entry_by_index(
2328
0
         internal_file_entry->extended_attributes_array,
2329
0
         attribute_index,
2330
0
         (intptr_t **) &safe_attribute_values,
2331
0
         error ) != 1 )
2332
0
    {
2333
0
      libcerror_error_set(
2334
0
       error,
2335
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2336
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2337
0
       "%s: unable to retrieve attribute: %d values.",
2338
0
       function,
2339
0
       attribute_index );
2340
2341
0
      return( -1 );
2342
0
    }
2343
0
    result = libfsxfs_attribute_values_compare_name_with_utf16_string(
2344
0
              safe_attribute_values,
2345
0
              utf16_string,
2346
0
              utf16_string_length,
2347
0
              error );
2348
2349
0
    if( result == -1 )
2350
0
    {
2351
0
      libcerror_error_set(
2352
0
       error,
2353
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2354
0
       LIBCERROR_RUNTIME_ERROR_GENERIC,
2355
0
       "%s: unable to compare UTF-16 string with name of attribute: %d values.",
2356
0
       function,
2357
0
       attribute_index );
2358
2359
0
      return( -1 );
2360
0
    }
2361
0
    else if( result == LIBUNA_COMPARE_EQUAL )
2362
0
    {
2363
0
      *attribute_values = safe_attribute_values;
2364
2365
0
      return( 1 );
2366
0
    }
2367
0
  }
2368
0
  return( 0 );
2369
0
}
2370
2371
/* Determines if there is an extended attribute for an UTF-8 encoded name
2372
 * Returns 1 if available, 0 if not or -1 on error
2373
 */
2374
int libfsxfs_file_entry_has_extended_attribute_by_utf8_name(
2375
     libfsxfs_file_entry_t *file_entry,
2376
     const uint8_t *utf8_string,
2377
     size_t utf8_string_length,
2378
     libcerror_error_t **error )
2379
0
{
2380
0
  libfsxfs_attribute_values_t *attribute_values       = NULL;
2381
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
2382
0
  static char *function                               = "libfsxfs_file_entry_has_extended_attribute_by_utf8_name";
2383
0
  int result                                          = 0;
2384
2385
0
  if( file_entry == NULL )
2386
0
  {
2387
0
    libcerror_error_set(
2388
0
     error,
2389
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2390
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2391
0
     "%s: invalid file entry.",
2392
0
     function );
2393
2394
0
    return( -1 );
2395
0
  }
2396
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
2397
2398
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2399
0
  if( libcthreads_read_write_lock_grab_for_write(
2400
0
       internal_file_entry->read_write_lock,
2401
0
       error ) != 1 )
2402
0
  {
2403
0
    libcerror_error_set(
2404
0
     error,
2405
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2406
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2407
0
     "%s: unable to grab read/write lock for writing.",
2408
0
     function );
2409
2410
0
    return( -1 );
2411
0
  }
2412
0
#endif
2413
0
  result = libfsxfs_internal_file_entry_get_attribute_values_by_utf8_name(
2414
0
            internal_file_entry,
2415
0
            utf8_string,
2416
0
            utf8_string_length,
2417
0
            &attribute_values,
2418
0
            error );
2419
2420
0
  if( result == -1 )
2421
0
  {
2422
0
    libcerror_error_set(
2423
0
     error,
2424
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2425
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2426
0
     "%s: unable to retrieve attribute values for UTF-8 name.",
2427
0
     function );
2428
2429
0
    result = -1;
2430
0
  }
2431
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2432
0
  if( libcthreads_read_write_lock_release_for_write(
2433
0
       internal_file_entry->read_write_lock,
2434
0
       error ) != 1 )
2435
0
  {
2436
0
    libcerror_error_set(
2437
0
     error,
2438
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2439
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2440
0
     "%s: unable to release read/write lock for writing.",
2441
0
     function );
2442
2443
0
    return( -1 );
2444
0
  }
2445
0
#endif
2446
0
  return( result );
2447
0
}
2448
2449
/* Determines if there is an extended attribute for an UTF-8 encoded name
2450
 * Returns 1 if available, 0 if not or -1 on error
2451
 */
2452
int libfsxfs_file_entry_has_extended_attribute_by_utf16_name(
2453
     libfsxfs_file_entry_t *file_entry,
2454
     const uint16_t *utf16_string,
2455
     size_t utf16_string_length,
2456
     libcerror_error_t **error )
2457
0
{
2458
0
  libfsxfs_attribute_values_t *attribute_values       = NULL;
2459
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
2460
0
  static char *function                               = "libfsxfs_file_entry_has_extended_attribute_by_utf16_name";
2461
0
  int result                                          = 0;
2462
2463
0
  if( file_entry == NULL )
2464
0
  {
2465
0
    libcerror_error_set(
2466
0
     error,
2467
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2468
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2469
0
     "%s: invalid file entry.",
2470
0
     function );
2471
2472
0
    return( -1 );
2473
0
  }
2474
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
2475
2476
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2477
0
  if( libcthreads_read_write_lock_grab_for_write(
2478
0
       internal_file_entry->read_write_lock,
2479
0
       error ) != 1 )
2480
0
  {
2481
0
    libcerror_error_set(
2482
0
     error,
2483
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2484
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2485
0
     "%s: unable to grab read/write lock for writing.",
2486
0
     function );
2487
2488
0
    return( -1 );
2489
0
  }
2490
0
#endif
2491
0
  result = libfsxfs_internal_file_entry_get_attribute_values_by_utf16_name(
2492
0
            internal_file_entry,
2493
0
            utf16_string,
2494
0
            utf16_string_length,
2495
0
            &attribute_values,
2496
0
            error );
2497
2498
0
  if( result == -1 )
2499
0
  {
2500
0
    libcerror_error_set(
2501
0
     error,
2502
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2503
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2504
0
     "%s: unable to retrieve attribute values for UTF-16 name.",
2505
0
     function );
2506
2507
0
    result = -1;
2508
0
  }
2509
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2510
0
  if( libcthreads_read_write_lock_release_for_write(
2511
0
       internal_file_entry->read_write_lock,
2512
0
       error ) != 1 )
2513
0
  {
2514
0
    libcerror_error_set(
2515
0
     error,
2516
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2517
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2518
0
     "%s: unable to release read/write lock for writing.",
2519
0
     function );
2520
2521
0
    return( -1 );
2522
0
  }
2523
0
#endif
2524
0
  return( result );
2525
0
}
2526
2527
/* Retrieves the extended attribute for an UTF-8 encoded name
2528
 * Returns 1 if successful, 0 if no such file entry or -1 on error
2529
 */
2530
int libfsxfs_file_entry_get_extended_attribute_by_utf8_name(
2531
     libfsxfs_file_entry_t *file_entry,
2532
     const uint8_t *utf8_string,
2533
     size_t utf8_string_length,
2534
     libfsxfs_extended_attribute_t **extended_attribute,
2535
     libcerror_error_t **error )
2536
0
{
2537
0
  libfsxfs_attribute_values_t *attribute_values       = NULL;
2538
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
2539
0
  static char *function                               = "libfsxfs_file_entry_get_extended_attribute_by_utf8_name";
2540
0
  int result                                          = 0;
2541
2542
0
  if( file_entry == NULL )
2543
0
  {
2544
0
    libcerror_error_set(
2545
0
     error,
2546
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2547
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2548
0
     "%s: invalid file entry.",
2549
0
     function );
2550
2551
0
    return( -1 );
2552
0
  }
2553
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
2554
2555
0
  if( extended_attribute == NULL )
2556
0
  {
2557
0
    libcerror_error_set(
2558
0
     error,
2559
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2560
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2561
0
     "%s: invalid extended attribute.",
2562
0
     function );
2563
2564
0
    return( -1 );
2565
0
  }
2566
0
  if( *extended_attribute != NULL )
2567
0
  {
2568
0
    libcerror_error_set(
2569
0
     error,
2570
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2571
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2572
0
     "%s: invalid extended attribute value already set.",
2573
0
     function );
2574
2575
0
    return( -1 );
2576
0
  }
2577
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2578
0
  if( libcthreads_read_write_lock_grab_for_write(
2579
0
       internal_file_entry->read_write_lock,
2580
0
       error ) != 1 )
2581
0
  {
2582
0
    libcerror_error_set(
2583
0
     error,
2584
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2585
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2586
0
     "%s: unable to grab read/write lock for writing.",
2587
0
     function );
2588
2589
0
    return( -1 );
2590
0
  }
2591
0
#endif
2592
0
  result = libfsxfs_internal_file_entry_get_attribute_values_by_utf8_name(
2593
0
            internal_file_entry,
2594
0
            utf8_string,
2595
0
            utf8_string_length,
2596
0
            &attribute_values,
2597
0
            error );
2598
2599
0
  if( result == -1 )
2600
0
  {
2601
0
    libcerror_error_set(
2602
0
     error,
2603
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2604
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2605
0
     "%s: unable to retrieve attribute values for UTF-8 name.",
2606
0
     function );
2607
2608
0
    result = -1;
2609
0
  }
2610
0
  else if( result != 0 )
2611
0
  {
2612
0
    if( libfsxfs_extended_attribute_initialize(
2613
0
         extended_attribute,
2614
0
         internal_file_entry->io_handle,
2615
0
         internal_file_entry->file_io_handle,
2616
0
         internal_file_entry->file_system,
2617
0
         internal_file_entry->inode,
2618
0
         attribute_values,
2619
0
         error ) != 1 )
2620
0
    {
2621
0
      libcerror_error_set(
2622
0
       error,
2623
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2624
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2625
0
       "%s: unable to create extended attribute.",
2626
0
       function );
2627
2628
0
      result = -1;
2629
0
    }
2630
0
  }
2631
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2632
0
  if( libcthreads_read_write_lock_release_for_write(
2633
0
       internal_file_entry->read_write_lock,
2634
0
       error ) != 1 )
2635
0
  {
2636
0
    libcerror_error_set(
2637
0
     error,
2638
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2639
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2640
0
     "%s: unable to release read/write lock for writing.",
2641
0
     function );
2642
2643
0
    return( -1 );
2644
0
  }
2645
0
#endif
2646
0
  return( result );
2647
0
}
2648
2649
/* Retrieves the extended attribute for an UTF-16 encoded name
2650
 * Returns 1 if successful, 0 if no such file entry or -1 on error
2651
 */
2652
int libfsxfs_file_entry_get_extended_attribute_by_utf16_name(
2653
     libfsxfs_file_entry_t *file_entry,
2654
     const uint16_t *utf16_string,
2655
     size_t utf16_string_length,
2656
     libfsxfs_extended_attribute_t **extended_attribute,
2657
     libcerror_error_t **error )
2658
0
{
2659
0
  libfsxfs_attribute_values_t *attribute_values       = NULL;
2660
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
2661
0
  static char *function                               = "libfsxfs_file_entry_get_extended_attribute_by_utf16_name";
2662
0
  int result                                          = 0;
2663
2664
0
  if( file_entry == NULL )
2665
0
  {
2666
0
    libcerror_error_set(
2667
0
     error,
2668
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2669
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2670
0
     "%s: invalid file entry.",
2671
0
     function );
2672
2673
0
    return( -1 );
2674
0
  }
2675
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
2676
2677
0
  if( extended_attribute == NULL )
2678
0
  {
2679
0
    libcerror_error_set(
2680
0
     error,
2681
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2682
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2683
0
     "%s: invalid extended attribute.",
2684
0
     function );
2685
2686
0
    return( -1 );
2687
0
  }
2688
0
  if( *extended_attribute != NULL )
2689
0
  {
2690
0
    libcerror_error_set(
2691
0
     error,
2692
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2693
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2694
0
     "%s: invalid extended attribute value already set.",
2695
0
     function );
2696
2697
0
    return( -1 );
2698
0
  }
2699
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2700
0
  if( libcthreads_read_write_lock_grab_for_write(
2701
0
       internal_file_entry->read_write_lock,
2702
0
       error ) != 1 )
2703
0
  {
2704
0
    libcerror_error_set(
2705
0
     error,
2706
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2707
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2708
0
     "%s: unable to grab read/write lock for writing.",
2709
0
     function );
2710
2711
0
    return( -1 );
2712
0
  }
2713
0
#endif
2714
0
  result = libfsxfs_internal_file_entry_get_attribute_values_by_utf16_name(
2715
0
            internal_file_entry,
2716
0
            utf16_string,
2717
0
            utf16_string_length,
2718
0
            &attribute_values,
2719
0
            error );
2720
2721
0
  if( result == -1 )
2722
0
  {
2723
0
    libcerror_error_set(
2724
0
     error,
2725
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2726
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2727
0
     "%s: unable to retrieve attribute values for UTF-16 name.",
2728
0
     function );
2729
2730
0
    result = -1;
2731
0
  }
2732
0
  else if( result != 0 )
2733
0
  {
2734
0
    if( libfsxfs_extended_attribute_initialize(
2735
0
         extended_attribute,
2736
0
         internal_file_entry->io_handle,
2737
0
         internal_file_entry->file_io_handle,
2738
0
         internal_file_entry->file_system,
2739
0
         internal_file_entry->inode,
2740
0
         attribute_values,
2741
0
         error ) != 1 )
2742
0
    {
2743
0
      libcerror_error_set(
2744
0
       error,
2745
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2746
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2747
0
       "%s: unable to create extended attribute.",
2748
0
       function );
2749
2750
0
      result = -1;
2751
0
    }
2752
0
  }
2753
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2754
0
  if( libcthreads_read_write_lock_release_for_write(
2755
0
       internal_file_entry->read_write_lock,
2756
0
       error ) != 1 )
2757
0
  {
2758
0
    libcerror_error_set(
2759
0
     error,
2760
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2761
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2762
0
     "%s: unable to release read/write lock for writing.",
2763
0
     function );
2764
2765
0
    return( -1 );
2766
0
  }
2767
0
#endif
2768
0
  return( result );
2769
0
}
2770
2771
/* Retrieves the number of sub file entries
2772
 * Returns 1 if successful or -1 on error
2773
 */
2774
int libfsxfs_file_entry_get_number_of_sub_file_entries(
2775
     libfsxfs_file_entry_t *file_entry,
2776
     int *number_of_sub_file_entries,
2777
     libcerror_error_t **error )
2778
1.08k
{
2779
1.08k
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
2780
1.08k
  static char *function                               = "libfsxfs_file_entry_get_number_of_sub_file_entries";
2781
1.08k
  int result                                          = 1;
2782
2783
1.08k
  if( file_entry == NULL )
2784
0
  {
2785
0
    libcerror_error_set(
2786
0
     error,
2787
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2788
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2789
0
     "%s: invalid file entry.",
2790
0
     function );
2791
2792
0
    return( -1 );
2793
0
  }
2794
1.08k
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
2795
2796
1.08k
  if( number_of_sub_file_entries == NULL )
2797
0
  {
2798
0
    libcerror_error_set(
2799
0
     error,
2800
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2801
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2802
0
     "%s: invalid number of sub file entries.",
2803
0
     function );
2804
2805
0
    return( -1 );
2806
0
  }
2807
1.08k
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2808
1.08k
  if( libcthreads_read_write_lock_grab_for_read(
2809
1.08k
       internal_file_entry->read_write_lock,
2810
1.08k
       error ) != 1 )
2811
0
  {
2812
0
    libcerror_error_set(
2813
0
     error,
2814
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2815
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2816
0
     "%s: unable to grab read/write lock for reading.",
2817
0
     function );
2818
2819
0
    return( -1 );
2820
0
  }
2821
1.08k
#endif
2822
1.08k
  if( internal_file_entry->directory == NULL )
2823
1.08k
  {
2824
1.08k
    if( libfsxfs_internal_file_entry_get_directory(
2825
1.08k
         internal_file_entry,
2826
1.08k
         error ) != 1 )
2827
376
    {
2828
376
      libcerror_error_set(
2829
376
       error,
2830
376
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2831
376
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2832
376
       "%s: unable to retrieve directory for inode: %" PRIu32 ".",
2833
376
       function,
2834
376
       internal_file_entry->inode_number );
2835
2836
376
      result = -1;
2837
376
    }
2838
1.08k
  }
2839
1.08k
  if( internal_file_entry->directory != NULL )
2840
674
  {
2841
674
    if( libfsxfs_directory_get_number_of_entries(
2842
674
         internal_file_entry->directory,
2843
674
         number_of_sub_file_entries,
2844
674
         error ) != 1 )
2845
0
    {
2846
0
      libcerror_error_set(
2847
0
       error,
2848
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2849
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2850
0
       "%s: unable to retrieve number of sub directory entries.",
2851
0
       function );
2852
2853
0
      result = -1;
2854
0
    }
2855
674
  }
2856
1.08k
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2857
1.08k
  if( libcthreads_read_write_lock_release_for_read(
2858
1.08k
       internal_file_entry->read_write_lock,
2859
1.08k
       error ) != 1 )
2860
0
  {
2861
0
    libcerror_error_set(
2862
0
     error,
2863
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2864
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2865
0
     "%s: unable to release read/write lock for reading.",
2866
0
     function );
2867
2868
0
    return( -1 );
2869
0
  }
2870
1.08k
#endif
2871
1.08k
  return( result );
2872
1.08k
}
2873
2874
/* Retrieves the sub file entry for the specific index
2875
 * Returns 1 if successful or -1 on error
2876
 */
2877
int libfsxfs_file_entry_get_sub_file_entry_by_index(
2878
     libfsxfs_file_entry_t *file_entry,
2879
     int sub_file_entry_index,
2880
     libfsxfs_file_entry_t **sub_file_entry,
2881
     libcerror_error_t **error )
2882
610
{
2883
610
  libfsxfs_directory_entry_t *safe_directory_entry    = NULL;
2884
610
  libfsxfs_directory_entry_t *sub_directory_entry     = NULL;
2885
610
  libfsxfs_inode_t *inode                             = NULL;
2886
610
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
2887
610
  static char *function                               = "libfsxfs_file_entry_get_sub_file_entry_by_index";
2888
610
  int result                                          = 1;
2889
2890
610
  if( file_entry == NULL )
2891
0
  {
2892
0
    libcerror_error_set(
2893
0
     error,
2894
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2895
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2896
0
     "%s: invalid file entry.",
2897
0
     function );
2898
2899
0
    return( -1 );
2900
0
  }
2901
610
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
2902
2903
610
  if( sub_file_entry == NULL )
2904
0
  {
2905
0
    libcerror_error_set(
2906
0
     error,
2907
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2908
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2909
0
     "%s: invalid sub file entry.",
2910
0
     function );
2911
2912
0
    return( -1 );
2913
0
  }
2914
610
  if( *sub_file_entry != NULL )
2915
0
  {
2916
0
    libcerror_error_set(
2917
0
     error,
2918
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2919
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2920
0
     "%s: invalid sub file entry value already set.",
2921
0
     function );
2922
2923
0
    return( -1 );
2924
0
  }
2925
610
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2926
610
  if( libcthreads_read_write_lock_grab_for_write(
2927
610
       internal_file_entry->read_write_lock,
2928
610
       error ) != 1 )
2929
0
  {
2930
0
    libcerror_error_set(
2931
0
     error,
2932
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2933
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2934
0
     "%s: unable to grab read/write lock for writing.",
2935
0
     function );
2936
2937
0
    return( -1 );
2938
0
  }
2939
610
#endif
2940
610
  if( internal_file_entry->directory == NULL )
2941
0
  {
2942
0
    if( libfsxfs_internal_file_entry_get_directory(
2943
0
         internal_file_entry,
2944
0
         error ) != 1 )
2945
0
    {
2946
0
      libcerror_error_set(
2947
0
       error,
2948
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2949
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2950
0
       "%s: unable to retrieve directory for inode: %" PRIu32 ".",
2951
0
       function,
2952
0
       internal_file_entry->inode_number );
2953
2954
0
      result = -1;
2955
0
    }
2956
0
  }
2957
610
  if( result != -1 )
2958
610
  {
2959
610
    if( libfsxfs_directory_get_entry_by_index(
2960
610
         internal_file_entry->directory,
2961
610
         sub_file_entry_index,
2962
610
         &sub_directory_entry,
2963
610
         error ) != 1 )
2964
0
    {
2965
0
      libcerror_error_set(
2966
0
       error,
2967
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2968
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2969
0
       "%s: unable to retrieve sub directory entry: %d.",
2970
0
       function,
2971
0
       sub_file_entry_index );
2972
2973
0
      result = -1;
2974
0
    }
2975
610
    else if( libfsxfs_file_system_get_inode_by_number(
2976
610
              internal_file_entry->file_system,
2977
610
              internal_file_entry->io_handle,
2978
610
              internal_file_entry->file_io_handle,
2979
610
              sub_directory_entry->inode_number,
2980
610
              &inode,
2981
610
              error ) != 1 )
2982
101
    {
2983
101
      libcerror_error_set(
2984
101
       error,
2985
101
       LIBCERROR_ERROR_DOMAIN_IO,
2986
101
       LIBCERROR_IO_ERROR_READ_FAILED,
2987
101
       "%s: unable to retrieve sub directory entry: %d inode: %" PRIu64 "\n",
2988
101
       function,
2989
101
       sub_file_entry_index,
2990
101
       sub_directory_entry->inode_number );
2991
2992
101
      result = -1;
2993
101
    }
2994
509
    else if( libfsxfs_directory_entry_clone(
2995
509
              &safe_directory_entry,
2996
509
              sub_directory_entry,
2997
509
              error ) != 1 )
2998
0
    {
2999
0
      libcerror_error_set(
3000
0
       error,
3001
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3002
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3003
0
       "%s: unable to clone sub directory entry: %d.",
3004
0
       function,
3005
0
       sub_file_entry_index );
3006
3007
0
      libfsxfs_inode_free(
3008
0
       &inode,
3009
0
       NULL );
3010
3011
0
      result = -1;
3012
0
    }
3013
    /* libfsxfs_file_entry_initialize takes over management of sub_directory_entry
3014
     */
3015
509
    else if( libfsxfs_file_entry_initialize(
3016
509
              sub_file_entry,
3017
509
              internal_file_entry->io_handle,
3018
509
              internal_file_entry->file_io_handle,
3019
509
              internal_file_entry->file_system,
3020
509
              sub_directory_entry->inode_number,
3021
509
              inode,
3022
509
              safe_directory_entry,
3023
509
              error ) != 1 )
3024
54
    {
3025
54
      libcerror_error_set(
3026
54
       error,
3027
54
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3028
54
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3029
54
       "%s: unable to create file entry.",
3030
54
       function );
3031
3032
54
      libfsxfs_inode_free(
3033
54
       &inode,
3034
54
       NULL );
3035
3036
54
      libfsxfs_directory_entry_free(
3037
54
       &safe_directory_entry,
3038
54
       NULL );
3039
3040
54
      result = -1;
3041
54
    }
3042
610
  }
3043
610
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3044
610
  if( libcthreads_read_write_lock_release_for_write(
3045
610
       internal_file_entry->read_write_lock,
3046
610
       error ) != 1 )
3047
0
  {
3048
0
    libcerror_error_set(
3049
0
     error,
3050
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3051
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3052
0
     "%s: unable to release read/write lock for writing.",
3053
0
     function );
3054
3055
0
    return( -1 );
3056
0
  }
3057
610
#endif
3058
610
  return( result );
3059
610
}
3060
3061
/* Retrieves the sub file entry for an UTF-8 encoded name
3062
 * Returns 1 if successful, 0 if no such file entry or -1 on error
3063
 */
3064
int libfsxfs_file_entry_get_sub_file_entry_by_utf8_name(
3065
     libfsxfs_file_entry_t *file_entry,
3066
     const uint8_t *utf8_string,
3067
     size_t utf8_string_length,
3068
     libfsxfs_file_entry_t **sub_file_entry,
3069
     libcerror_error_t **error )
3070
0
{
3071
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3072
0
  static char *function                               = "libfsxfs_file_entry_get_sub_file_entry_by_utf8_name";
3073
0
  int result                                          = 1;
3074
3075
0
  if( file_entry == NULL )
3076
0
  {
3077
0
    libcerror_error_set(
3078
0
     error,
3079
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3080
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3081
0
     "%s: invalid file entry.",
3082
0
     function );
3083
3084
0
    return( -1 );
3085
0
  }
3086
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3087
3088
0
  if( sub_file_entry == NULL )
3089
0
  {
3090
0
    libcerror_error_set(
3091
0
     error,
3092
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3093
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3094
0
     "%s: invalid sub file entry.",
3095
0
     function );
3096
3097
0
    return( -1 );
3098
0
  }
3099
0
  if( *sub_file_entry != NULL )
3100
0
  {
3101
0
    libcerror_error_set(
3102
0
     error,
3103
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3104
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3105
0
     "%s: invalid sub file entry value already set.",
3106
0
     function );
3107
3108
0
    return( -1 );
3109
0
  }
3110
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3111
0
  if( libcthreads_read_write_lock_grab_for_read(
3112
0
       internal_file_entry->read_write_lock,
3113
0
       error ) != 1 )
3114
0
  {
3115
0
    libcerror_error_set(
3116
0
     error,
3117
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3118
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3119
0
     "%s: unable to grab read/write lock for reading.",
3120
0
     function );
3121
3122
0
    return( -1 );
3123
0
  }
3124
0
#endif
3125
  /* TODO implement */
3126
0
  result = -1;
3127
3128
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3129
0
  if( libcthreads_read_write_lock_release_for_read(
3130
0
       internal_file_entry->read_write_lock,
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_SET_FAILED,
3137
0
     "%s: unable to release read/write lock for reading.",
3138
0
     function );
3139
3140
0
    return( -1 );
3141
0
  }
3142
0
#endif
3143
0
  return( result );
3144
0
}
3145
3146
/* Retrieves the sub file entry for an UTF-16 encoded name
3147
 * Returns 1 if successful, 0 if no such file entry or -1 on error
3148
 */
3149
int libfsxfs_file_entry_get_sub_file_entry_by_utf16_name(
3150
     libfsxfs_file_entry_t *file_entry,
3151
     const uint16_t *utf16_string,
3152
     size_t utf16_string_length,
3153
     libfsxfs_file_entry_t **sub_file_entry,
3154
     libcerror_error_t **error )
3155
0
{
3156
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3157
0
  static char *function                               = "libfsxfs_file_entry_get_sub_file_entry_by_utf16_name";
3158
0
  int result                                          = 1;
3159
3160
0
  if( file_entry == NULL )
3161
0
  {
3162
0
    libcerror_error_set(
3163
0
     error,
3164
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3165
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3166
0
     "%s: invalid file entry.",
3167
0
     function );
3168
3169
0
    return( -1 );
3170
0
  }
3171
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3172
3173
0
  if( sub_file_entry == NULL )
3174
0
  {
3175
0
    libcerror_error_set(
3176
0
     error,
3177
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3178
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3179
0
     "%s: invalid sub file entry.",
3180
0
     function );
3181
3182
0
    return( -1 );
3183
0
  }
3184
0
  if( *sub_file_entry != NULL )
3185
0
  {
3186
0
    libcerror_error_set(
3187
0
     error,
3188
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3189
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3190
0
     "%s: invalid sub file entry value already set.",
3191
0
     function );
3192
3193
0
    return( -1 );
3194
0
  }
3195
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3196
0
  if( libcthreads_read_write_lock_grab_for_read(
3197
0
       internal_file_entry->read_write_lock,
3198
0
       error ) != 1 )
3199
0
  {
3200
0
    libcerror_error_set(
3201
0
     error,
3202
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3203
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3204
0
     "%s: unable to grab read/write lock for reading.",
3205
0
     function );
3206
3207
0
    return( -1 );
3208
0
  }
3209
0
#endif
3210
  /* TODO implement */
3211
0
  result = -1;
3212
3213
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3214
0
  if( libcthreads_read_write_lock_release_for_read(
3215
0
       internal_file_entry->read_write_lock,
3216
0
       error ) != 1 )
3217
0
  {
3218
0
    libcerror_error_set(
3219
0
     error,
3220
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3221
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3222
0
     "%s: unable to release read/write lock for reading.",
3223
0
     function );
3224
3225
0
    return( -1 );
3226
0
  }
3227
0
#endif
3228
0
  return( result );
3229
0
}
3230
3231
/* Reads data at the current offset
3232
 * Returns the number of bytes read or -1 on error
3233
 */
3234
ssize_t libfsxfs_file_entry_read_buffer(
3235
         libfsxfs_file_entry_t *file_entry,
3236
         void *buffer,
3237
         size_t buffer_size,
3238
         libcerror_error_t **error )
3239
0
{
3240
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3241
0
  static char *function                               = "libfsxfs_file_entry_read_buffer";
3242
0
  ssize_t read_count                                  = 0;
3243
3244
0
  if( file_entry == NULL )
3245
0
  {
3246
0
    libcerror_error_set(
3247
0
     error,
3248
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3249
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3250
0
     "%s: invalid file entry.",
3251
0
     function );
3252
3253
0
    return( -1 );
3254
0
  }
3255
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3256
3257
0
  if( internal_file_entry->inode == NULL )
3258
0
  {
3259
0
    libcerror_error_set(
3260
0
     error,
3261
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3262
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3263
0
     "%s: invalid file entry - missing inode.",
3264
0
     function );
3265
3266
0
    return( -1 );
3267
0
  }
3268
0
  if( ( internal_file_entry->inode->file_mode & 0xf000 ) != LIBFSXFS_FILE_TYPE_REGULAR_FILE )
3269
0
  {
3270
0
    libcerror_error_set(
3271
0
     error,
3272
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3273
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3274
0
     "%s: invalid file entry - invalid inode - unsupported file mode not a regular file.",
3275
0
     function );
3276
3277
0
    return( -1 );
3278
0
  }
3279
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3280
0
  if( libcthreads_read_write_lock_grab_for_write(
3281
0
       internal_file_entry->read_write_lock,
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_SET_FAILED,
3288
0
     "%s: unable to grab read/write lock for writing.",
3289
0
     function );
3290
3291
0
    return( -1 );
3292
0
  }
3293
0
#endif
3294
0
  read_count = libfdata_stream_read_buffer(
3295
0
                internal_file_entry->data_stream,
3296
0
                (intptr_t *) internal_file_entry->file_io_handle,
3297
0
                buffer,
3298
0
                buffer_size,
3299
0
                0,
3300
0
                error );
3301
3302
0
  if( read_count < 0 )
3303
0
  {
3304
0
    libcerror_error_set(
3305
0
     error,
3306
0
     LIBCERROR_ERROR_DOMAIN_IO,
3307
0
     LIBCERROR_IO_ERROR_READ_FAILED,
3308
0
     "%s: unable to read from data stream.",
3309
0
     function );
3310
3311
0
    read_count = -1;
3312
0
  }
3313
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3314
0
  if( libcthreads_read_write_lock_release_for_write(
3315
0
       internal_file_entry->read_write_lock,
3316
0
       error ) != 1 )
3317
0
  {
3318
0
    libcerror_error_set(
3319
0
     error,
3320
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3321
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3322
0
     "%s: unable to release read/write lock for writing.",
3323
0
     function );
3324
3325
0
    return( -1 );
3326
0
  }
3327
0
#endif
3328
0
  return( read_count );
3329
0
}
3330
3331
/* Reads data at a specific offset
3332
 * Returns the number of bytes read or -1 on error
3333
 */
3334
ssize_t libfsxfs_file_entry_read_buffer_at_offset(
3335
         libfsxfs_file_entry_t *file_entry,
3336
         void *buffer,
3337
         size_t buffer_size,
3338
         off64_t offset,
3339
         libcerror_error_t **error )
3340
0
{
3341
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3342
0
  static char *function                               = "libfsxfs_file_entry_read_buffer_at_offset";
3343
0
  ssize_t read_count                                  = 0;
3344
3345
0
  if( file_entry == NULL )
3346
0
  {
3347
0
    libcerror_error_set(
3348
0
     error,
3349
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3350
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3351
0
     "%s: invalid file entry.",
3352
0
     function );
3353
3354
0
    return( -1 );
3355
0
  }
3356
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3357
3358
0
  if( internal_file_entry->inode == NULL )
3359
0
  {
3360
0
    libcerror_error_set(
3361
0
     error,
3362
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3363
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3364
0
     "%s: invalid file entry - missing inode.",
3365
0
     function );
3366
3367
0
    return( -1 );
3368
0
  }
3369
0
  if( ( internal_file_entry->inode->file_mode & 0xf000 ) != LIBFSXFS_FILE_TYPE_REGULAR_FILE )
3370
0
  {
3371
0
    libcerror_error_set(
3372
0
     error,
3373
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3374
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3375
0
     "%s: invalid file entry - invalid inode - unsupported file mode not a regular file.",
3376
0
     function );
3377
3378
0
    return( -1 );
3379
0
  }
3380
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3381
0
  if( libcthreads_read_write_lock_grab_for_write(
3382
0
       internal_file_entry->read_write_lock,
3383
0
       error ) != 1 )
3384
0
  {
3385
0
    libcerror_error_set(
3386
0
     error,
3387
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3388
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3389
0
     "%s: unable to grab read/write lock for writing.",
3390
0
     function );
3391
3392
0
    return( -1 );
3393
0
  }
3394
0
#endif
3395
0
  read_count = libfdata_stream_read_buffer_at_offset(
3396
0
                internal_file_entry->data_stream,
3397
0
                (intptr_t *) internal_file_entry->file_io_handle,
3398
0
                buffer,
3399
0
                buffer_size,
3400
0
                offset,
3401
0
                0,
3402
0
                error );
3403
3404
0
  if( read_count < 0 )
3405
0
  {
3406
0
    libcerror_error_set(
3407
0
     error,
3408
0
     LIBCERROR_ERROR_DOMAIN_IO,
3409
0
     LIBCERROR_IO_ERROR_READ_FAILED,
3410
0
     "%s: unable to read from data stream.",
3411
0
     function );
3412
3413
0
    read_count = -1;
3414
0
  }
3415
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3416
0
  if( libcthreads_read_write_lock_release_for_write(
3417
0
       internal_file_entry->read_write_lock,
3418
0
       error ) != 1 )
3419
0
  {
3420
0
    libcerror_error_set(
3421
0
     error,
3422
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3423
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3424
0
     "%s: unable to release read/write lock for writing.",
3425
0
     function );
3426
3427
0
    return( -1 );
3428
0
  }
3429
0
#endif
3430
0
  return( read_count );
3431
0
}
3432
3433
/* Seeks a certain offset in the data
3434
 * Returns the offset if seek is successful or -1 on error
3435
 */
3436
off64_t libfsxfs_file_entry_seek_offset(
3437
         libfsxfs_file_entry_t *file_entry,
3438
         off64_t offset,
3439
         int whence,
3440
         libcerror_error_t **error )
3441
0
{
3442
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3443
0
  static char *function                                = "libfsxfs_file_entry_seek_offset";
3444
3445
0
  if( file_entry == NULL )
3446
0
  {
3447
0
    libcerror_error_set(
3448
0
     error,
3449
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3450
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3451
0
     "%s: invalid file entry.",
3452
0
     function );
3453
3454
0
    return( -1 );
3455
0
  }
3456
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3457
3458
0
  if( internal_file_entry->inode == NULL )
3459
0
  {
3460
0
    libcerror_error_set(
3461
0
     error,
3462
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3463
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3464
0
     "%s: invalid file entry - missing inode.",
3465
0
     function );
3466
3467
0
    return( -1 );
3468
0
  }
3469
0
  if( ( internal_file_entry->inode->file_mode & 0xf000 ) != LIBFSXFS_FILE_TYPE_REGULAR_FILE )
3470
0
  {
3471
0
    libcerror_error_set(
3472
0
     error,
3473
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3474
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3475
0
     "%s: invalid file entry - invalid inode - unsupported file mode not a regular file.",
3476
0
     function );
3477
3478
0
    return( -1 );
3479
0
  }
3480
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3481
0
  if( libcthreads_read_write_lock_grab_for_write(
3482
0
       internal_file_entry->read_write_lock,
3483
0
       error ) != 1 )
3484
0
  {
3485
0
    libcerror_error_set(
3486
0
     error,
3487
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3488
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3489
0
     "%s: unable to grab read/write lock for writing.",
3490
0
     function );
3491
3492
0
    return( -1 );
3493
0
  }
3494
0
#endif
3495
0
  offset = libfdata_stream_seek_offset(
3496
0
            internal_file_entry->data_stream,
3497
0
            offset,
3498
0
            whence,
3499
0
            error );
3500
3501
0
  if( offset == -1 )
3502
0
  {
3503
0
    libcerror_error_set(
3504
0
     error,
3505
0
     LIBCERROR_ERROR_DOMAIN_IO,
3506
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
3507
0
     "%s: unable to seek offset in data stream.",
3508
0
     function );
3509
3510
0
    offset = -1;
3511
0
  }
3512
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3513
0
  if( libcthreads_read_write_lock_release_for_write(
3514
0
       internal_file_entry->read_write_lock,
3515
0
       error ) != 1 )
3516
0
  {
3517
0
    libcerror_error_set(
3518
0
     error,
3519
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3520
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3521
0
     "%s: unable to release read/write lock for writing.",
3522
0
     function );
3523
3524
0
    return( -1 );
3525
0
  }
3526
0
#endif
3527
0
  return( offset );
3528
0
}
3529
3530
/* Retrieves the current offset of the data
3531
 * Returns the offset if successful or -1 on error
3532
 */
3533
int libfsxfs_file_entry_get_offset(
3534
     libfsxfs_file_entry_t *file_entry,
3535
     off64_t *offset,
3536
     libcerror_error_t **error )
3537
455
{
3538
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3539
455
  static char *function                               = "libfsxfs_file_entry_get_offset";
3540
455
  int result                                          = 1;
3541
3542
455
  if( file_entry == NULL )
3543
0
  {
3544
0
    libcerror_error_set(
3545
0
     error,
3546
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3547
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3548
0
     "%s: invalid file entry.",
3549
0
     function );
3550
3551
0
    return( -1 );
3552
0
  }
3553
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3554
3555
455
  if( internal_file_entry->inode == NULL )
3556
0
  {
3557
0
    libcerror_error_set(
3558
0
     error,
3559
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3560
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3561
0
     "%s: invalid file entry - missing inode.",
3562
0
     function );
3563
3564
0
    return( -1 );
3565
0
  }
3566
455
  if( ( internal_file_entry->inode->file_mode & 0xf000 ) != LIBFSXFS_FILE_TYPE_REGULAR_FILE )
3567
454
  {
3568
454
    libcerror_error_set(
3569
454
     error,
3570
454
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3571
454
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3572
454
     "%s: invalid file entry - invalid inode - unsupported file mode not a regular file.",
3573
454
     function );
3574
3575
454
    return( -1 );
3576
454
  }
3577
1
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3578
1
  if( libcthreads_read_write_lock_grab_for_read(
3579
1
       internal_file_entry->read_write_lock,
3580
1
       error ) != 1 )
3581
0
  {
3582
0
    libcerror_error_set(
3583
0
     error,
3584
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3585
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3586
0
     "%s: unable to grab read/write lock for reading.",
3587
0
     function );
3588
3589
0
    return( -1 );
3590
0
  }
3591
1
#endif
3592
1
  if( libfdata_stream_get_offset(
3593
1
       internal_file_entry->data_stream,
3594
1
       offset,
3595
1
       error ) != 1 )
3596
0
  {
3597
0
    libcerror_error_set(
3598
0
     error,
3599
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3600
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3601
0
     "%s: unable to retrieve offset from data stream.",
3602
0
     function );
3603
3604
0
    result = -1;
3605
0
  }
3606
1
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3607
1
  if( libcthreads_read_write_lock_release_for_read(
3608
1
       internal_file_entry->read_write_lock,
3609
1
       error ) != 1 )
3610
0
  {
3611
0
    libcerror_error_set(
3612
0
     error,
3613
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3614
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3615
0
     "%s: unable to release read/write lock for reading.",
3616
0
     function );
3617
3618
0
    return( -1 );
3619
0
  }
3620
1
#endif
3621
1
  return( result );
3622
1
}
3623
3624
/* Retrieves the size of the data
3625
 * Returns 1 if successful or -1 on error
3626
 */
3627
int libfsxfs_file_entry_get_size(
3628
     libfsxfs_file_entry_t *file_entry,
3629
     size64_t *size,
3630
     libcerror_error_t **error )
3631
455
{
3632
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3633
455
  static char *function                               = "libfsxfs_file_entry_get_size";
3634
3635
455
  if( file_entry == NULL )
3636
0
  {
3637
0
    libcerror_error_set(
3638
0
     error,
3639
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3640
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3641
0
     "%s: invalid file entry.",
3642
0
     function );
3643
3644
0
    return( -1 );
3645
0
  }
3646
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3647
3648
455
  if( size == NULL )
3649
0
  {
3650
0
    libcerror_error_set(
3651
0
     error,
3652
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3653
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3654
0
     "%s: invalid size.",
3655
0
     function );
3656
3657
0
    return( -1 );
3658
0
  }
3659
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3660
455
  if( libcthreads_read_write_lock_grab_for_read(
3661
455
       internal_file_entry->read_write_lock,
3662
455
       error ) != 1 )
3663
0
  {
3664
0
    libcerror_error_set(
3665
0
     error,
3666
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3667
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3668
0
     "%s: unable to grab read/write lock for reading.",
3669
0
     function );
3670
3671
0
    return( -1 );
3672
0
  }
3673
455
#endif
3674
455
  *size = internal_file_entry->data_size;
3675
3676
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3677
455
  if( libcthreads_read_write_lock_release_for_read(
3678
455
       internal_file_entry->read_write_lock,
3679
455
       error ) != 1 )
3680
0
  {
3681
0
    libcerror_error_set(
3682
0
     error,
3683
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3684
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3685
0
     "%s: unable to release read/write lock for reading.",
3686
0
     function );
3687
3688
0
    return( -1 );
3689
0
  }
3690
455
#endif
3691
455
  return( 1 );
3692
455
}
3693
3694
/* Retrieves the number of extents of the data
3695
 * Returns 1 if successful or -1 on error
3696
 */
3697
int libfsxfs_file_entry_get_number_of_extents(
3698
     libfsxfs_file_entry_t *file_entry,
3699
     int *number_of_extents,
3700
     libcerror_error_t **error )
3701
455
{
3702
455
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3703
455
  static char *function                               = "libfsxfs_file_entry_get_number_of_extents";
3704
455
  int result                                           = 1;
3705
3706
455
  if( file_entry == NULL )
3707
0
  {
3708
0
    libcerror_error_set(
3709
0
     error,
3710
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3711
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3712
0
     "%s: invalid file entry.",
3713
0
     function );
3714
3715
0
    return( -1 );
3716
0
  }
3717
455
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3718
3719
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3720
455
  if( libcthreads_read_write_lock_grab_for_read(
3721
455
       internal_file_entry->read_write_lock,
3722
455
       error ) != 1 )
3723
0
  {
3724
0
    libcerror_error_set(
3725
0
     error,
3726
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3727
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3728
0
     "%s: unable to grab read/write lock for reading.",
3729
0
     function );
3730
3731
0
    return( -1 );
3732
0
  }
3733
455
#endif
3734
455
  if( libfsxfs_inode_get_number_of_data_extents(
3735
455
       internal_file_entry->inode,
3736
455
       number_of_extents,
3737
455
       error ) != 1 )
3738
151
  {
3739
151
    libcerror_error_set(
3740
151
     error,
3741
151
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3742
151
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3743
151
     "%s: unable to retrieve number of data extents from inode.",
3744
151
     function );
3745
3746
151
    result = -1;
3747
151
  }
3748
455
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3749
455
  if( libcthreads_read_write_lock_release_for_read(
3750
455
       internal_file_entry->read_write_lock,
3751
455
       error ) != 1 )
3752
0
  {
3753
0
    libcerror_error_set(
3754
0
     error,
3755
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3756
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3757
0
     "%s: unable to release read/write lock for reading.",
3758
0
     function );
3759
3760
0
    return( -1 );
3761
0
  }
3762
455
#endif
3763
455
  return( result );
3764
455
}
3765
3766
/* Retrieves a specific extent of the data
3767
 * Returns 1 if successful or -1 on error
3768
 */
3769
int libfsxfs_file_entry_get_extent_by_index(
3770
     libfsxfs_file_entry_t *file_entry,
3771
     int extent_index,
3772
     off64_t *extent_offset,
3773
     size64_t *extent_size,
3774
     uint32_t *extent_flags,
3775
     libcerror_error_t **error )
3776
0
{
3777
0
  libfsxfs_extent_t *extent                           = NULL;
3778
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3779
0
  static char *function                               = "libfsxfs_file_entry_get_extent_by_index";
3780
0
  int result                                          = 1;
3781
3782
0
  if( file_entry == NULL )
3783
0
  {
3784
0
    libcerror_error_set(
3785
0
     error,
3786
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3787
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3788
0
     "%s: invalid file entry.",
3789
0
     function );
3790
3791
0
    return( -1 );
3792
0
  }
3793
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3794
3795
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3796
0
  if( libcthreads_read_write_lock_grab_for_read(
3797
0
       internal_file_entry->read_write_lock,
3798
0
       error ) != 1 )
3799
0
  {
3800
0
    libcerror_error_set(
3801
0
     error,
3802
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3803
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3804
0
     "%s: unable to grab read/write lock for reading.",
3805
0
     function );
3806
3807
0
    return( -1 );
3808
0
  }
3809
0
#endif
3810
0
  if( libfsxfs_inode_get_data_extent_by_index(
3811
0
       internal_file_entry->inode,
3812
0
       extent_index,
3813
0
       &extent,
3814
0
       error ) != 1 )
3815
0
  {
3816
0
    libcerror_error_set(
3817
0
     error,
3818
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3819
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3820
0
     "%s: unable to retrieve data extent: %d from inode.",
3821
0
     function,
3822
0
     extent_index );
3823
3824
0
    result = -1;
3825
0
  }
3826
0
  if( result == 1 )
3827
0
  {
3828
0
    if( libfsxfs_extent_get_values(
3829
0
         extent,
3830
0
         internal_file_entry->io_handle,
3831
0
         extent_offset,
3832
0
         extent_size,
3833
0
         extent_flags,
3834
0
         error ) != 1 )
3835
0
    {
3836
0
      libcerror_error_set(
3837
0
       error,
3838
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3839
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3840
0
       "%s: unable to retrieve extent: %d values.",
3841
0
       function,
3842
0
       extent_index );
3843
3844
0
      result = -1;
3845
0
    }
3846
0
  }
3847
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3848
0
  if( libcthreads_read_write_lock_release_for_read(
3849
0
       internal_file_entry->read_write_lock,
3850
0
       error ) != 1 )
3851
0
  {
3852
0
    libcerror_error_set(
3853
0
     error,
3854
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3855
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3856
0
     "%s: unable to release read/write lock for reading.",
3857
0
     function );
3858
3859
0
    return( -1 );
3860
0
  }
3861
0
#endif
3862
0
  return( result );
3863
0
}
3864