Coverage Report

Created: 2026-05-30 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libfsxfs/libfsxfs/libfsxfs_file_entry.c
Line
Count
Source
1
/*
2
 * File entry functions
3
 *
4
 * Copyright (C) 2020-2026, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <types.h>
25
26
#include "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.85k
{
57
1.85k
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
58
1.85k
  static char *function                               = "libfsxfs_file_entry_initialize";
59
60
1.85k
  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.85k
  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.85k
  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.85k
  internal_file_entry = memory_allocate_structure(
94
1.85k
                         libfsxfs_internal_file_entry_t );
95
96
1.85k
  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.85k
  if( memory_set(
108
1.85k
       internal_file_entry,
109
1.85k
       0,
110
1.85k
       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.85k
  if( ( ( inode->file_mode & 0xf000 ) == LIBFSXFS_FILE_TYPE_REGULAR_FILE )
125
1.77k
   || ( ( inode->file_mode & 0xf000 ) == LIBFSXFS_FILE_TYPE_SYMBOLIC_LINK ) )
126
677
  {
127
677
    if( libfsxfs_inode_get_data_size(
128
677
         inode,
129
677
         &( internal_file_entry->data_size ),
130
677
         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
677
    if( libfsxfs_data_stream_initialize(
142
677
         &( internal_file_entry->data_stream ),
143
677
         io_handle,
144
677
         inode,
145
677
         internal_file_entry->data_size,
146
677
         error ) != 1 )
147
274
    {
148
274
      libcerror_error_set(
149
274
       error,
150
274
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
151
274
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
152
274
       "%s: unable to create data stream.",
153
274
       function );
154
155
274
      goto on_error;
156
274
    }
157
677
  }
158
1.58k
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
159
1.58k
  if( libcthreads_read_write_lock_initialize(
160
1.58k
       &( internal_file_entry->read_write_lock ),
161
1.58k
       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.58k
#endif
173
1.58k
  internal_file_entry->io_handle       = io_handle;
174
1.58k
  internal_file_entry->file_io_handle  = file_io_handle;
175
1.58k
  internal_file_entry->file_system     = file_system;
176
1.58k
  internal_file_entry->inode_number    = inode_number;
177
1.58k
  internal_file_entry->inode           = inode;
178
1.58k
  internal_file_entry->directory_entry = directory_entry;
179
180
1.58k
  *file_entry = (libfsxfs_file_entry_t *) internal_file_entry;
181
182
1.58k
  return( 1 );
183
184
274
on_error:
185
274
  if( internal_file_entry != NULL )
186
274
  {
187
274
    memory_free(
188
274
     internal_file_entry );
189
274
  }
190
274
  return( -1 );
191
1.58k
}
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.83k
{
200
1.83k
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
201
1.83k
  static char *function                               = "libfsxfs_file_entry_free";
202
1.83k
  int result                                          = 1;
203
204
1.83k
  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.83k
  if( *file_entry != NULL )
216
1.58k
  {
217
1.58k
    internal_file_entry = (libfsxfs_internal_file_entry_t *) *file_entry;
218
1.58k
    *file_entry         = NULL;
219
220
1.58k
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
221
1.58k
    if( libcthreads_read_write_lock_free(
222
1.58k
         &( internal_file_entry->read_write_lock ),
223
1.58k
         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.58k
#endif
235
    /* The io_handle and file_io_handle references are freed elsewhere
236
     */
237
1.58k
    if( libfsxfs_inode_free(
238
1.58k
         &( internal_file_entry->inode ),
239
1.58k
         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.58k
    if( internal_file_entry->directory_entry != NULL )
251
407
    {
252
407
      if( libfsxfs_directory_entry_free(
253
407
           &( internal_file_entry->directory_entry ),
254
407
           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
407
    }
266
1.58k
    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.58k
    if( internal_file_entry->directory != NULL )
284
705
    {
285
705
      if( libfsxfs_directory_free(
286
705
           &( internal_file_entry->directory ),
287
705
           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
705
    }
299
1.58k
    if( internal_file_entry->data_stream != NULL )
300
403
    {
301
403
      if( libfdata_stream_free(
302
403
           &( internal_file_entry->data_stream ),
303
403
           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
403
    }
315
1.58k
    if( internal_file_entry->symbolic_link_data != NULL )
316
179
    {
317
179
      memory_free(
318
179
       internal_file_entry->symbolic_link_data );
319
179
    }
320
1.58k
    memory_free(
321
1.58k
     internal_file_entry );
322
1.58k
  }
323
1.83k
  return( result );
324
1.83k
}
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.17k
{
333
1.17k
  static char *function = "libfsxfs_internal_file_entry_get_directory";
334
335
1.17k
  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.17k
  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.17k
  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.17k
  if( ( internal_file_entry->inode->file_mode & 0xf000 ) == LIBFSXFS_FILE_TYPE_DIRECTORY )
369
1.13k
  {
370
1.13k
    if( libfsxfs_directory_initialize(
371
1.13k
         &( internal_file_entry->directory ),
372
1.13k
         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.13k
    if( libfsxfs_directory_read_file_io_handle(
384
1.13k
         internal_file_entry->directory,
385
1.13k
         internal_file_entry->io_handle,
386
1.13k
         internal_file_entry->file_io_handle,
387
1.13k
         internal_file_entry->inode,
388
1.13k
         error ) != 1 )
389
429
    {
390
429
      libcerror_error_set(
391
429
       error,
392
429
       LIBCERROR_ERROR_DOMAIN_IO,
393
429
       LIBCERROR_IO_ERROR_READ_FAILED,
394
429
       "%s: unable to read directory for inode: %" PRIu32 ".",
395
429
       function,
396
429
       internal_file_entry->inode_number );
397
398
429
      goto on_error;
399
429
    }
400
1.13k
  }
401
745
  return( 1 );
402
403
429
on_error:
404
429
  if( internal_file_entry->directory != NULL )
405
429
  {
406
429
    libfsxfs_directory_free(
407
429
     &( internal_file_entry->directory ),
408
429
     NULL );
409
429
  }
410
429
  return( -1 );
411
1.17k
}
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
635
{
420
635
  static char *function = "libfsxfs_internal_file_entry_get_symbolic_link_data";
421
635
  ssize_t read_count    = 0;
422
423
635
  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
635
  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
635
  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
635
  if( ( internal_file_entry->inode->file_mode & 0xf000 ) == LIBFSXFS_FILE_TYPE_SYMBOLIC_LINK )
457
549
  {
458
549
    if( ( internal_file_entry->data_size == 0 )
459
545
     || ( internal_file_entry->data_size > (uint64_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
460
50
    {
461
50
      libcerror_error_set(
462
50
       error,
463
50
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
464
50
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
465
50
       "%s: invalid data size value out of bounds.",
466
50
       function );
467
468
50
      goto on_error;
469
50
    }
470
499
    internal_file_entry->symbolic_link_data = (uint8_t *) memory_allocate(
471
499
                                                           sizeof( uint8_t ) * (size_t) internal_file_entry->data_size );
472
473
499
    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
499
    internal_file_entry->symbolic_link_data_size = (size_t) internal_file_entry->data_size;
485
486
499
    read_count = libfdata_stream_read_buffer_at_offset(
487
499
                  internal_file_entry->data_stream,
488
499
                  (intptr_t *) internal_file_entry->file_io_handle,
489
499
                  internal_file_entry->symbolic_link_data,
490
499
                  (size_t) internal_file_entry->data_size,
491
499
                  0,
492
499
                  0,
493
499
                  error );
494
495
499
    if( read_count != (ssize_t) internal_file_entry->data_size )
496
320
    {
497
320
      libcerror_error_set(
498
320
       error,
499
320
       LIBCERROR_ERROR_DOMAIN_IO,
500
320
       LIBCERROR_IO_ERROR_READ_FAILED,
501
320
       "%s: unable to read from data stream.",
502
320
       function );
503
504
320
      goto on_error;
505
320
    }
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
499
  }
519
265
  return( 1 );
520
521
370
on_error:
522
370
  if( internal_file_entry->symbolic_link_data != NULL )
523
320
  {
524
320
    memory_free(
525
320
     internal_file_entry->symbolic_link_data );
526
527
320
    internal_file_entry->symbolic_link_data = NULL;
528
320
  }
529
370
  internal_file_entry->symbolic_link_data_size = 0;
530
531
370
  return( -1 );
532
635
}
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
407
{
542
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
543
407
  static char *function                               = "libfsxfs_file_entry_get_inode_number";
544
545
407
  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
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
557
558
407
  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
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
570
407
  if( libcthreads_read_write_lock_grab_for_read(
571
407
       internal_file_entry->read_write_lock,
572
407
       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
407
#endif
584
407
  *inode_number = internal_file_entry->inode_number;
585
586
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
587
407
  if( libcthreads_read_write_lock_release_for_read(
588
407
       internal_file_entry->read_write_lock,
589
407
       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
407
#endif
601
407
  return( 1 );
602
407
}
603
604
/* Retrieves the creation date and time
605
 * The timestamp is a signed 64-bit POSIX date and time value in number of nanoseconds
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
407
{
614
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
615
407
  static char *function                               = "libfsxfs_file_entry_get_creation_time";
616
407
  int result                                          = 1;
617
618
407
  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
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
630
631
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
632
407
  if( libcthreads_read_write_lock_grab_for_read(
633
407
       internal_file_entry->read_write_lock,
634
407
       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
407
#endif
646
407
  result = libfsxfs_inode_get_creation_time(
647
407
            internal_file_entry->inode,
648
407
            posix_time,
649
407
            error );
650
651
407
  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
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
663
407
  if( libcthreads_read_write_lock_release_for_read(
664
407
       internal_file_entry->read_write_lock,
665
407
       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
407
#endif
677
407
  return( result );
678
407
}
679
680
/* Retrieves the modification date and time
681
 * The timestamp is a signed 64-bit POSIX date and time value in number of nanoseconds
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
407
{
690
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
691
407
  static char *function                               = "libfsxfs_file_entry_get_modification_time";
692
407
  int result                                          = 1;
693
694
407
  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
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
706
707
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
708
407
  if( libcthreads_read_write_lock_grab_for_read(
709
407
       internal_file_entry->read_write_lock,
710
407
       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
407
#endif
722
407
  if( libfsxfs_inode_get_modification_time(
723
407
       internal_file_entry->inode,
724
407
       posix_time,
725
407
       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
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
737
407
  if( libcthreads_read_write_lock_release_for_read(
738
407
       internal_file_entry->read_write_lock,
739
407
       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
407
#endif
751
407
  return( result );
752
407
}
753
754
/* Retrieves the access date and time
755
 * The timestamp is a signed 64-bit POSIX date and time value in number of nanoseconds
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
407
{
764
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
765
407
  static char *function                               = "libfsxfs_file_entry_get_access_time";
766
407
  int result                                          = 1;
767
768
407
  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
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
780
781
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
782
407
  if( libcthreads_read_write_lock_grab_for_read(
783
407
       internal_file_entry->read_write_lock,
784
407
       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
407
#endif
796
407
  if( libfsxfs_inode_get_access_time(
797
407
       internal_file_entry->inode,
798
407
       posix_time,
799
407
       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
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
811
407
  if( libcthreads_read_write_lock_release_for_read(
812
407
       internal_file_entry->read_write_lock,
813
407
       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
407
#endif
825
407
  return( result );
826
407
}
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 nanoseconds
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
407
{
838
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
839
407
  static char *function                               = "libfsxfs_file_entry_get_inode_change_time";
840
407
  int result                                          = 1;
841
842
407
  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
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
854
855
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
856
407
  if( libcthreads_read_write_lock_grab_for_read(
857
407
       internal_file_entry->read_write_lock,
858
407
       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
407
#endif
870
407
  if( libfsxfs_inode_get_inode_change_time(
871
407
       internal_file_entry->inode,
872
407
       posix_time,
873
407
       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
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
885
407
  if( libcthreads_read_write_lock_release_for_read(
886
407
       internal_file_entry->read_write_lock,
887
407
       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
407
#endif
899
407
  return( result );
900
407
}
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
407
{
911
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
912
407
  static char *function                               = "libfsxfs_file_entry_get_file_mode";
913
407
  int result                                          = 1;
914
915
407
  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
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
927
928
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
929
407
  if( libcthreads_read_write_lock_grab_for_read(
930
407
       internal_file_entry->read_write_lock,
931
407
       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
407
#endif
943
407
  if( libfsxfs_inode_get_file_mode(
944
407
       internal_file_entry->inode,
945
407
       file_mode,
946
407
       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
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
958
407
  if( libcthreads_read_write_lock_release_for_read(
959
407
       internal_file_entry->read_write_lock,
960
407
       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
407
#endif
972
407
  return( result );
973
407
}
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
407
{
984
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
985
407
  static char *function                               = "libfsxfs_file_entry_get_number_of_links";
986
407
  int result                                          = 1;
987
988
407
  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
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1000
1001
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1002
407
  if( libcthreads_read_write_lock_grab_for_read(
1003
407
       internal_file_entry->read_write_lock,
1004
407
       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
407
#endif
1016
407
  if( libfsxfs_inode_get_number_of_links(
1017
407
       internal_file_entry->inode,
1018
407
       number_of_links,
1019
407
       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
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1031
407
  if( libcthreads_read_write_lock_release_for_read(
1032
407
       internal_file_entry->read_write_lock,
1033
407
       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
407
#endif
1045
407
  return( result );
1046
407
}
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
407
{
1057
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1058
407
  static char *function                               = "libfsxfs_file_entry_get_owner_identifier";
1059
407
  int result                                          = 1;
1060
1061
407
  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
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1073
1074
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1075
407
  if( libcthreads_read_write_lock_grab_for_read(
1076
407
       internal_file_entry->read_write_lock,
1077
407
       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
407
#endif
1089
407
  if( libfsxfs_inode_get_owner_identifier(
1090
407
       internal_file_entry->inode,
1091
407
       owner_identifier,
1092
407
       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
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1104
407
  if( libcthreads_read_write_lock_release_for_read(
1105
407
       internal_file_entry->read_write_lock,
1106
407
       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
407
#endif
1118
407
  return( result );
1119
407
}
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
407
{
1130
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1131
407
  static char *function                               = "libfsxfs_file_entry_get_group_identifier";
1132
407
  int result                                          = 1;
1133
1134
407
  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
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1146
1147
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1148
407
  if( libcthreads_read_write_lock_grab_for_read(
1149
407
       internal_file_entry->read_write_lock,
1150
407
       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
407
#endif
1162
407
  if( libfsxfs_inode_get_group_identifier(
1163
407
       internal_file_entry->inode,
1164
407
       group_identifier,
1165
407
       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
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1177
407
  if( libcthreads_read_write_lock_release_for_read(
1178
407
       internal_file_entry->read_write_lock,
1179
407
       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
407
#endif
1191
407
  return( result );
1192
407
}
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
407
{
1203
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1204
407
  static char *function                               = "libfsxfs_file_entry_get_device_identifier";
1205
407
  int result                                          = 0;
1206
1207
407
  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
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1219
1220
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1221
407
  if( libcthreads_read_write_lock_grab_for_read(
1222
407
       internal_file_entry->read_write_lock,
1223
407
       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
407
#endif
1235
407
  result = libfsxfs_inode_get_device_identifier(
1236
407
            internal_file_entry->inode,
1237
407
            device_identifier,
1238
407
            error );
1239
1240
407
  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
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1252
407
  if( libcthreads_read_write_lock_release_for_read(
1253
407
       internal_file_entry->read_write_lock,
1254
407
       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
407
#endif
1266
407
  return( result );
1267
407
}
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
407
{
1279
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1280
407
  static char *function                               = "libfsxfs_file_entry_get_device_number";
1281
407
  int result                                          = 0;
1282
1283
407
  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
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1295
1296
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1297
407
  if( libcthreads_read_write_lock_grab_for_read(
1298
407
       internal_file_entry->read_write_lock,
1299
407
       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
407
#endif
1311
407
  result = libfsxfs_inode_get_device_number(
1312
407
            internal_file_entry->inode,
1313
407
            major_device_number,
1314
407
            minor_device_number,
1315
407
            error );
1316
1317
407
  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
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1329
407
  if( libcthreads_read_write_lock_release_for_read(
1330
407
       internal_file_entry->read_write_lock,
1331
407
       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
407
#endif
1343
407
  return( result );
1344
407
}
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
407
{
1356
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1357
407
  static char *function                               = "libfsxfs_file_entry_get_utf8_name_size";
1358
407
  int result                                          = 0;
1359
1360
407
  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
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1372
1373
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1374
407
  if( libcthreads_read_write_lock_grab_for_read(
1375
407
       internal_file_entry->read_write_lock,
1376
407
       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
407
#endif
1388
407
  if( internal_file_entry->directory_entry != NULL )
1389
407
  {
1390
407
    result = libfsxfs_directory_entry_get_utf8_name_size(
1391
407
              internal_file_entry->directory_entry,
1392
407
              utf8_string_size,
1393
407
              error );
1394
1395
407
    if( result != 1 )
1396
292
    {
1397
292
      libcerror_error_set(
1398
292
       error,
1399
292
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1400
292
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1401
292
       "%s: unable to retrieve size of UTF-8 name from directory entry.",
1402
292
       function );
1403
1404
292
      result = -1;
1405
292
    }
1406
407
  }
1407
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1408
407
  if( libcthreads_read_write_lock_release_for_read(
1409
407
       internal_file_entry->read_write_lock,
1410
407
       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
407
#endif
1422
407
  return( result );
1423
407
}
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
407
{
1436
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1437
407
  static char *function                               = "libfsxfs_file_entry_get_utf8_name";
1438
407
  int result                                          = 0;
1439
1440
407
  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
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1452
1453
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1454
407
  if( libcthreads_read_write_lock_grab_for_read(
1455
407
       internal_file_entry->read_write_lock,
1456
407
       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
407
#endif
1468
407
  if( internal_file_entry->directory_entry != NULL )
1469
407
  {
1470
407
    result = libfsxfs_directory_entry_get_utf8_name(
1471
407
              internal_file_entry->directory_entry,
1472
407
              utf8_string,
1473
407
              utf8_string_size,
1474
407
              error );
1475
1476
407
    if( result != 1 )
1477
316
    {
1478
316
      libcerror_error_set(
1479
316
       error,
1480
316
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1481
316
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1482
316
       "%s: unable to retrieve UTF-8 name from directory entry.",
1483
316
       function );
1484
1485
316
      result = -1;
1486
316
    }
1487
407
  }
1488
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1489
407
  if( libcthreads_read_write_lock_release_for_read(
1490
407
       internal_file_entry->read_write_lock,
1491
407
       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
407
#endif
1503
407
  return( result );
1504
407
}
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
407
{
1675
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1676
407
  static char *function                               = "libfsxfs_file_entry_get_utf8_symbolic_link_target_size";
1677
407
  int result                                          = 0;
1678
1679
407
  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
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1691
1692
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1693
407
  if( libcthreads_read_write_lock_grab_for_write(
1694
407
       internal_file_entry->read_write_lock,
1695
407
       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
407
#endif
1707
407
  if( internal_file_entry->symbolic_link_data == NULL )
1708
407
  {
1709
407
    if( libfsxfs_internal_file_entry_get_symbolic_link_data(
1710
407
         internal_file_entry,
1711
407
         error ) != 1 )
1712
185
    {
1713
185
      libcerror_error_set(
1714
185
       error,
1715
185
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1716
185
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1717
185
       "%s: unable to determine symbolic link data.",
1718
185
       function );
1719
1720
185
      result = -1;
1721
185
    }
1722
407
  }
1723
407
  if( internal_file_entry->symbolic_link_data != NULL )
1724
179
  {
1725
179
    result = libuna_utf8_string_size_from_utf8_stream(
1726
179
              internal_file_entry->symbolic_link_data,
1727
179
              internal_file_entry->symbolic_link_data_size,
1728
179
              utf8_string_size,
1729
179
              error );
1730
1731
179
    if( result != 1 )
1732
88
    {
1733
88
      libcerror_error_set(
1734
88
       error,
1735
88
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1736
88
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1737
88
       "%s: unable to retrieve UTF-8 string size.",
1738
88
       function );
1739
1740
88
      result = -1;
1741
88
    }
1742
179
  }
1743
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1744
407
  if( libcthreads_read_write_lock_release_for_write(
1745
407
       internal_file_entry->read_write_lock,
1746
407
       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
407
#endif
1758
407
  return( result );
1759
407
}
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
407
{
1771
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1772
407
  static char *function                               = "libfsxfs_file_entry_get_utf8_symbolic_link_target";
1773
407
  int result                                          = 0;
1774
1775
407
  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
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1787
1788
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1789
407
  if( libcthreads_read_write_lock_grab_for_write(
1790
407
       internal_file_entry->read_write_lock,
1791
407
       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
407
#endif
1803
407
  if( internal_file_entry->symbolic_link_data == NULL )
1804
228
  {
1805
228
    if( libfsxfs_internal_file_entry_get_symbolic_link_data(
1806
228
         internal_file_entry,
1807
228
         error ) != 1 )
1808
185
    {
1809
185
      libcerror_error_set(
1810
185
       error,
1811
185
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1812
185
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1813
185
       "%s: unable to determine symbolic link data.",
1814
185
       function );
1815
1816
185
      result = -1;
1817
185
    }
1818
228
  }
1819
407
  if( internal_file_entry->symbolic_link_data != NULL )
1820
179
  {
1821
179
    result = libuna_utf8_string_copy_from_utf8_stream(
1822
179
              utf8_string,
1823
179
              utf8_string_size,
1824
179
              internal_file_entry->symbolic_link_data,
1825
179
              internal_file_entry->symbolic_link_data_size,
1826
179
              error );
1827
1828
179
    if( result != 1 )
1829
94
    {
1830
94
      libcerror_error_set(
1831
94
       error,
1832
94
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1833
94
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1834
94
       "%s: unable to retrieve UTF-8 string.",
1835
94
       function );
1836
1837
94
      result = -1;
1838
94
    }
1839
179
  }
1840
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1841
407
  if( libcthreads_read_write_lock_release_for_write(
1842
407
       internal_file_entry->read_write_lock,
1843
407
       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
407
#endif
1855
407
  return( result );
1856
407
}
1857
1858
/* Retrieves the size of the UTF-16 encoded symbolic link target
1859
 * The size should include the end of string character
1860
 * Returns 1 if successful, 0 if not available or -1 on error
1861
 */
1862
int libfsxfs_file_entry_get_utf16_symbolic_link_target_size(
1863
     libfsxfs_file_entry_t *file_entry,
1864
     size_t *utf16_string_size,
1865
     libcerror_error_t **error )
1866
0
{
1867
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1868
0
  static char *function                               = "libfsxfs_file_entry_get_utf16_symbolic_link_target_size";
1869
0
  int result                                          = 0;
1870
1871
0
  if( file_entry == NULL )
1872
0
  {
1873
0
    libcerror_error_set(
1874
0
     error,
1875
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1876
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1877
0
     "%s: invalid file entry.",
1878
0
     function );
1879
1880
0
    return( -1 );
1881
0
  }
1882
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1883
1884
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1885
0
  if( libcthreads_read_write_lock_grab_for_write(
1886
0
       internal_file_entry->read_write_lock,
1887
0
       error ) != 1 )
1888
0
  {
1889
0
    libcerror_error_set(
1890
0
     error,
1891
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1892
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1893
0
     "%s: unable to grab read/write lock for writing.",
1894
0
     function );
1895
1896
0
    return( -1 );
1897
0
  }
1898
0
#endif
1899
0
  if( internal_file_entry->symbolic_link_data == NULL )
1900
0
  {
1901
0
    if( libfsxfs_internal_file_entry_get_symbolic_link_data(
1902
0
         internal_file_entry,
1903
0
         error ) != 1 )
1904
0
    {
1905
0
      libcerror_error_set(
1906
0
       error,
1907
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1908
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1909
0
       "%s: unable to determine symbolic link data.",
1910
0
       function );
1911
1912
0
      result = -1;
1913
0
    }
1914
0
  }
1915
0
  if( internal_file_entry->symbolic_link_data != NULL )
1916
0
  {
1917
0
    result = libuna_utf16_string_size_from_utf8_stream(
1918
0
              internal_file_entry->symbolic_link_data,
1919
0
              internal_file_entry->symbolic_link_data_size,
1920
0
              utf16_string_size,
1921
0
              error );
1922
1923
0
    if( result != 1 )
1924
0
    {
1925
0
      libcerror_error_set(
1926
0
       error,
1927
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1928
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1929
0
       "%s: unable to retrieve UTF-16 string size.",
1930
0
       function );
1931
1932
0
      result = -1;
1933
0
    }
1934
0
  }
1935
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1936
0
  if( libcthreads_read_write_lock_release_for_write(
1937
0
       internal_file_entry->read_write_lock,
1938
0
       error ) != 1 )
1939
0
  {
1940
0
    libcerror_error_set(
1941
0
     error,
1942
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1943
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1944
0
     "%s: unable to release read/write lock for writing.",
1945
0
     function );
1946
1947
0
    return( -1 );
1948
0
  }
1949
0
#endif
1950
0
  return( result );
1951
0
}
1952
1953
/* Retrieves the UTF-16 encoded symbolic link target
1954
 * The size should include the end of string character
1955
 * Returns 1 if successful, 0 if not available or -1 on error
1956
 */
1957
int libfsxfs_file_entry_get_utf16_symbolic_link_target(
1958
     libfsxfs_file_entry_t *file_entry,
1959
     uint16_t *utf16_string,
1960
     size_t utf16_string_size,
1961
     libcerror_error_t **error )
1962
0
{
1963
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
1964
0
  static char *function                               = "libfsxfs_file_entry_get_utf16_symbolic_link_target";
1965
0
  int result                                          = 0;
1966
1967
0
  if( file_entry == NULL )
1968
0
  {
1969
0
    libcerror_error_set(
1970
0
     error,
1971
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1972
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1973
0
     "%s: invalid file entry.",
1974
0
     function );
1975
1976
0
    return( -1 );
1977
0
  }
1978
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
1979
1980
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
1981
0
  if( libcthreads_read_write_lock_grab_for_write(
1982
0
       internal_file_entry->read_write_lock,
1983
0
       error ) != 1 )
1984
0
  {
1985
0
    libcerror_error_set(
1986
0
     error,
1987
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1988
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1989
0
     "%s: unable to grab read/write lock for writing.",
1990
0
     function );
1991
1992
0
    return( -1 );
1993
0
  }
1994
0
#endif
1995
0
  if( internal_file_entry->symbolic_link_data == NULL )
1996
0
  {
1997
0
    if( libfsxfs_internal_file_entry_get_symbolic_link_data(
1998
0
         internal_file_entry,
1999
0
         error ) != 1 )
2000
0
    {
2001
0
      libcerror_error_set(
2002
0
       error,
2003
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2004
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2005
0
       "%s: unable to determine symbolic link data.",
2006
0
       function );
2007
2008
0
      result = -1;
2009
0
    }
2010
0
  }
2011
0
  if( internal_file_entry->symbolic_link_data != NULL )
2012
0
  {
2013
0
    result = libuna_utf16_string_copy_from_utf8_stream(
2014
0
              utf16_string,
2015
0
              utf16_string_size,
2016
0
              internal_file_entry->symbolic_link_data,
2017
0
              internal_file_entry->symbolic_link_data_size,
2018
0
              error );
2019
2020
0
    if( result != 1 )
2021
0
    {
2022
0
      libcerror_error_set(
2023
0
       error,
2024
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2025
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2026
0
       "%s: unable to retrieve UTF-16 string.",
2027
0
       function );
2028
2029
0
      result = -1;
2030
0
    }
2031
0
  }
2032
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2033
0
  if( libcthreads_read_write_lock_release_for_write(
2034
0
       internal_file_entry->read_write_lock,
2035
0
       error ) != 1 )
2036
0
  {
2037
0
    libcerror_error_set(
2038
0
     error,
2039
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2040
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2041
0
     "%s: unable to release read/write lock for writing.",
2042
0
     function );
2043
2044
0
    return( -1 );
2045
0
  }
2046
0
#endif
2047
0
  return( result );
2048
0
}
2049
2050
/* Determines the extended attributes
2051
 * Returns 1 if successful or -1 on error
2052
 */
2053
int libfsxfs_internal_file_entry_get_extended_attributes(
2054
     libfsxfs_internal_file_entry_t *internal_file_entry,
2055
     libcerror_error_t **error )
2056
0
{
2057
0
  static char *function = "libfsxfs_internal_file_entry_get_extended_attributes";
2058
2059
0
  if( internal_file_entry == NULL )
2060
0
  {
2061
0
    libcerror_error_set(
2062
0
     error,
2063
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2064
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2065
0
     "%s: invalid file entry.",
2066
0
     function );
2067
2068
0
    return( -1 );
2069
0
  }
2070
0
  if( internal_file_entry->extended_attributes_array != NULL )
2071
0
  {
2072
0
    libcerror_error_set(
2073
0
     error,
2074
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2075
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2076
0
     "%s: invalid file entry - extended attributes array value already set.",
2077
0
     function );
2078
2079
0
    return( -1 );
2080
0
  }
2081
0
  if( libcdata_array_initialize(
2082
0
       &( internal_file_entry->extended_attributes_array ),
2083
0
       0,
2084
0
       error ) != 1 )
2085
0
  {
2086
0
    libcerror_error_set(
2087
0
     error,
2088
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2089
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2090
0
     "%s: unable to create extended attributes array.",
2091
0
     function );
2092
2093
0
    goto on_error;
2094
0
  }
2095
0
  if( libfsxfs_attributes_read_from_inode(
2096
0
       internal_file_entry->io_handle,
2097
0
       internal_file_entry->file_io_handle,
2098
0
       internal_file_entry->inode,
2099
0
       internal_file_entry->extended_attributes_array,
2100
0
       error ) != 1 )
2101
0
  {
2102
0
    libcerror_error_set(
2103
0
     error,
2104
0
     LIBCERROR_ERROR_DOMAIN_IO,
2105
0
     LIBCERROR_IO_ERROR_READ_FAILED,
2106
0
     "%s: unable to read extended attributes from inode.",
2107
0
     function );
2108
2109
0
    goto on_error;
2110
0
  }
2111
0
  return( 1 );
2112
2113
0
on_error:
2114
0
  if( internal_file_entry->extended_attributes_array != NULL )
2115
0
  {
2116
0
    libcdata_array_free(
2117
0
     &( internal_file_entry->extended_attributes_array ),
2118
0
     (int (*)(intptr_t **, libcerror_error_t **)) &libfsxfs_attribute_values_free,
2119
0
     NULL );
2120
0
  }
2121
0
  return( -1 );
2122
0
}
2123
2124
/* Retrieves the number of extended attributes
2125
 * Returns 1 if successful or -1 on error
2126
 */
2127
int libfsxfs_file_entry_get_number_of_extended_attributes(
2128
     libfsxfs_file_entry_t *file_entry,
2129
     int *number_of_extended_attributes,
2130
     libcerror_error_t **error )
2131
0
{
2132
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
2133
0
  static char *function                               = "libfsxfs_file_entry_get_number_of_extended_attributes";
2134
0
  int result                                          = 1;
2135
2136
0
  if( file_entry == NULL )
2137
0
  {
2138
0
    libcerror_error_set(
2139
0
     error,
2140
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2141
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2142
0
     "%s: invalid file entry.",
2143
0
     function );
2144
2145
0
    return( -1 );
2146
0
  }
2147
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
2148
2149
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2150
0
  if( libcthreads_read_write_lock_grab_for_write(
2151
0
       internal_file_entry->read_write_lock,
2152
0
       error ) != 1 )
2153
0
  {
2154
0
    libcerror_error_set(
2155
0
     error,
2156
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2157
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2158
0
     "%s: unable to grab read/write lock for writing.",
2159
0
     function );
2160
2161
0
    return( -1 );
2162
0
  }
2163
0
#endif
2164
0
  if( internal_file_entry->extended_attributes_array == NULL )
2165
0
  {
2166
0
    if( libfsxfs_internal_file_entry_get_extended_attributes(
2167
0
         internal_file_entry,
2168
0
         error ) != 1 )
2169
0
    {
2170
0
      libcerror_error_set(
2171
0
       error,
2172
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2173
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2174
0
       "%s: unable to determine extended attributes.",
2175
0
       function );
2176
2177
0
      result = -1;
2178
0
    }
2179
0
  }
2180
0
  if( internal_file_entry->extended_attributes_array != NULL )
2181
0
  {
2182
0
    if( libcdata_array_get_number_of_entries(
2183
0
         internal_file_entry->extended_attributes_array,
2184
0
         number_of_extended_attributes,
2185
0
         error ) != 1 )
2186
0
    {
2187
0
      libcerror_error_set(
2188
0
       error,
2189
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2190
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2191
0
       "%s: unable to retrieve number of entries from extended attributes array.",
2192
0
       function );
2193
2194
0
      result = -1;
2195
0
    }
2196
0
  }
2197
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2198
0
  if( libcthreads_read_write_lock_release_for_write(
2199
0
       internal_file_entry->read_write_lock,
2200
0
       error ) != 1 )
2201
0
  {
2202
0
    libcerror_error_set(
2203
0
     error,
2204
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2205
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2206
0
     "%s: unable to release read/write lock for writing.",
2207
0
     function );
2208
2209
0
    return( -1 );
2210
0
  }
2211
0
#endif
2212
0
  return( result );
2213
0
}
2214
2215
/* Retrieves the extended attribute for the specific index
2216
 * Returns 1 if successful or -1 on error
2217
 */
2218
int libfsxfs_file_entry_get_extended_attribute_by_index(
2219
     libfsxfs_file_entry_t *file_entry,
2220
     int extended_attribute_index,
2221
     libfsxfs_extended_attribute_t **extended_attribute,
2222
     libcerror_error_t **error )
2223
0
{
2224
0
  libfsxfs_attribute_values_t *attribute_values       = NULL;
2225
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
2226
0
  static char *function                               = "libfsxfs_file_entry_get_extended_attribute_by_index";
2227
0
  int result                                          = 1;
2228
2229
0
  if( file_entry == NULL )
2230
0
  {
2231
0
    libcerror_error_set(
2232
0
     error,
2233
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2234
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2235
0
     "%s: invalid file entry.",
2236
0
     function );
2237
2238
0
    return( -1 );
2239
0
  }
2240
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
2241
2242
0
  if( extended_attribute == NULL )
2243
0
  {
2244
0
    libcerror_error_set(
2245
0
     error,
2246
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2247
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2248
0
     "%s: invalid extended attribute.",
2249
0
     function );
2250
2251
0
    return( -1 );
2252
0
  }
2253
0
  if( *extended_attribute != NULL )
2254
0
  {
2255
0
    libcerror_error_set(
2256
0
     error,
2257
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2258
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2259
0
     "%s: invalid extended attribute value already set.",
2260
0
     function );
2261
2262
0
    return( -1 );
2263
0
  }
2264
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2265
0
  if( libcthreads_read_write_lock_grab_for_write(
2266
0
       internal_file_entry->read_write_lock,
2267
0
       error ) != 1 )
2268
0
  {
2269
0
    libcerror_error_set(
2270
0
     error,
2271
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2272
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2273
0
     "%s: unable to grab read/write lock for writing.",
2274
0
     function );
2275
2276
0
    return( -1 );
2277
0
  }
2278
0
#endif
2279
0
  if( internal_file_entry->extended_attributes_array == NULL )
2280
0
  {
2281
0
    if( libfsxfs_internal_file_entry_get_extended_attributes(
2282
0
         internal_file_entry,
2283
0
         error ) != 1 )
2284
0
    {
2285
0
      libcerror_error_set(
2286
0
       error,
2287
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2288
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2289
0
       "%s: unable to determine extended attributes.",
2290
0
       function );
2291
2292
0
      result = -1;
2293
0
    }
2294
0
  }
2295
0
  if( internal_file_entry->extended_attributes_array != NULL )
2296
0
  {
2297
0
    if( libcdata_array_get_entry_by_index(
2298
0
         internal_file_entry->extended_attributes_array,
2299
0
         extended_attribute_index,
2300
0
         (intptr_t **) &attribute_values,
2301
0
         error ) != 1 )
2302
0
    {
2303
0
      libcerror_error_set(
2304
0
       error,
2305
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2306
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2307
0
       "%s: unable to retrieve attribute: %d values.",
2308
0
       function,
2309
0
       extended_attribute_index );
2310
2311
0
      result = -1;
2312
0
    }
2313
0
    else
2314
0
    {
2315
0
      if( libfsxfs_extended_attribute_initialize(
2316
0
           extended_attribute,
2317
0
           internal_file_entry->io_handle,
2318
0
           internal_file_entry->file_io_handle,
2319
0
           internal_file_entry->file_system,
2320
0
           internal_file_entry->inode,
2321
0
           attribute_values,
2322
0
           error ) != 1 )
2323
0
      {
2324
0
        libcerror_error_set(
2325
0
         error,
2326
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2327
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2328
0
         "%s: unable to create extended attribute.",
2329
0
         function );
2330
2331
0
        result = -1;
2332
0
      }
2333
0
    }
2334
0
  }
2335
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2336
0
  if( libcthreads_read_write_lock_release_for_write(
2337
0
       internal_file_entry->read_write_lock,
2338
0
       error ) != 1 )
2339
0
  {
2340
0
    libcerror_error_set(
2341
0
     error,
2342
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2343
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2344
0
     "%s: unable to release read/write lock for writing.",
2345
0
     function );
2346
2347
0
    return( -1 );
2348
0
  }
2349
0
#endif
2350
0
  return( result );
2351
0
}
2352
2353
/* Retrieves the attribute values for an UTF-8 encoded name
2354
 * Returns 1 if successful, 0 if no such file entry or -1 on error
2355
 */
2356
int libfsxfs_internal_file_entry_get_attribute_values_by_utf8_name(
2357
     libfsxfs_internal_file_entry_t *internal_file_entry,
2358
     const uint8_t *utf8_string,
2359
     size_t utf8_string_length,
2360
     libfsxfs_attribute_values_t **attribute_values,
2361
     libcerror_error_t **error )
2362
0
{
2363
0
  libfsxfs_attribute_values_t *safe_attribute_values = NULL;
2364
0
  static char *function                              = "libfsxfs_internal_file_entry_get_attribute_values_by_utf8_name";
2365
0
  int attribute_index                                = 0;
2366
0
  int number_of_attributes                           = 0;
2367
0
  int result                                         = 0;
2368
2369
0
  if( internal_file_entry == NULL )
2370
0
  {
2371
0
    libcerror_error_set(
2372
0
     error,
2373
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2374
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2375
0
     "%s: invalid file entry.",
2376
0
     function );
2377
2378
0
    return( -1 );
2379
0
  }
2380
0
  if( internal_file_entry->extended_attributes_array == NULL )
2381
0
  {
2382
0
    if( libfsxfs_internal_file_entry_get_extended_attributes(
2383
0
         internal_file_entry,
2384
0
         error ) != 1 )
2385
0
    {
2386
0
      libcerror_error_set(
2387
0
       error,
2388
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2389
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2390
0
       "%s: unable to determine extended attributes.",
2391
0
       function );
2392
2393
0
      return( -1 );
2394
0
    }
2395
0
  }
2396
0
  if( libcdata_array_get_number_of_entries(
2397
0
       internal_file_entry->extended_attributes_array,
2398
0
       &number_of_attributes,
2399
0
       error ) != 1 )
2400
0
  {
2401
0
    libcerror_error_set(
2402
0
     error,
2403
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2404
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2405
0
     "%s: unable to retrieve number of entries from extended attributes array.",
2406
0
     function );
2407
2408
0
    return( -1 );
2409
0
  }
2410
0
  for( attribute_index = 0;
2411
0
       attribute_index < number_of_attributes;
2412
0
       attribute_index++ )
2413
0
  {
2414
0
    if( libcdata_array_get_entry_by_index(
2415
0
         internal_file_entry->extended_attributes_array,
2416
0
         attribute_index,
2417
0
         (intptr_t **) &safe_attribute_values,
2418
0
         error ) != 1 )
2419
0
    {
2420
0
      libcerror_error_set(
2421
0
       error,
2422
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2423
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2424
0
       "%s: unable to retrieve attribute: %d values.",
2425
0
       function,
2426
0
       attribute_index );
2427
2428
0
      return( -1 );
2429
0
    }
2430
0
    result = libfsxfs_attribute_values_compare_name_with_utf8_string(
2431
0
              safe_attribute_values,
2432
0
              utf8_string,
2433
0
              utf8_string_length,
2434
0
              error );
2435
2436
0
    if( result == -1 )
2437
0
    {
2438
0
      libcerror_error_set(
2439
0
       error,
2440
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2441
0
       LIBCERROR_RUNTIME_ERROR_GENERIC,
2442
0
       "%s: unable to compare UTF-8 string with name of attribute: %d values.",
2443
0
       function,
2444
0
       attribute_index );
2445
2446
0
      return( -1 );
2447
0
    }
2448
0
    else if( result == LIBUNA_COMPARE_EQUAL )
2449
0
    {
2450
0
      *attribute_values = safe_attribute_values;
2451
2452
0
      return( 1 );
2453
0
    }
2454
0
  }
2455
0
  return( 0 );
2456
0
}
2457
2458
/* Retrieves the attribute values for an UTF-16 encoded name
2459
 * Returns 1 if successful, 0 if no such file entry or -1 on error
2460
 */
2461
int libfsxfs_internal_file_entry_get_attribute_values_by_utf16_name(
2462
     libfsxfs_internal_file_entry_t *internal_file_entry,
2463
     const uint16_t *utf16_string,
2464
     size_t utf16_string_length,
2465
     libfsxfs_attribute_values_t **attribute_values,
2466
     libcerror_error_t **error )
2467
0
{
2468
0
  libfsxfs_attribute_values_t *safe_attribute_values = NULL;
2469
0
  static char *function                              = "libfsxfs_internal_file_entry_get_attribute_values_by_utf16_name";
2470
0
  int attribute_index                                = 0;
2471
0
  int number_of_attributes                           = 0;
2472
0
  int result                                         = 0;
2473
2474
0
  if( internal_file_entry == NULL )
2475
0
  {
2476
0
    libcerror_error_set(
2477
0
     error,
2478
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2479
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2480
0
     "%s: invalid file entry.",
2481
0
     function );
2482
2483
0
    return( -1 );
2484
0
  }
2485
0
  if( internal_file_entry->extended_attributes_array == NULL )
2486
0
  {
2487
0
    if( libfsxfs_internal_file_entry_get_extended_attributes(
2488
0
         internal_file_entry,
2489
0
         error ) != 1 )
2490
0
    {
2491
0
      libcerror_error_set(
2492
0
       error,
2493
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2494
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2495
0
       "%s: unable to determine extended attributes.",
2496
0
       function );
2497
2498
0
      return( -1 );
2499
0
    }
2500
0
  }
2501
0
  if( libcdata_array_get_number_of_entries(
2502
0
       internal_file_entry->extended_attributes_array,
2503
0
       &number_of_attributes,
2504
0
       error ) != 1 )
2505
0
  {
2506
0
    libcerror_error_set(
2507
0
     error,
2508
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2509
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2510
0
     "%s: unable to retrieve number of entries from extended attributes array.",
2511
0
     function );
2512
2513
0
    return( -1 );
2514
0
  }
2515
0
  for( attribute_index = 0;
2516
0
       attribute_index < number_of_attributes;
2517
0
       attribute_index++ )
2518
0
  {
2519
0
    if( libcdata_array_get_entry_by_index(
2520
0
         internal_file_entry->extended_attributes_array,
2521
0
         attribute_index,
2522
0
         (intptr_t **) &safe_attribute_values,
2523
0
         error ) != 1 )
2524
0
    {
2525
0
      libcerror_error_set(
2526
0
       error,
2527
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2528
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2529
0
       "%s: unable to retrieve attribute: %d values.",
2530
0
       function,
2531
0
       attribute_index );
2532
2533
0
      return( -1 );
2534
0
    }
2535
0
    result = libfsxfs_attribute_values_compare_name_with_utf16_string(
2536
0
              safe_attribute_values,
2537
0
              utf16_string,
2538
0
              utf16_string_length,
2539
0
              error );
2540
2541
0
    if( result == -1 )
2542
0
    {
2543
0
      libcerror_error_set(
2544
0
       error,
2545
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2546
0
       LIBCERROR_RUNTIME_ERROR_GENERIC,
2547
0
       "%s: unable to compare UTF-16 string with name of attribute: %d values.",
2548
0
       function,
2549
0
       attribute_index );
2550
2551
0
      return( -1 );
2552
0
    }
2553
0
    else if( result == LIBUNA_COMPARE_EQUAL )
2554
0
    {
2555
0
      *attribute_values = safe_attribute_values;
2556
2557
0
      return( 1 );
2558
0
    }
2559
0
  }
2560
0
  return( 0 );
2561
0
}
2562
2563
/* Determines if there is an extended attribute for an UTF-8 encoded name
2564
 * Returns 1 if available, 0 if not or -1 on error
2565
 */
2566
int libfsxfs_file_entry_has_extended_attribute_by_utf8_name(
2567
     libfsxfs_file_entry_t *file_entry,
2568
     const uint8_t *utf8_string,
2569
     size_t utf8_string_length,
2570
     libcerror_error_t **error )
2571
0
{
2572
0
  libfsxfs_attribute_values_t *attribute_values       = NULL;
2573
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
2574
0
  static char *function                               = "libfsxfs_file_entry_has_extended_attribute_by_utf8_name";
2575
0
  int result                                          = 0;
2576
2577
0
  if( file_entry == NULL )
2578
0
  {
2579
0
    libcerror_error_set(
2580
0
     error,
2581
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2582
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2583
0
     "%s: invalid file entry.",
2584
0
     function );
2585
2586
0
    return( -1 );
2587
0
  }
2588
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
2589
2590
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2591
0
  if( libcthreads_read_write_lock_grab_for_write(
2592
0
       internal_file_entry->read_write_lock,
2593
0
       error ) != 1 )
2594
0
  {
2595
0
    libcerror_error_set(
2596
0
     error,
2597
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2598
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2599
0
     "%s: unable to grab read/write lock for writing.",
2600
0
     function );
2601
2602
0
    return( -1 );
2603
0
  }
2604
0
#endif
2605
0
  result = libfsxfs_internal_file_entry_get_attribute_values_by_utf8_name(
2606
0
            internal_file_entry,
2607
0
            utf8_string,
2608
0
            utf8_string_length,
2609
0
            &attribute_values,
2610
0
            error );
2611
2612
0
  if( result == -1 )
2613
0
  {
2614
0
    libcerror_error_set(
2615
0
     error,
2616
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2617
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2618
0
     "%s: unable to retrieve attribute values for UTF-8 name.",
2619
0
     function );
2620
2621
0
    result = -1;
2622
0
  }
2623
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2624
0
  if( libcthreads_read_write_lock_release_for_write(
2625
0
       internal_file_entry->read_write_lock,
2626
0
       error ) != 1 )
2627
0
  {
2628
0
    libcerror_error_set(
2629
0
     error,
2630
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2631
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2632
0
     "%s: unable to release read/write lock for writing.",
2633
0
     function );
2634
2635
0
    return( -1 );
2636
0
  }
2637
0
#endif
2638
0
  return( result );
2639
0
}
2640
2641
/* Determines if there is an extended attribute for an UTF-8 encoded name
2642
 * Returns 1 if available, 0 if not or -1 on error
2643
 */
2644
int libfsxfs_file_entry_has_extended_attribute_by_utf16_name(
2645
     libfsxfs_file_entry_t *file_entry,
2646
     const uint16_t *utf16_string,
2647
     size_t utf16_string_length,
2648
     libcerror_error_t **error )
2649
0
{
2650
0
  libfsxfs_attribute_values_t *attribute_values       = NULL;
2651
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
2652
0
  static char *function                               = "libfsxfs_file_entry_has_extended_attribute_by_utf16_name";
2653
0
  int result                                          = 0;
2654
2655
0
  if( file_entry == NULL )
2656
0
  {
2657
0
    libcerror_error_set(
2658
0
     error,
2659
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2660
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2661
0
     "%s: invalid file entry.",
2662
0
     function );
2663
2664
0
    return( -1 );
2665
0
  }
2666
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
2667
2668
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2669
0
  if( libcthreads_read_write_lock_grab_for_write(
2670
0
       internal_file_entry->read_write_lock,
2671
0
       error ) != 1 )
2672
0
  {
2673
0
    libcerror_error_set(
2674
0
     error,
2675
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2676
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2677
0
     "%s: unable to grab read/write lock for writing.",
2678
0
     function );
2679
2680
0
    return( -1 );
2681
0
  }
2682
0
#endif
2683
0
  result = libfsxfs_internal_file_entry_get_attribute_values_by_utf16_name(
2684
0
            internal_file_entry,
2685
0
            utf16_string,
2686
0
            utf16_string_length,
2687
0
            &attribute_values,
2688
0
            error );
2689
2690
0
  if( result == -1 )
2691
0
  {
2692
0
    libcerror_error_set(
2693
0
     error,
2694
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2695
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2696
0
     "%s: unable to retrieve attribute values for UTF-16 name.",
2697
0
     function );
2698
2699
0
    result = -1;
2700
0
  }
2701
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2702
0
  if( libcthreads_read_write_lock_release_for_write(
2703
0
       internal_file_entry->read_write_lock,
2704
0
       error ) != 1 )
2705
0
  {
2706
0
    libcerror_error_set(
2707
0
     error,
2708
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2709
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2710
0
     "%s: unable to release read/write lock for writing.",
2711
0
     function );
2712
2713
0
    return( -1 );
2714
0
  }
2715
0
#endif
2716
0
  return( result );
2717
0
}
2718
2719
/* Retrieves the extended attribute for an UTF-8 encoded name
2720
 * Returns 1 if successful, 0 if no such file entry or -1 on error
2721
 */
2722
int libfsxfs_file_entry_get_extended_attribute_by_utf8_name(
2723
     libfsxfs_file_entry_t *file_entry,
2724
     const uint8_t *utf8_string,
2725
     size_t utf8_string_length,
2726
     libfsxfs_extended_attribute_t **extended_attribute,
2727
     libcerror_error_t **error )
2728
0
{
2729
0
  libfsxfs_attribute_values_t *attribute_values       = NULL;
2730
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
2731
0
  static char *function                               = "libfsxfs_file_entry_get_extended_attribute_by_utf8_name";
2732
0
  int result                                          = 0;
2733
2734
0
  if( file_entry == NULL )
2735
0
  {
2736
0
    libcerror_error_set(
2737
0
     error,
2738
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2739
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2740
0
     "%s: invalid file entry.",
2741
0
     function );
2742
2743
0
    return( -1 );
2744
0
  }
2745
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
2746
2747
0
  if( extended_attribute == NULL )
2748
0
  {
2749
0
    libcerror_error_set(
2750
0
     error,
2751
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2752
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2753
0
     "%s: invalid extended attribute.",
2754
0
     function );
2755
2756
0
    return( -1 );
2757
0
  }
2758
0
  if( *extended_attribute != NULL )
2759
0
  {
2760
0
    libcerror_error_set(
2761
0
     error,
2762
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2763
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2764
0
     "%s: invalid extended attribute value already set.",
2765
0
     function );
2766
2767
0
    return( -1 );
2768
0
  }
2769
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2770
0
  if( libcthreads_read_write_lock_grab_for_write(
2771
0
       internal_file_entry->read_write_lock,
2772
0
       error ) != 1 )
2773
0
  {
2774
0
    libcerror_error_set(
2775
0
     error,
2776
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2777
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2778
0
     "%s: unable to grab read/write lock for writing.",
2779
0
     function );
2780
2781
0
    return( -1 );
2782
0
  }
2783
0
#endif
2784
0
  result = libfsxfs_internal_file_entry_get_attribute_values_by_utf8_name(
2785
0
            internal_file_entry,
2786
0
            utf8_string,
2787
0
            utf8_string_length,
2788
0
            &attribute_values,
2789
0
            error );
2790
2791
0
  if( result == -1 )
2792
0
  {
2793
0
    libcerror_error_set(
2794
0
     error,
2795
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2796
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2797
0
     "%s: unable to retrieve attribute values for UTF-8 name.",
2798
0
     function );
2799
2800
0
    result = -1;
2801
0
  }
2802
0
  else if( result != 0 )
2803
0
  {
2804
0
    if( libfsxfs_extended_attribute_initialize(
2805
0
         extended_attribute,
2806
0
         internal_file_entry->io_handle,
2807
0
         internal_file_entry->file_io_handle,
2808
0
         internal_file_entry->file_system,
2809
0
         internal_file_entry->inode,
2810
0
         attribute_values,
2811
0
         error ) != 1 )
2812
0
    {
2813
0
      libcerror_error_set(
2814
0
       error,
2815
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2816
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2817
0
       "%s: unable to create extended attribute.",
2818
0
       function );
2819
2820
0
      result = -1;
2821
0
    }
2822
0
  }
2823
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2824
0
  if( libcthreads_read_write_lock_release_for_write(
2825
0
       internal_file_entry->read_write_lock,
2826
0
       error ) != 1 )
2827
0
  {
2828
0
    libcerror_error_set(
2829
0
     error,
2830
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2831
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2832
0
     "%s: unable to release read/write lock for writing.",
2833
0
     function );
2834
2835
0
    return( -1 );
2836
0
  }
2837
0
#endif
2838
0
  return( result );
2839
0
}
2840
2841
/* Retrieves the extended attribute for an UTF-16 encoded name
2842
 * Returns 1 if successful, 0 if no such file entry or -1 on error
2843
 */
2844
int libfsxfs_file_entry_get_extended_attribute_by_utf16_name(
2845
     libfsxfs_file_entry_t *file_entry,
2846
     const uint16_t *utf16_string,
2847
     size_t utf16_string_length,
2848
     libfsxfs_extended_attribute_t **extended_attribute,
2849
     libcerror_error_t **error )
2850
0
{
2851
0
  libfsxfs_attribute_values_t *attribute_values       = NULL;
2852
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
2853
0
  static char *function                               = "libfsxfs_file_entry_get_extended_attribute_by_utf16_name";
2854
0
  int result                                          = 0;
2855
2856
0
  if( file_entry == NULL )
2857
0
  {
2858
0
    libcerror_error_set(
2859
0
     error,
2860
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2861
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2862
0
     "%s: invalid file entry.",
2863
0
     function );
2864
2865
0
    return( -1 );
2866
0
  }
2867
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
2868
2869
0
  if( extended_attribute == NULL )
2870
0
  {
2871
0
    libcerror_error_set(
2872
0
     error,
2873
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2874
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2875
0
     "%s: invalid extended attribute.",
2876
0
     function );
2877
2878
0
    return( -1 );
2879
0
  }
2880
0
  if( *extended_attribute != NULL )
2881
0
  {
2882
0
    libcerror_error_set(
2883
0
     error,
2884
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2885
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2886
0
     "%s: invalid extended attribute value already set.",
2887
0
     function );
2888
2889
0
    return( -1 );
2890
0
  }
2891
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2892
0
  if( libcthreads_read_write_lock_grab_for_write(
2893
0
       internal_file_entry->read_write_lock,
2894
0
       error ) != 1 )
2895
0
  {
2896
0
    libcerror_error_set(
2897
0
     error,
2898
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2899
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2900
0
     "%s: unable to grab read/write lock for writing.",
2901
0
     function );
2902
2903
0
    return( -1 );
2904
0
  }
2905
0
#endif
2906
0
  result = libfsxfs_internal_file_entry_get_attribute_values_by_utf16_name(
2907
0
            internal_file_entry,
2908
0
            utf16_string,
2909
0
            utf16_string_length,
2910
0
            &attribute_values,
2911
0
            error );
2912
2913
0
  if( result == -1 )
2914
0
  {
2915
0
    libcerror_error_set(
2916
0
     error,
2917
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2918
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2919
0
     "%s: unable to retrieve attribute values for UTF-16 name.",
2920
0
     function );
2921
2922
0
    result = -1;
2923
0
  }
2924
0
  else if( result != 0 )
2925
0
  {
2926
0
    if( libfsxfs_extended_attribute_initialize(
2927
0
         extended_attribute,
2928
0
         internal_file_entry->io_handle,
2929
0
         internal_file_entry->file_io_handle,
2930
0
         internal_file_entry->file_system,
2931
0
         internal_file_entry->inode,
2932
0
         attribute_values,
2933
0
         error ) != 1 )
2934
0
    {
2935
0
      libcerror_error_set(
2936
0
       error,
2937
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2938
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2939
0
       "%s: unable to create extended attribute.",
2940
0
       function );
2941
2942
0
      result = -1;
2943
0
    }
2944
0
  }
2945
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
2946
0
  if( libcthreads_read_write_lock_release_for_write(
2947
0
       internal_file_entry->read_write_lock,
2948
0
       error ) != 1 )
2949
0
  {
2950
0
    libcerror_error_set(
2951
0
     error,
2952
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2953
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2954
0
     "%s: unable to release read/write lock for writing.",
2955
0
     function );
2956
2957
0
    return( -1 );
2958
0
  }
2959
0
#endif
2960
0
  return( result );
2961
0
}
2962
2963
/* Retrieves the number of sub file entries
2964
 * Returns 1 if successful or -1 on error
2965
 */
2966
int libfsxfs_file_entry_get_number_of_sub_file_entries(
2967
     libfsxfs_file_entry_t *file_entry,
2968
     int *number_of_sub_file_entries,
2969
     libcerror_error_t **error )
2970
1.17k
{
2971
1.17k
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
2972
1.17k
  static char *function                               = "libfsxfs_file_entry_get_number_of_sub_file_entries";
2973
1.17k
  int result                                          = 1;
2974
2975
1.17k
  if( file_entry == NULL )
2976
0
  {
2977
0
    libcerror_error_set(
2978
0
     error,
2979
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2980
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2981
0
     "%s: invalid file entry.",
2982
0
     function );
2983
2984
0
    return( -1 );
2985
0
  }
2986
1.17k
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
2987
2988
1.17k
  if( number_of_sub_file_entries == NULL )
2989
0
  {
2990
0
    libcerror_error_set(
2991
0
     error,
2992
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2993
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2994
0
     "%s: invalid number of sub file entries.",
2995
0
     function );
2996
2997
0
    return( -1 );
2998
0
  }
2999
1.17k
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3000
1.17k
  if( libcthreads_read_write_lock_grab_for_write(
3001
1.17k
       internal_file_entry->read_write_lock,
3002
1.17k
       error ) != 1 )
3003
0
  {
3004
0
    libcerror_error_set(
3005
0
     error,
3006
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3007
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3008
0
     "%s: unable to grab read/write lock for writing.",
3009
0
     function );
3010
3011
0
    return( -1 );
3012
0
  }
3013
1.17k
#endif
3014
1.17k
  if( internal_file_entry->directory == NULL )
3015
1.17k
  {
3016
1.17k
    if( libfsxfs_internal_file_entry_get_directory(
3017
1.17k
         internal_file_entry,
3018
1.17k
         error ) != 1 )
3019
429
    {
3020
429
      libcerror_error_set(
3021
429
       error,
3022
429
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3023
429
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3024
429
       "%s: unable to retrieve directory for inode: %" PRIu32 ".",
3025
429
       function,
3026
429
       internal_file_entry->inode_number );
3027
3028
429
      result = -1;
3029
429
    }
3030
1.17k
  }
3031
1.17k
  if( internal_file_entry->directory != NULL )
3032
705
  {
3033
705
    if( libfsxfs_directory_get_number_of_entries(
3034
705
         internal_file_entry->directory,
3035
705
         number_of_sub_file_entries,
3036
705
         error ) != 1 )
3037
0
    {
3038
0
      libcerror_error_set(
3039
0
       error,
3040
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3041
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3042
0
       "%s: unable to retrieve number of sub directory entries.",
3043
0
       function );
3044
3045
0
      result = -1;
3046
0
    }
3047
705
  }
3048
1.17k
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3049
1.17k
  if( libcthreads_read_write_lock_release_for_write(
3050
1.17k
       internal_file_entry->read_write_lock,
3051
1.17k
       error ) != 1 )
3052
0
  {
3053
0
    libcerror_error_set(
3054
0
     error,
3055
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3056
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3057
0
     "%s: unable to release read/write lock for writing.",
3058
0
     function );
3059
3060
0
    return( -1 );
3061
0
  }
3062
1.17k
#endif
3063
1.17k
  return( result );
3064
1.17k
}
3065
3066
/* Retrieves the sub file entry for the specific index
3067
 * Returns 1 if successful or -1 on error
3068
 */
3069
int libfsxfs_file_entry_get_sub_file_entry_by_index(
3070
     libfsxfs_file_entry_t *file_entry,
3071
     int sub_file_entry_index,
3072
     libfsxfs_file_entry_t **sub_file_entry,
3073
     libcerror_error_t **error )
3074
656
{
3075
656
  libfsxfs_directory_entry_t *safe_directory_entry    = NULL;
3076
656
  libfsxfs_directory_entry_t *sub_directory_entry     = NULL;
3077
656
  libfsxfs_inode_t *inode                             = NULL;
3078
656
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3079
656
  static char *function                               = "libfsxfs_file_entry_get_sub_file_entry_by_index";
3080
656
  int result                                          = 1;
3081
3082
656
  if( file_entry == NULL )
3083
0
  {
3084
0
    libcerror_error_set(
3085
0
     error,
3086
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3087
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3088
0
     "%s: invalid file entry.",
3089
0
     function );
3090
3091
0
    return( -1 );
3092
0
  }
3093
656
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3094
3095
656
  if( sub_file_entry == NULL )
3096
0
  {
3097
0
    libcerror_error_set(
3098
0
     error,
3099
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3100
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3101
0
     "%s: invalid sub file entry.",
3102
0
     function );
3103
3104
0
    return( -1 );
3105
0
  }
3106
656
  if( *sub_file_entry != NULL )
3107
0
  {
3108
0
    libcerror_error_set(
3109
0
     error,
3110
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3111
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3112
0
     "%s: invalid sub file entry value already set.",
3113
0
     function );
3114
3115
0
    return( -1 );
3116
0
  }
3117
656
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3118
656
  if( libcthreads_read_write_lock_grab_for_write(
3119
656
       internal_file_entry->read_write_lock,
3120
656
       error ) != 1 )
3121
0
  {
3122
0
    libcerror_error_set(
3123
0
     error,
3124
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3125
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3126
0
     "%s: unable to grab read/write lock for writing.",
3127
0
     function );
3128
3129
0
    return( -1 );
3130
0
  }
3131
656
#endif
3132
656
  if( internal_file_entry->directory == NULL )
3133
0
  {
3134
0
    if( libfsxfs_internal_file_entry_get_directory(
3135
0
         internal_file_entry,
3136
0
         error ) != 1 )
3137
0
    {
3138
0
      libcerror_error_set(
3139
0
       error,
3140
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3141
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3142
0
       "%s: unable to retrieve directory for inode: %" PRIu32 ".",
3143
0
       function,
3144
0
       internal_file_entry->inode_number );
3145
3146
0
      result = -1;
3147
0
    }
3148
0
  }
3149
656
  if( result != -1 )
3150
656
  {
3151
656
    if( libfsxfs_directory_get_entry_by_index(
3152
656
         internal_file_entry->directory,
3153
656
         sub_file_entry_index,
3154
656
         &sub_directory_entry,
3155
656
         error ) != 1 )
3156
0
    {
3157
0
      libcerror_error_set(
3158
0
       error,
3159
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3160
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3161
0
       "%s: unable to retrieve sub directory entry: %d.",
3162
0
       function,
3163
0
       sub_file_entry_index );
3164
3165
0
      result = -1;
3166
0
    }
3167
656
    else if( libfsxfs_file_system_get_inode_by_number(
3168
656
              internal_file_entry->file_system,
3169
656
              internal_file_entry->io_handle,
3170
656
              internal_file_entry->file_io_handle,
3171
656
              sub_directory_entry->inode_number,
3172
656
              &inode,
3173
656
              error ) != 1 )
3174
116
    {
3175
116
      libcerror_error_set(
3176
116
       error,
3177
116
       LIBCERROR_ERROR_DOMAIN_IO,
3178
116
       LIBCERROR_IO_ERROR_READ_FAILED,
3179
116
       "%s: unable to retrieve sub directory entry: %d inode: %" PRIu64 "\n",
3180
116
       function,
3181
116
       sub_file_entry_index,
3182
116
       sub_directory_entry->inode_number );
3183
3184
116
      result = -1;
3185
116
    }
3186
540
    else if( libfsxfs_directory_entry_clone(
3187
540
              &safe_directory_entry,
3188
540
              sub_directory_entry,
3189
540
              error ) != 1 )
3190
0
    {
3191
0
      libcerror_error_set(
3192
0
       error,
3193
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3194
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3195
0
       "%s: unable to clone sub directory entry: %d.",
3196
0
       function,
3197
0
       sub_file_entry_index );
3198
3199
0
      libfsxfs_inode_free(
3200
0
       &inode,
3201
0
       NULL );
3202
3203
0
      result = -1;
3204
0
    }
3205
    /* libfsxfs_file_entry_initialize takes over management of sub_directory_entry
3206
     */
3207
540
    else if( libfsxfs_file_entry_initialize(
3208
540
              sub_file_entry,
3209
540
              internal_file_entry->io_handle,
3210
540
              internal_file_entry->file_io_handle,
3211
540
              internal_file_entry->file_system,
3212
540
              sub_directory_entry->inode_number,
3213
540
              inode,
3214
540
              safe_directory_entry,
3215
540
              error ) != 1 )
3216
133
    {
3217
133
      libcerror_error_set(
3218
133
       error,
3219
133
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3220
133
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3221
133
       "%s: unable to create file entry.",
3222
133
       function );
3223
3224
133
      libfsxfs_inode_free(
3225
133
       &inode,
3226
133
       NULL );
3227
3228
133
      libfsxfs_directory_entry_free(
3229
133
       &safe_directory_entry,
3230
133
       NULL );
3231
3232
133
      result = -1;
3233
133
    }
3234
656
  }
3235
656
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3236
656
  if( libcthreads_read_write_lock_release_for_write(
3237
656
       internal_file_entry->read_write_lock,
3238
656
       error ) != 1 )
3239
0
  {
3240
0
    libcerror_error_set(
3241
0
     error,
3242
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3243
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3244
0
     "%s: unable to release read/write lock for writing.",
3245
0
     function );
3246
3247
0
    return( -1 );
3248
0
  }
3249
656
#endif
3250
656
  return( result );
3251
656
}
3252
3253
/* Retrieves the sub file entry for an UTF-8 encoded name
3254
 * Returns 1 if successful, 0 if no such file entry or -1 on error
3255
 */
3256
int libfsxfs_file_entry_get_sub_file_entry_by_utf8_name(
3257
     libfsxfs_file_entry_t *file_entry,
3258
     const uint8_t *utf8_string,
3259
     size_t utf8_string_length,
3260
     libfsxfs_file_entry_t **sub_file_entry,
3261
     libcerror_error_t **error )
3262
0
{
3263
0
  libfsxfs_directory_entry_t *directory_entry         = NULL;
3264
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3265
0
  static char *function                               = "libfsxfs_file_entry_get_sub_file_entry_by_utf8_name";
3266
0
  int result                                          = 1;
3267
3268
0
  if( file_entry == NULL )
3269
0
  {
3270
0
    libcerror_error_set(
3271
0
     error,
3272
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3273
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3274
0
     "%s: invalid file entry.",
3275
0
     function );
3276
3277
0
    return( -1 );
3278
0
  }
3279
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3280
3281
0
  if( sub_file_entry == NULL )
3282
0
  {
3283
0
    libcerror_error_set(
3284
0
     error,
3285
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3286
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3287
0
     "%s: invalid sub file entry.",
3288
0
     function );
3289
3290
0
    return( -1 );
3291
0
  }
3292
0
  if( *sub_file_entry != NULL )
3293
0
  {
3294
0
    libcerror_error_set(
3295
0
     error,
3296
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3297
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3298
0
     "%s: invalid sub file entry value already set.",
3299
0
     function );
3300
3301
0
    return( -1 );
3302
0
  }
3303
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3304
0
  if( libcthreads_read_write_lock_grab_for_write(
3305
0
       internal_file_entry->read_write_lock,
3306
0
       error ) != 1 )
3307
0
  {
3308
0
    libcerror_error_set(
3309
0
     error,
3310
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3311
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3312
0
     "%s: unable to grab read/write lock for writing.",
3313
0
     function );
3314
3315
0
    return( -1 );
3316
0
  }
3317
0
#endif
3318
0
  if( internal_file_entry->directory == NULL )
3319
0
  {
3320
0
    if( libfsxfs_internal_file_entry_get_directory(
3321
0
         internal_file_entry,
3322
0
         error ) != 1 )
3323
0
    {
3324
0
      libcerror_error_set(
3325
0
       error,
3326
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3327
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3328
0
       "%s: unable to retrieve directory for inode: %" PRIu32 ".",
3329
0
       function,
3330
0
       internal_file_entry->inode_number );
3331
3332
0
      result = -1;
3333
0
    }
3334
0
  }
3335
0
  if( internal_file_entry->directory != NULL )
3336
0
  {
3337
0
    result = libfsxfs_directory_get_entry_by_utf8_name(
3338
0
              internal_file_entry->directory,
3339
0
              utf8_string,
3340
0
              utf8_string_length,
3341
0
              &directory_entry,
3342
0
              error );
3343
3344
0
    if( result == -1 )
3345
0
    {
3346
0
      libcerror_error_set(
3347
0
       error,
3348
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3349
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3350
0
       "%s: unable to retrieve directory entry by UTF-8 name.",
3351
0
       function );
3352
3353
0
      result = -1;
3354
0
    }
3355
0
    else if( result != 0 )
3356
0
    {
3357
      /* TODO */
3358
0
      result = -1;
3359
0
    }
3360
0
  }
3361
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3362
0
  if( libcthreads_read_write_lock_release_for_write(
3363
0
       internal_file_entry->read_write_lock,
3364
0
       error ) != 1 )
3365
0
  {
3366
0
    libcerror_error_set(
3367
0
     error,
3368
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3369
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3370
0
     "%s: unable to release read/write lock for writing.",
3371
0
     function );
3372
3373
0
    return( -1 );
3374
0
  }
3375
0
#endif
3376
0
  return( result );
3377
0
}
3378
3379
/* Retrieves the sub file entry for an UTF-16 encoded name
3380
 * Returns 1 if successful, 0 if no such file entry or -1 on error
3381
 */
3382
int libfsxfs_file_entry_get_sub_file_entry_by_utf16_name(
3383
     libfsxfs_file_entry_t *file_entry,
3384
     const uint16_t *utf16_string,
3385
     size_t utf16_string_length,
3386
     libfsxfs_file_entry_t **sub_file_entry,
3387
     libcerror_error_t **error )
3388
0
{
3389
0
  libfsxfs_directory_entry_t *directory_entry         = NULL;
3390
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3391
0
  static char *function                               = "libfsxfs_file_entry_get_sub_file_entry_by_utf16_name";
3392
0
  int result                                          = 1;
3393
3394
0
  if( file_entry == NULL )
3395
0
  {
3396
0
    libcerror_error_set(
3397
0
     error,
3398
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3399
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3400
0
     "%s: invalid file entry.",
3401
0
     function );
3402
3403
0
    return( -1 );
3404
0
  }
3405
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3406
3407
0
  if( sub_file_entry == NULL )
3408
0
  {
3409
0
    libcerror_error_set(
3410
0
     error,
3411
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3412
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3413
0
     "%s: invalid sub file entry.",
3414
0
     function );
3415
3416
0
    return( -1 );
3417
0
  }
3418
0
  if( *sub_file_entry != NULL )
3419
0
  {
3420
0
    libcerror_error_set(
3421
0
     error,
3422
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3423
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3424
0
     "%s: invalid sub file entry value already set.",
3425
0
     function );
3426
3427
0
    return( -1 );
3428
0
  }
3429
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3430
0
  if( libcthreads_read_write_lock_grab_for_write(
3431
0
       internal_file_entry->read_write_lock,
3432
0
       error ) != 1 )
3433
0
  {
3434
0
    libcerror_error_set(
3435
0
     error,
3436
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3437
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3438
0
     "%s: unable to grab read/write lock for writing.",
3439
0
     function );
3440
3441
0
    return( -1 );
3442
0
  }
3443
0
#endif
3444
0
  if( internal_file_entry->directory == NULL )
3445
0
  {
3446
0
    if( libfsxfs_internal_file_entry_get_directory(
3447
0
         internal_file_entry,
3448
0
         error ) != 1 )
3449
0
    {
3450
0
      libcerror_error_set(
3451
0
       error,
3452
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3453
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3454
0
       "%s: unable to retrieve directory for inode: %" PRIu32 ".",
3455
0
       function,
3456
0
       internal_file_entry->inode_number );
3457
3458
0
      result = -1;
3459
0
    }
3460
0
  }
3461
0
  if( internal_file_entry->directory != NULL )
3462
0
  {
3463
0
    result = libfsxfs_directory_get_entry_by_utf16_name(
3464
0
              internal_file_entry->directory,
3465
0
              utf16_string,
3466
0
              utf16_string_length,
3467
0
              &directory_entry,
3468
0
              error );
3469
3470
0
    if( result == -1 )
3471
0
    {
3472
0
      libcerror_error_set(
3473
0
       error,
3474
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3475
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3476
0
       "%s: unable to retrieve directory entry by UTF-16 name.",
3477
0
       function );
3478
3479
0
      result = -1;
3480
0
    }
3481
0
    else if( result != 0 )
3482
0
    {
3483
      /* TODO */
3484
0
      result = -1;
3485
0
    }
3486
0
  }
3487
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3488
0
  if( libcthreads_read_write_lock_release_for_write(
3489
0
       internal_file_entry->read_write_lock,
3490
0
       error ) != 1 )
3491
0
  {
3492
0
    libcerror_error_set(
3493
0
     error,
3494
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3495
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3496
0
     "%s: unable to release read/write lock for writing.",
3497
0
     function );
3498
3499
0
    return( -1 );
3500
0
  }
3501
0
#endif
3502
0
  return( result );
3503
0
}
3504
3505
/* Reads data at the current offset
3506
 * Returns the number of bytes read or -1 on error
3507
 */
3508
ssize_t libfsxfs_file_entry_read_buffer(
3509
         libfsxfs_file_entry_t *file_entry,
3510
         void *buffer,
3511
         size_t buffer_size,
3512
         libcerror_error_t **error )
3513
0
{
3514
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3515
0
  static char *function                               = "libfsxfs_file_entry_read_buffer";
3516
0
  ssize_t read_count                                  = 0;
3517
3518
0
  if( file_entry == NULL )
3519
0
  {
3520
0
    libcerror_error_set(
3521
0
     error,
3522
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3523
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3524
0
     "%s: invalid file entry.",
3525
0
     function );
3526
3527
0
    return( -1 );
3528
0
  }
3529
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3530
3531
0
  if( internal_file_entry->inode == NULL )
3532
0
  {
3533
0
    libcerror_error_set(
3534
0
     error,
3535
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3536
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3537
0
     "%s: invalid file entry - missing inode.",
3538
0
     function );
3539
3540
0
    return( -1 );
3541
0
  }
3542
0
  if( ( internal_file_entry->inode->file_mode & 0xf000 ) != LIBFSXFS_FILE_TYPE_REGULAR_FILE )
3543
0
  {
3544
0
    libcerror_error_set(
3545
0
     error,
3546
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3547
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3548
0
     "%s: invalid file entry - invalid inode - unsupported file mode not a regular file.",
3549
0
     function );
3550
3551
0
    return( -1 );
3552
0
  }
3553
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3554
0
  if( libcthreads_read_write_lock_grab_for_write(
3555
0
       internal_file_entry->read_write_lock,
3556
0
       error ) != 1 )
3557
0
  {
3558
0
    libcerror_error_set(
3559
0
     error,
3560
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3561
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3562
0
     "%s: unable to grab read/write lock for writing.",
3563
0
     function );
3564
3565
0
    return( -1 );
3566
0
  }
3567
0
#endif
3568
0
  read_count = libfdata_stream_read_buffer(
3569
0
                internal_file_entry->data_stream,
3570
0
                (intptr_t *) internal_file_entry->file_io_handle,
3571
0
                buffer,
3572
0
                buffer_size,
3573
0
                0,
3574
0
                error );
3575
3576
0
  if( read_count < 0 )
3577
0
  {
3578
0
    libcerror_error_set(
3579
0
     error,
3580
0
     LIBCERROR_ERROR_DOMAIN_IO,
3581
0
     LIBCERROR_IO_ERROR_READ_FAILED,
3582
0
     "%s: unable to read from data stream.",
3583
0
     function );
3584
3585
0
    read_count = -1;
3586
0
  }
3587
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3588
0
  if( libcthreads_read_write_lock_release_for_write(
3589
0
       internal_file_entry->read_write_lock,
3590
0
       error ) != 1 )
3591
0
  {
3592
0
    libcerror_error_set(
3593
0
     error,
3594
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3595
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3596
0
     "%s: unable to release read/write lock for writing.",
3597
0
     function );
3598
3599
0
    return( -1 );
3600
0
  }
3601
0
#endif
3602
0
  return( read_count );
3603
0
}
3604
3605
/* Reads data at a specific offset
3606
 * Returns the number of bytes read or -1 on error
3607
 */
3608
ssize_t libfsxfs_file_entry_read_buffer_at_offset(
3609
         libfsxfs_file_entry_t *file_entry,
3610
         void *buffer,
3611
         size_t buffer_size,
3612
         off64_t offset,
3613
         libcerror_error_t **error )
3614
0
{
3615
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3616
0
  static char *function                               = "libfsxfs_file_entry_read_buffer_at_offset";
3617
0
  ssize_t read_count                                  = 0;
3618
3619
0
  if( file_entry == NULL )
3620
0
  {
3621
0
    libcerror_error_set(
3622
0
     error,
3623
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3624
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3625
0
     "%s: invalid file entry.",
3626
0
     function );
3627
3628
0
    return( -1 );
3629
0
  }
3630
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3631
3632
0
  if( internal_file_entry->inode == NULL )
3633
0
  {
3634
0
    libcerror_error_set(
3635
0
     error,
3636
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3637
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3638
0
     "%s: invalid file entry - missing inode.",
3639
0
     function );
3640
3641
0
    return( -1 );
3642
0
  }
3643
0
  if( ( internal_file_entry->inode->file_mode & 0xf000 ) != LIBFSXFS_FILE_TYPE_REGULAR_FILE )
3644
0
  {
3645
0
    libcerror_error_set(
3646
0
     error,
3647
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3648
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3649
0
     "%s: invalid file entry - invalid inode - unsupported file mode not a regular file.",
3650
0
     function );
3651
3652
0
    return( -1 );
3653
0
  }
3654
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3655
0
  if( libcthreads_read_write_lock_grab_for_write(
3656
0
       internal_file_entry->read_write_lock,
3657
0
       error ) != 1 )
3658
0
  {
3659
0
    libcerror_error_set(
3660
0
     error,
3661
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3662
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3663
0
     "%s: unable to grab read/write lock for writing.",
3664
0
     function );
3665
3666
0
    return( -1 );
3667
0
  }
3668
0
#endif
3669
0
  read_count = libfdata_stream_read_buffer_at_offset(
3670
0
                internal_file_entry->data_stream,
3671
0
                (intptr_t *) internal_file_entry->file_io_handle,
3672
0
                buffer,
3673
0
                buffer_size,
3674
0
                offset,
3675
0
                0,
3676
0
                error );
3677
3678
0
  if( read_count < 0 )
3679
0
  {
3680
0
    libcerror_error_set(
3681
0
     error,
3682
0
     LIBCERROR_ERROR_DOMAIN_IO,
3683
0
     LIBCERROR_IO_ERROR_READ_FAILED,
3684
0
     "%s: unable to read from data stream.",
3685
0
     function );
3686
3687
0
    read_count = -1;
3688
0
  }
3689
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3690
0
  if( libcthreads_read_write_lock_release_for_write(
3691
0
       internal_file_entry->read_write_lock,
3692
0
       error ) != 1 )
3693
0
  {
3694
0
    libcerror_error_set(
3695
0
     error,
3696
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3697
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3698
0
     "%s: unable to release read/write lock for writing.",
3699
0
     function );
3700
3701
0
    return( -1 );
3702
0
  }
3703
0
#endif
3704
0
  return( read_count );
3705
0
}
3706
3707
/* Seeks a certain offset in the data
3708
 * Returns the offset if seek is successful or -1 on error
3709
 */
3710
off64_t libfsxfs_file_entry_seek_offset(
3711
         libfsxfs_file_entry_t *file_entry,
3712
         off64_t offset,
3713
         int whence,
3714
         libcerror_error_t **error )
3715
0
{
3716
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3717
0
  static char *function                                = "libfsxfs_file_entry_seek_offset";
3718
3719
0
  if( file_entry == NULL )
3720
0
  {
3721
0
    libcerror_error_set(
3722
0
     error,
3723
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3724
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3725
0
     "%s: invalid file entry.",
3726
0
     function );
3727
3728
0
    return( -1 );
3729
0
  }
3730
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3731
3732
0
  if( internal_file_entry->inode == NULL )
3733
0
  {
3734
0
    libcerror_error_set(
3735
0
     error,
3736
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3737
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3738
0
     "%s: invalid file entry - missing inode.",
3739
0
     function );
3740
3741
0
    return( -1 );
3742
0
  }
3743
0
  if( ( internal_file_entry->inode->file_mode & 0xf000 ) != LIBFSXFS_FILE_TYPE_REGULAR_FILE )
3744
0
  {
3745
0
    libcerror_error_set(
3746
0
     error,
3747
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3748
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3749
0
     "%s: invalid file entry - invalid inode - unsupported file mode not a regular file.",
3750
0
     function );
3751
3752
0
    return( -1 );
3753
0
  }
3754
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3755
0
  if( libcthreads_read_write_lock_grab_for_write(
3756
0
       internal_file_entry->read_write_lock,
3757
0
       error ) != 1 )
3758
0
  {
3759
0
    libcerror_error_set(
3760
0
     error,
3761
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3762
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3763
0
     "%s: unable to grab read/write lock for writing.",
3764
0
     function );
3765
3766
0
    return( -1 );
3767
0
  }
3768
0
#endif
3769
0
  offset = libfdata_stream_seek_offset(
3770
0
            internal_file_entry->data_stream,
3771
0
            offset,
3772
0
            whence,
3773
0
            error );
3774
3775
0
  if( offset == -1 )
3776
0
  {
3777
0
    libcerror_error_set(
3778
0
     error,
3779
0
     LIBCERROR_ERROR_DOMAIN_IO,
3780
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
3781
0
     "%s: unable to seek offset in data stream.",
3782
0
     function );
3783
3784
0
    offset = -1;
3785
0
  }
3786
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3787
0
  if( libcthreads_read_write_lock_release_for_write(
3788
0
       internal_file_entry->read_write_lock,
3789
0
       error ) != 1 )
3790
0
  {
3791
0
    libcerror_error_set(
3792
0
     error,
3793
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3794
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3795
0
     "%s: unable to release read/write lock for writing.",
3796
0
     function );
3797
3798
0
    return( -1 );
3799
0
  }
3800
0
#endif
3801
0
  return( offset );
3802
0
}
3803
3804
/* Retrieves the current offset of the data
3805
 * Returns the offset if successful or -1 on error
3806
 */
3807
int libfsxfs_file_entry_get_offset(
3808
     libfsxfs_file_entry_t *file_entry,
3809
     off64_t *offset,
3810
     libcerror_error_t **error )
3811
407
{
3812
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3813
407
  static char *function                               = "libfsxfs_file_entry_get_offset";
3814
407
  int result                                          = 1;
3815
3816
407
  if( file_entry == NULL )
3817
0
  {
3818
0
    libcerror_error_set(
3819
0
     error,
3820
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3821
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3822
0
     "%s: invalid file entry.",
3823
0
     function );
3824
3825
0
    return( -1 );
3826
0
  }
3827
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3828
3829
407
  if( internal_file_entry->inode == NULL )
3830
0
  {
3831
0
    libcerror_error_set(
3832
0
     error,
3833
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3834
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3835
0
     "%s: invalid file entry - missing inode.",
3836
0
     function );
3837
3838
0
    return( -1 );
3839
0
  }
3840
407
  if( ( internal_file_entry->inode->file_mode & 0xf000 ) != LIBFSXFS_FILE_TYPE_REGULAR_FILE )
3841
401
  {
3842
401
    libcerror_error_set(
3843
401
     error,
3844
401
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3845
401
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3846
401
     "%s: invalid file entry - invalid inode - unsupported file mode not a regular file.",
3847
401
     function );
3848
3849
401
    return( -1 );
3850
401
  }
3851
6
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3852
6
  if( libcthreads_read_write_lock_grab_for_read(
3853
6
       internal_file_entry->read_write_lock,
3854
6
       error ) != 1 )
3855
0
  {
3856
0
    libcerror_error_set(
3857
0
     error,
3858
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3859
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3860
0
     "%s: unable to grab read/write lock for reading.",
3861
0
     function );
3862
3863
0
    return( -1 );
3864
0
  }
3865
6
#endif
3866
6
  if( libfdata_stream_get_offset(
3867
6
       internal_file_entry->data_stream,
3868
6
       offset,
3869
6
       error ) != 1 )
3870
0
  {
3871
0
    libcerror_error_set(
3872
0
     error,
3873
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3874
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3875
0
     "%s: unable to retrieve offset from data stream.",
3876
0
     function );
3877
3878
0
    result = -1;
3879
0
  }
3880
6
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3881
6
  if( libcthreads_read_write_lock_release_for_read(
3882
6
       internal_file_entry->read_write_lock,
3883
6
       error ) != 1 )
3884
0
  {
3885
0
    libcerror_error_set(
3886
0
     error,
3887
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3888
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3889
0
     "%s: unable to release read/write lock for reading.",
3890
0
     function );
3891
3892
0
    return( -1 );
3893
0
  }
3894
6
#endif
3895
6
  return( result );
3896
6
}
3897
3898
/* Retrieves the size of the data
3899
 * Returns 1 if successful or -1 on error
3900
 */
3901
int libfsxfs_file_entry_get_size(
3902
     libfsxfs_file_entry_t *file_entry,
3903
     size64_t *size,
3904
     libcerror_error_t **error )
3905
407
{
3906
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3907
407
  static char *function                               = "libfsxfs_file_entry_get_size";
3908
3909
407
  if( file_entry == NULL )
3910
0
  {
3911
0
    libcerror_error_set(
3912
0
     error,
3913
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3914
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3915
0
     "%s: invalid file entry.",
3916
0
     function );
3917
3918
0
    return( -1 );
3919
0
  }
3920
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3921
3922
407
  if( size == NULL )
3923
0
  {
3924
0
    libcerror_error_set(
3925
0
     error,
3926
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3927
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3928
0
     "%s: invalid size.",
3929
0
     function );
3930
3931
0
    return( -1 );
3932
0
  }
3933
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3934
407
  if( libcthreads_read_write_lock_grab_for_read(
3935
407
       internal_file_entry->read_write_lock,
3936
407
       error ) != 1 )
3937
0
  {
3938
0
    libcerror_error_set(
3939
0
     error,
3940
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3941
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3942
0
     "%s: unable to grab read/write lock for reading.",
3943
0
     function );
3944
3945
0
    return( -1 );
3946
0
  }
3947
407
#endif
3948
407
  *size = internal_file_entry->data_size;
3949
3950
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3951
407
  if( libcthreads_read_write_lock_release_for_read(
3952
407
       internal_file_entry->read_write_lock,
3953
407
       error ) != 1 )
3954
0
  {
3955
0
    libcerror_error_set(
3956
0
     error,
3957
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3958
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3959
0
     "%s: unable to release read/write lock for reading.",
3960
0
     function );
3961
3962
0
    return( -1 );
3963
0
  }
3964
407
#endif
3965
407
  return( 1 );
3966
407
}
3967
3968
/* Retrieves the number of extents of the data
3969
 * Returns 1 if successful or -1 on error
3970
 */
3971
int libfsxfs_file_entry_get_number_of_extents(
3972
     libfsxfs_file_entry_t *file_entry,
3973
     int *number_of_extents,
3974
     libcerror_error_t **error )
3975
407
{
3976
407
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
3977
407
  static char *function                               = "libfsxfs_file_entry_get_number_of_extents";
3978
407
  int result                                           = 1;
3979
3980
407
  if( file_entry == NULL )
3981
0
  {
3982
0
    libcerror_error_set(
3983
0
     error,
3984
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3985
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3986
0
     "%s: invalid file entry.",
3987
0
     function );
3988
3989
0
    return( -1 );
3990
0
  }
3991
407
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
3992
3993
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
3994
407
  if( libcthreads_read_write_lock_grab_for_read(
3995
407
       internal_file_entry->read_write_lock,
3996
407
       error ) != 1 )
3997
0
  {
3998
0
    libcerror_error_set(
3999
0
     error,
4000
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4001
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4002
0
     "%s: unable to grab read/write lock for reading.",
4003
0
     function );
4004
4005
0
    return( -1 );
4006
0
  }
4007
407
#endif
4008
407
  if( libfsxfs_inode_get_number_of_data_extents(
4009
407
       internal_file_entry->inode,
4010
407
       number_of_extents,
4011
407
       error ) != 1 )
4012
134
  {
4013
134
    libcerror_error_set(
4014
134
     error,
4015
134
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4016
134
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4017
134
     "%s: unable to retrieve number of data extents from inode.",
4018
134
     function );
4019
4020
134
    result = -1;
4021
134
  }
4022
407
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
4023
407
  if( libcthreads_read_write_lock_release_for_read(
4024
407
       internal_file_entry->read_write_lock,
4025
407
       error ) != 1 )
4026
0
  {
4027
0
    libcerror_error_set(
4028
0
     error,
4029
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4030
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4031
0
     "%s: unable to release read/write lock for reading.",
4032
0
     function );
4033
4034
0
    return( -1 );
4035
0
  }
4036
407
#endif
4037
407
  return( result );
4038
407
}
4039
4040
/* Retrieves a specific extent of the data
4041
 * Returns 1 if successful or -1 on error
4042
 */
4043
int libfsxfs_file_entry_get_extent_by_index(
4044
     libfsxfs_file_entry_t *file_entry,
4045
     int extent_index,
4046
     off64_t *extent_offset,
4047
     size64_t *extent_size,
4048
     uint32_t *extent_flags,
4049
     libcerror_error_t **error )
4050
0
{
4051
0
  libfsxfs_extent_t *extent                           = NULL;
4052
0
  libfsxfs_internal_file_entry_t *internal_file_entry = NULL;
4053
0
  static char *function                               = "libfsxfs_file_entry_get_extent_by_index";
4054
0
  int result                                          = 1;
4055
4056
0
  if( file_entry == NULL )
4057
0
  {
4058
0
    libcerror_error_set(
4059
0
     error,
4060
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4061
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4062
0
     "%s: invalid file entry.",
4063
0
     function );
4064
4065
0
    return( -1 );
4066
0
  }
4067
0
  internal_file_entry = (libfsxfs_internal_file_entry_t *) file_entry;
4068
4069
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
4070
0
  if( libcthreads_read_write_lock_grab_for_read(
4071
0
       internal_file_entry->read_write_lock,
4072
0
       error ) != 1 )
4073
0
  {
4074
0
    libcerror_error_set(
4075
0
     error,
4076
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4077
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4078
0
     "%s: unable to grab read/write lock for reading.",
4079
0
     function );
4080
4081
0
    return( -1 );
4082
0
  }
4083
0
#endif
4084
0
  if( libfsxfs_inode_get_data_extent_by_index(
4085
0
       internal_file_entry->inode,
4086
0
       extent_index,
4087
0
       &extent,
4088
0
       error ) != 1 )
4089
0
  {
4090
0
    libcerror_error_set(
4091
0
     error,
4092
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4093
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4094
0
     "%s: unable to retrieve data extent: %d from inode.",
4095
0
     function,
4096
0
     extent_index );
4097
4098
0
    result = -1;
4099
0
  }
4100
0
  if( result == 1 )
4101
0
  {
4102
0
    if( libfsxfs_extent_get_values(
4103
0
         extent,
4104
0
         internal_file_entry->io_handle,
4105
0
         extent_offset,
4106
0
         extent_size,
4107
0
         extent_flags,
4108
0
         error ) != 1 )
4109
0
    {
4110
0
      libcerror_error_set(
4111
0
       error,
4112
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4113
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4114
0
       "%s: unable to retrieve extent: %d values.",
4115
0
       function,
4116
0
       extent_index );
4117
4118
0
      result = -1;
4119
0
    }
4120
0
  }
4121
0
#if defined( HAVE_LIBFSXFS_MULTI_THREAD_SUPPORT )
4122
0
  if( libcthreads_read_write_lock_release_for_read(
4123
0
       internal_file_entry->read_write_lock,
4124
0
       error ) != 1 )
4125
0
  {
4126
0
    libcerror_error_set(
4127
0
     error,
4128
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4129
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4130
0
     "%s: unable to release read/write lock for reading.",
4131
0
     function );
4132
4133
0
    return( -1 );
4134
0
  }
4135
0
#endif
4136
0
  return( result );
4137
0
}
4138