Coverage Report

Created: 2024-02-25 07:20

/src/libfsext/libfsext/libfsext_file_entry.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * File entry functions
3
 *
4
 * Copyright (C) 2010-2024, 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 "libfsext_attribute_values.h"
27
#include "libfsext_attributes_block.h"
28
#include "libfsext_block_stream.h"
29
#include "libfsext_definitions.h"
30
#include "libfsext_directory.h"
31
#include "libfsext_directory_entry.h"
32
#include "libfsext_extended_attribute.h"
33
#include "libfsext_file_entry.h"
34
#include "libfsext_inode.h"
35
#include "libfsext_inode_table.h"
36
#include "libfsext_libbfio.h"
37
#include "libfsext_libcerror.h"
38
#include "libfsext_libcnotify.h"
39
#include "libfsext_libcthreads.h"
40
#include "libfsext_libuna.h"
41
#include "libfsext_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 libfsext_file_entry_initialize(
48
     libfsext_file_entry_t **file_entry,
49
     libfsext_io_handle_t *io_handle,
50
     libbfio_handle_t *file_io_handle,
51
     libfsext_inode_table_t *inode_table,
52
     uint32_t inode_number,
53
     libfsext_inode_t *inode,
54
     libfsext_directory_entry_t *directory_entry,
55
     libcerror_error_t **error )
56
1.93k
{
57
1.93k
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
58
1.93k
  static char *function                               = "libfsext_file_entry_initialize";
59
60
1.93k
  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.93k
  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.93k
  if( io_handle == 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 IO handle.",
89
0
     function );
90
91
0
    return( -1 );
92
0
  }
93
1.93k
  if( inode_table == NULL )
94
0
  {
95
0
    libcerror_error_set(
96
0
     error,
97
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
98
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
99
0
     "%s: invalid inode table.",
100
0
     function );
101
102
0
    return( -1 );
103
0
  }
104
1.93k
  if( inode == NULL )
105
0
  {
106
0
    libcerror_error_set(
107
0
     error,
108
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
109
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
110
0
     "%s: invalid inode.",
111
0
     function );
112
113
0
    return( -1 );
114
0
  }
115
1.93k
  internal_file_entry = memory_allocate_structure(
116
1.93k
                         libfsext_internal_file_entry_t );
117
118
1.93k
  if( internal_file_entry == NULL )
119
0
  {
120
0
    libcerror_error_set(
121
0
     error,
122
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
123
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
124
0
     "%s: unable to create file entry.",
125
0
     function );
126
127
0
    goto on_error;
128
0
  }
129
1.93k
  if( memory_set(
130
1.93k
       internal_file_entry,
131
1.93k
       0,
132
1.93k
       sizeof( libfsext_internal_file_entry_t ) ) == NULL )
133
0
  {
134
0
    libcerror_error_set(
135
0
     error,
136
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
137
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
138
0
     "%s: unable to clear file entry.",
139
0
     function );
140
141
0
    memory_free(
142
0
     internal_file_entry );
143
144
0
    return( -1 );
145
0
  }
146
1.93k
  if( ( ( inode->file_mode & 0xf000 ) == LIBFSEXT_FILE_TYPE_REGULAR_FILE )
147
1.93k
   || ( ( inode->file_mode & 0xf000 ) == LIBFSEXT_FILE_TYPE_SYMBOLIC_LINK ) )
148
665
  {
149
665
    if( libfsext_inode_get_data_size(
150
665
         inode,
151
665
         (uint64_t *) &( internal_file_entry->data_size ),
152
665
         error ) != 1 )
153
0
    {
154
0
      libcerror_error_set(
155
0
       error,
156
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
157
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
158
0
       "%s: unable to retrieve data size from inode.",
159
0
       function );
160
161
0
      goto on_error;
162
0
    }
163
665
    if( ( ( inode->file_mode & 0xf000 ) == LIBFSEXT_FILE_TYPE_REGULAR_FILE )
164
665
     || ( internal_file_entry->data_size >= 60 ) )
165
605
    {
166
605
      if( libfsext_block_stream_initialize(
167
605
           &( internal_file_entry->data_block_stream ),
168
605
           io_handle,
169
605
           inode,
170
605
           internal_file_entry->data_size,
171
605
           error ) != 1 )
172
82
      {
173
82
        libcerror_error_set(
174
82
         error,
175
82
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
176
82
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
177
82
         "%s: unable to create data block stream.",
178
82
         function );
179
180
82
        goto on_error;
181
82
      }
182
605
    }
183
665
  }
184
1.85k
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
185
1.85k
  if( libcthreads_read_write_lock_initialize(
186
1.85k
       &( internal_file_entry->read_write_lock ),
187
1.85k
       error ) != 1 )
188
0
  {
189
0
    libcerror_error_set(
190
0
     error,
191
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
192
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
193
0
     "%s: unable to initialize read/write lock.",
194
0
     function );
195
196
0
    goto on_error;
197
0
  }
198
1.85k
#endif
199
1.85k
  internal_file_entry->io_handle       = io_handle;
200
1.85k
  internal_file_entry->file_io_handle  = file_io_handle;
201
1.85k
  internal_file_entry->inode_table     = inode_table;
202
1.85k
  internal_file_entry->inode_number    = inode_number;
203
1.85k
  internal_file_entry->inode           = inode;
204
1.85k
  internal_file_entry->directory_entry = directory_entry;
205
206
1.85k
  *file_entry = (libfsext_file_entry_t *) internal_file_entry;
207
208
1.85k
  return( 1 );
209
210
82
on_error:
211
82
  if( internal_file_entry != NULL )
212
82
  {
213
82
    if( internal_file_entry->data_block_stream != NULL )
214
0
    {
215
0
      libfdata_stream_free(
216
0
       &( internal_file_entry->data_block_stream ),
217
0
       NULL );
218
0
    }
219
82
    memory_free(
220
82
     internal_file_entry );
221
82
  }
222
82
  return( -1 );
223
1.85k
}
224
225
/* Frees a file entry
226
 * Returns 1 if successful or -1 on error
227
 */
228
int libfsext_file_entry_free(
229
     libfsext_file_entry_t **file_entry,
230
     libcerror_error_t **error )
231
2.16k
{
232
2.16k
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
233
2.16k
  static char *function                               = "libfsext_file_entry_free";
234
2.16k
  int result                                          = 1;
235
236
2.16k
  if( file_entry == NULL )
237
0
  {
238
0
    libcerror_error_set(
239
0
     error,
240
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
241
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
242
0
     "%s: invalid file entry.",
243
0
     function );
244
245
0
    return( -1 );
246
0
  }
247
2.16k
  if( *file_entry != NULL )
248
1.85k
  {
249
1.85k
    internal_file_entry = (libfsext_internal_file_entry_t *) *file_entry;
250
1.85k
    *file_entry         = NULL;
251
252
1.85k
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
253
1.85k
    if( libcthreads_read_write_lock_free(
254
1.85k
         &( internal_file_entry->read_write_lock ),
255
1.85k
         error ) != 1 )
256
0
    {
257
0
      libcerror_error_set(
258
0
       error,
259
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
260
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
261
0
       "%s: unable to free read/write lock.",
262
0
       function );
263
264
0
      result = -1;
265
0
    }
266
1.85k
#endif
267
    /* The file_io_handle and io_handle references are freed elsewhere
268
     */
269
1.85k
    if( internal_file_entry->inode != NULL )
270
1.85k
    {
271
1.85k
      if( libfsext_inode_free(
272
1.85k
           &( internal_file_entry->inode ),
273
1.85k
           error ) != 1 )
274
0
      {
275
0
        libcerror_error_set(
276
0
         error,
277
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
278
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
279
0
         "%s: unable to free inode.",
280
0
         function );
281
282
0
        result = -1;
283
0
      }
284
1.85k
    }
285
1.85k
    if( internal_file_entry->directory_entry != NULL )
286
711
    {
287
711
      if( libfsext_directory_entry_free(
288
711
           &( internal_file_entry->directory_entry ),
289
711
           error ) != 1 )
290
0
      {
291
0
        libcerror_error_set(
292
0
         error,
293
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
294
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
295
0
         "%s: unable to free directory entry.",
296
0
         function );
297
298
0
        result = -1;
299
0
      }
300
711
    }
301
1.85k
    if( internal_file_entry->extended_attributes_array != NULL )
302
20
    {
303
20
      if( libcdata_array_free(
304
20
           &( internal_file_entry->extended_attributes_array ),
305
20
           (int (*)(intptr_t **, libcerror_error_t **)) &libfsext_attribute_values_free,
306
20
           error ) != 1 )
307
0
      {
308
0
        libcerror_error_set(
309
0
         error,
310
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
311
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
312
0
         "%s: unable to free extended attributes array.",
313
0
         function );
314
315
0
        result = -1;
316
0
      }
317
20
    }
318
1.85k
    if( internal_file_entry->directory != NULL )
319
765
    {
320
765
      if( libfsext_directory_free(
321
765
           &( internal_file_entry->directory ),
322
765
           error ) != 1 )
323
0
      {
324
0
        libcerror_error_set(
325
0
         error,
326
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
327
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
328
0
         "%s: unable to free directory.",
329
0
         function );
330
331
0
        result = -1;
332
0
      }
333
765
    }
334
1.85k
    if( internal_file_entry->data_block_stream != NULL )
335
523
    {
336
523
      if( libfdata_stream_free(
337
523
           &( internal_file_entry->data_block_stream ),
338
523
           error ) != 1 )
339
0
      {
340
0
        libcerror_error_set(
341
0
         error,
342
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
343
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
344
0
         "%s: unable to free data block stream.",
345
0
         function );
346
347
0
        result = -1;
348
0
      }
349
523
    }
350
1.85k
    if( internal_file_entry->symbolic_link_data != NULL )
351
163
    {
352
163
      memory_free(
353
163
       internal_file_entry->symbolic_link_data );
354
163
    }
355
1.85k
    memory_free(
356
1.85k
     internal_file_entry );
357
1.85k
  }
358
2.16k
  return( result );
359
2.16k
}
360
361
/* Determines the directory
362
 * Returns 1 if successful or -1 on error
363
 */
364
int libfsext_internal_file_entry_get_directory(
365
     libfsext_internal_file_entry_t *internal_file_entry,
366
     libcerror_error_t **error )
367
1.14k
{
368
1.14k
  static char *function = "libfsext_internal_file_entry_get_directory";
369
370
1.14k
  if( internal_file_entry == NULL )
371
0
  {
372
0
    libcerror_error_set(
373
0
     error,
374
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
375
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
376
0
     "%s: invalid file entry.",
377
0
     function );
378
379
0
    return( -1 );
380
0
  }
381
1.14k
  if( internal_file_entry->inode == NULL )
382
0
  {
383
0
    libcerror_error_set(
384
0
     error,
385
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
386
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
387
0
     "%s: invalid file entry - missing inode.",
388
0
     function );
389
390
0
    return( -1 );
391
0
  }
392
1.14k
  if( internal_file_entry->directory != NULL )
393
0
  {
394
0
    libcerror_error_set(
395
0
     error,
396
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
397
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
398
0
     "%s: invalid file entry - directory value already set.",
399
0
     function );
400
401
0
    return( -1 );
402
0
  }
403
1.14k
  if( ( internal_file_entry->inode->file_mode & 0xf000 ) == LIBFSEXT_FILE_TYPE_DIRECTORY )
404
1.01k
  {
405
1.01k
    if( libfsext_directory_initialize(
406
1.01k
         &( internal_file_entry->directory ),
407
1.01k
         error ) != 1 )
408
0
    {
409
0
      libcerror_error_set(
410
0
       error,
411
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
412
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
413
0
       "%s: unable to create directory.",
414
0
       function );
415
416
0
      goto on_error;
417
0
    }
418
1.01k
    if( libfsext_directory_read_file_io_handle(
419
1.01k
         internal_file_entry->directory,
420
1.01k
         internal_file_entry->io_handle,
421
1.01k
         internal_file_entry->file_io_handle,
422
1.01k
         internal_file_entry->inode,
423
1.01k
         error ) != 1 )
424
253
    {
425
253
      libcerror_error_set(
426
253
       error,
427
253
       LIBCERROR_ERROR_DOMAIN_IO,
428
253
       LIBCERROR_IO_ERROR_READ_FAILED,
429
253
       "%s: unable to read directory for inode: %" PRIu64 ".",
430
253
       function,
431
253
       internal_file_entry->inode_number );
432
433
253
      goto on_error;
434
253
    }
435
1.01k
  }
436
891
  return( 1 );
437
438
253
on_error:
439
253
  if( internal_file_entry->directory != NULL )
440
253
  {
441
253
    libfsext_directory_free(
442
253
     &( internal_file_entry->directory ),
443
253
     NULL );
444
253
  }
445
253
  return( -1 );
446
1.14k
}
447
448
/* Determines the symbolic link data
449
 * Returns 1 if successful or -1 on error
450
 */
451
int libfsext_internal_file_entry_get_symbolic_link_data(
452
     libfsext_internal_file_entry_t *internal_file_entry,
453
     libcerror_error_t **error )
454
711
{
455
711
  static char *function = "libfsext_internal_file_entry_get_symbolic_link_data";
456
711
  ssize_t read_count    = 0;
457
711
  uint64_t data_size    = 0;
458
711
  uint16_t file_mode    = 0;
459
460
711
  if( internal_file_entry == NULL )
461
0
  {
462
0
    libcerror_error_set(
463
0
     error,
464
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
465
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
466
0
     "%s: invalid file entry.",
467
0
     function );
468
469
0
    return( -1 );
470
0
  }
471
711
  if( internal_file_entry->inode == NULL )
472
0
  {
473
0
    libcerror_error_set(
474
0
     error,
475
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
476
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
477
0
     "%s: invalid file entry - missing inode.",
478
0
     function );
479
480
0
    return( -1 );
481
0
  }
482
711
  if( internal_file_entry->symbolic_link_data != NULL )
483
0
  {
484
0
    libcerror_error_set(
485
0
     error,
486
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
487
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
488
0
     "%s: invalid file entry - symbolic link data value already set.",
489
0
     function );
490
491
0
    return( -1 );
492
0
  }
493
711
  if( libfsext_inode_get_file_mode(
494
711
       internal_file_entry->inode,
495
711
       &file_mode,
496
711
       error ) != 1 )
497
0
  {
498
0
    libcerror_error_set(
499
0
     error,
500
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
501
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
502
0
     "%s: unable to retrieve file mode from inode.",
503
0
     function );
504
505
0
    goto on_error;
506
0
  }
507
711
  if( ( file_mode & 0xf000 ) == LIBFSEXT_FILE_TYPE_SYMBOLIC_LINK )
508
497
  {
509
497
    if( libfsext_inode_get_data_size(
510
497
         internal_file_entry->inode,
511
497
         &data_size,
512
497
         error ) != 1 )
513
0
    {
514
0
      libcerror_error_set(
515
0
       error,
516
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
517
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
518
0
       "%s: unable to retrieve data size from inode.",
519
0
       function );
520
521
0
      goto on_error;
522
0
    }
523
497
    if( ( data_size == 0 )
524
497
     || ( data_size > (uint64_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
525
42
    {
526
42
      libcerror_error_set(
527
42
       error,
528
42
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
529
42
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
530
42
       "%s: invalid data size value out of bounds.",
531
42
       function );
532
533
42
      goto on_error;
534
42
    }
535
455
    internal_file_entry->symbolic_link_data = (uint8_t *) memory_allocate(
536
455
                                                           sizeof( uint8_t ) * (size_t) data_size );
537
538
455
    if( internal_file_entry->symbolic_link_data == NULL )
539
0
    {
540
0
      libcerror_error_set(
541
0
       error,
542
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
543
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
544
0
       "%s: unable to create symbolic link data.",
545
0
       function );
546
547
0
      goto on_error;
548
0
    }
549
455
    internal_file_entry->symbolic_link_data_size = (size_t) data_size;
550
551
455
    if( data_size < 60 )
552
47
    {
553
47
      if( memory_copy(
554
47
           internal_file_entry->symbolic_link_data,
555
47
           internal_file_entry->inode->data_reference,
556
47
           (size_t) data_size ) == NULL )
557
0
      {
558
0
        libcerror_error_set(
559
0
         error,
560
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
561
0
         LIBCERROR_MEMORY_ERROR_SET_FAILED,
562
0
         "%s: unable to copy data reference data.",
563
0
         function );
564
565
0
        goto on_error;
566
0
      }
567
47
    }
568
408
    else
569
408
    {
570
408
      read_count = libfdata_stream_read_buffer_at_offset(
571
408
                    internal_file_entry->data_block_stream,
572
408
                    (intptr_t *) internal_file_entry->file_io_handle,
573
408
                    internal_file_entry->symbolic_link_data,
574
408
                    (size_t) data_size,
575
408
                    0,
576
408
                    0,
577
408
                    error );
578
579
408
      if( read_count != (ssize_t) data_size )
580
292
      {
581
292
        libcerror_error_set(
582
292
         error,
583
292
         LIBCERROR_ERROR_DOMAIN_IO,
584
292
         LIBCERROR_IO_ERROR_READ_FAILED,
585
292
         "%s: unable to read from data block stream.",
586
292
         function );
587
588
292
        goto on_error;
589
292
      }
590
408
    }
591
#if defined( HAVE_DEBUG_OUTPUT )
592
    if( libcnotify_verbose != 0 )
593
    {
594
      libcnotify_printf(
595
       "%s: symbolic link data:\n",
596
       function );
597
      libcnotify_print_data(
598
       internal_file_entry->symbolic_link_data,
599
       internal_file_entry->symbolic_link_data_size,
600
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
601
    }
602
#endif
603
455
  }
604
377
  return( 1 );
605
606
334
on_error:
607
334
  if( internal_file_entry->symbolic_link_data != NULL )
608
292
  {
609
292
    memory_free(
610
292
     internal_file_entry->symbolic_link_data );
611
612
292
    internal_file_entry->symbolic_link_data = NULL;
613
292
  }
614
334
  internal_file_entry->symbolic_link_data_size = 0;
615
616
334
  return( -1 );
617
711
}
618
619
/* Determines if the file entry is empty
620
 * Returns 1 if empty, 0 if not or -1 on error
621
 */
622
int libfsext_file_entry_is_empty(
623
     libfsext_file_entry_t *file_entry,
624
     libcerror_error_t **error )
625
0
{
626
0
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
627
0
  static char *function                               = "libfsext_file_entry_is_empty";
628
0
  int result                                          = 0;
629
630
0
  if( file_entry == NULL )
631
0
  {
632
0
    libcerror_error_set(
633
0
     error,
634
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
635
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
636
0
     "%s: invalid file entry.",
637
0
     function );
638
639
0
    return( -1 );
640
0
  }
641
0
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
642
643
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
644
0
  if( libcthreads_read_write_lock_grab_for_read(
645
0
       internal_file_entry->read_write_lock,
646
0
       error ) != 1 )
647
0
  {
648
0
    libcerror_error_set(
649
0
     error,
650
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
651
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
652
0
     "%s: unable to grab read/write lock for reading.",
653
0
     function );
654
655
0
    return( -1 );
656
0
  }
657
0
#endif
658
0
  result = libfsext_inode_is_empty(
659
0
            internal_file_entry->inode,
660
0
            error );
661
662
0
  if( result == -1 )
663
0
  {
664
0
    libcerror_error_set(
665
0
     error,
666
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
667
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
668
0
     "%s: unable to determine if inode is empty.",
669
0
     function );
670
671
0
    result = -1;
672
0
  }
673
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
674
0
  if( libcthreads_read_write_lock_release_for_read(
675
0
       internal_file_entry->read_write_lock,
676
0
       error ) != 1 )
677
0
  {
678
0
    libcerror_error_set(
679
0
     error,
680
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
681
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
682
0
     "%s: unable to release read/write lock for reading.",
683
0
     function );
684
685
0
    return( -1 );
686
0
  }
687
0
#endif
688
0
  return( result );
689
0
}
690
691
/* Retrieves the inode number
692
 * Returns 1 if successful or -1 on error
693
 */
694
int libfsext_file_entry_get_inode_number(
695
     libfsext_file_entry_t *file_entry,
696
     uint32_t *inode_number,
697
     libcerror_error_t **error )
698
437
{
699
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
700
437
  static char *function                               = "libfsext_file_entry_get_inode_number";
701
702
437
  if( file_entry == NULL )
703
0
  {
704
0
    libcerror_error_set(
705
0
     error,
706
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
707
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
708
0
     "%s: invalid file entry.",
709
0
     function );
710
711
0
    return( -1 );
712
0
  }
713
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
714
715
437
  if( inode_number == NULL )
716
0
  {
717
0
    libcerror_error_set(
718
0
     error,
719
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
720
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
721
0
     "%s: invalid inode number.",
722
0
     function );
723
724
0
    return( -1 );
725
0
  }
726
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
727
437
  if( libcthreads_read_write_lock_grab_for_read(
728
437
       internal_file_entry->read_write_lock,
729
437
       error ) != 1 )
730
0
  {
731
0
    libcerror_error_set(
732
0
     error,
733
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
734
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
735
0
     "%s: unable to grab read/write lock for reading.",
736
0
     function );
737
738
0
    return( -1 );
739
0
  }
740
437
#endif
741
437
  *inode_number = internal_file_entry->inode_number;
742
743
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
744
437
  if( libcthreads_read_write_lock_release_for_read(
745
437
       internal_file_entry->read_write_lock,
746
437
       error ) != 1 )
747
0
  {
748
0
    libcerror_error_set(
749
0
     error,
750
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
751
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
752
0
     "%s: unable to release read/write lock for reading.",
753
0
     function );
754
755
0
    return( -1 );
756
0
  }
757
437
#endif
758
437
  return( 1 );
759
437
}
760
761
/* Retrieves the access date and time
762
 * The timestamp is a signed 64-bit POSIX date and time value in number of nano seconds
763
 * This value is retrieved from the inode
764
 * Returns 1 if successful or -1 on error
765
 */
766
int libfsext_file_entry_get_access_time(
767
     libfsext_file_entry_t *file_entry,
768
     int64_t *posix_time,
769
     libcerror_error_t **error )
770
437
{
771
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
772
437
  static char *function                               = "libfsext_file_entry_get_access_time";
773
437
  int result                                          = 1;
774
775
437
  if( file_entry == NULL )
776
0
  {
777
0
    libcerror_error_set(
778
0
     error,
779
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
780
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
781
0
     "%s: invalid file entry.",
782
0
     function );
783
784
0
    return( -1 );
785
0
  }
786
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
787
788
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
789
437
  if( libcthreads_read_write_lock_grab_for_read(
790
437
       internal_file_entry->read_write_lock,
791
437
       error ) != 1 )
792
0
  {
793
0
    libcerror_error_set(
794
0
     error,
795
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
796
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
797
0
     "%s: unable to grab read/write lock for reading.",
798
0
     function );
799
800
0
    return( -1 );
801
0
  }
802
437
#endif
803
437
  if( libfsext_inode_get_access_time(
804
437
       internal_file_entry->inode,
805
437
       posix_time,
806
437
       error ) != 1 )
807
0
  {
808
0
    libcerror_error_set(
809
0
     error,
810
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
811
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
812
0
     "%s: unable to retrieve access time from inode.",
813
0
     function );
814
815
0
    result = -1;
816
0
  }
817
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
818
437
  if( libcthreads_read_write_lock_release_for_read(
819
437
       internal_file_entry->read_write_lock,
820
437
       error ) != 1 )
821
0
  {
822
0
    libcerror_error_set(
823
0
     error,
824
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
825
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
826
0
     "%s: unable to release read/write lock for reading.",
827
0
     function );
828
829
0
    return( -1 );
830
0
  }
831
437
#endif
832
437
  return( result );
833
437
}
834
835
/* Retrieves the creation date and time
836
 * The timestamp is a signed 64-bit POSIX date and time value in number of nano seconds
837
 * This value is retrieved from the inode
838
 * Returns 1 if successful, 0 if not available or -1 on error
839
 */
840
int libfsext_file_entry_get_creation_time(
841
     libfsext_file_entry_t *file_entry,
842
     int64_t *posix_time,
843
     libcerror_error_t **error )
844
437
{
845
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
846
437
  static char *function                               = "libfsext_file_entry_get_creation_time";
847
437
  int result                                          = 1;
848
849
437
  if( file_entry == NULL )
850
0
  {
851
0
    libcerror_error_set(
852
0
     error,
853
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
854
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
855
0
     "%s: invalid file entry.",
856
0
     function );
857
858
0
    return( -1 );
859
0
  }
860
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
861
862
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
863
437
  if( libcthreads_read_write_lock_grab_for_read(
864
437
       internal_file_entry->read_write_lock,
865
437
       error ) != 1 )
866
0
  {
867
0
    libcerror_error_set(
868
0
     error,
869
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
870
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
871
0
     "%s: unable to grab read/write lock for reading.",
872
0
     function );
873
874
0
    return( -1 );
875
0
  }
876
437
#endif
877
437
  result = libfsext_inode_get_creation_time(
878
437
            internal_file_entry->inode,
879
437
            posix_time,
880
437
            error );
881
882
437
  if( result == -1 )
883
0
  {
884
0
    libcerror_error_set(
885
0
     error,
886
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
887
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
888
0
     "%s: unable to retrieve creation time from inode.",
889
0
     function );
890
891
0
    result = -1;
892
0
  }
893
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
894
437
  if( libcthreads_read_write_lock_release_for_read(
895
437
       internal_file_entry->read_write_lock,
896
437
       error ) != 1 )
897
0
  {
898
0
    libcerror_error_set(
899
0
     error,
900
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
901
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
902
0
     "%s: unable to release read/write lock for reading.",
903
0
     function );
904
905
0
    return( -1 );
906
0
  }
907
437
#endif
908
437
  return( result );
909
437
}
910
911
/* Retrieves the inode change time date and time
912
 * The timestamp is a signed 64-bit POSIX date and time value in number of nano seconds
913
 * This value is retrieved from the inode
914
 * Returns 1 if successful or -1 on error
915
 */
916
int libfsext_file_entry_get_inode_change_time(
917
     libfsext_file_entry_t *file_entry,
918
     int64_t *posix_time,
919
     libcerror_error_t **error )
920
437
{
921
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
922
437
  static char *function                               = "libfsext_file_entry_get_inode_change_time";
923
437
  int result                                          = 1;
924
925
437
  if( file_entry == NULL )
926
0
  {
927
0
    libcerror_error_set(
928
0
     error,
929
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
930
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
931
0
     "%s: invalid file entry.",
932
0
     function );
933
934
0
    return( -1 );
935
0
  }
936
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
937
938
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
939
437
  if( libcthreads_read_write_lock_grab_for_read(
940
437
       internal_file_entry->read_write_lock,
941
437
       error ) != 1 )
942
0
  {
943
0
    libcerror_error_set(
944
0
     error,
945
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
946
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
947
0
     "%s: unable to grab read/write lock for reading.",
948
0
     function );
949
950
0
    return( -1 );
951
0
  }
952
437
#endif
953
437
  if( libfsext_inode_get_inode_change_time(
954
437
       internal_file_entry->inode,
955
437
       posix_time,
956
437
       error ) != 1 )
957
0
  {
958
0
    libcerror_error_set(
959
0
     error,
960
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
961
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
962
0
     "%s: unable to retrieve inode change time time from inode.",
963
0
     function );
964
965
0
    result = -1;
966
0
  }
967
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
968
437
  if( libcthreads_read_write_lock_release_for_read(
969
437
       internal_file_entry->read_write_lock,
970
437
       error ) != 1 )
971
0
  {
972
0
    libcerror_error_set(
973
0
     error,
974
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
975
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
976
0
     "%s: unable to release read/write lock for reading.",
977
0
     function );
978
979
0
    return( -1 );
980
0
  }
981
437
#endif
982
437
  return( result );
983
437
}
984
985
/* Retrieves the modification date and time
986
 * The timestamp is a signed 64-bit POSIX date and time value in number of nano seconds
987
 * This value is retrieved from the inode
988
 * Returns 1 if successful or -1 on error
989
 */
990
int libfsext_file_entry_get_modification_time(
991
     libfsext_file_entry_t *file_entry,
992
     int64_t *posix_time,
993
     libcerror_error_t **error )
994
437
{
995
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
996
437
  static char *function                               = "libfsext_file_entry_get_modification_time";
997
437
  int result                                          = 1;
998
999
437
  if( file_entry == NULL )
1000
0
  {
1001
0
    libcerror_error_set(
1002
0
     error,
1003
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1004
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1005
0
     "%s: invalid file entry.",
1006
0
     function );
1007
1008
0
    return( -1 );
1009
0
  }
1010
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
1011
1012
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1013
437
  if( libcthreads_read_write_lock_grab_for_read(
1014
437
       internal_file_entry->read_write_lock,
1015
437
       error ) != 1 )
1016
0
  {
1017
0
    libcerror_error_set(
1018
0
     error,
1019
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1020
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1021
0
     "%s: unable to grab read/write lock for reading.",
1022
0
     function );
1023
1024
0
    return( -1 );
1025
0
  }
1026
437
#endif
1027
437
  if( libfsext_inode_get_modification_time(
1028
437
       internal_file_entry->inode,
1029
437
       posix_time,
1030
437
       error ) != 1 )
1031
0
  {
1032
0
    libcerror_error_set(
1033
0
     error,
1034
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1035
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1036
0
     "%s: unable to retrieve modification time from inode.",
1037
0
     function );
1038
1039
0
    result = -1;
1040
0
  }
1041
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1042
437
  if( libcthreads_read_write_lock_release_for_read(
1043
437
       internal_file_entry->read_write_lock,
1044
437
       error ) != 1 )
1045
0
  {
1046
0
    libcerror_error_set(
1047
0
     error,
1048
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1049
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1050
0
     "%s: unable to release read/write lock for reading.",
1051
0
     function );
1052
1053
0
    return( -1 );
1054
0
  }
1055
437
#endif
1056
437
  return( result );
1057
437
}
1058
1059
/* Retrieves the deletion date and time
1060
 * The timestamp is a signed 32-bit POSIX date and time value in number of seconds
1061
 * This value is retrieved from the inode
1062
 * Returns 1 if successful or -1 on error
1063
 */
1064
int libfsext_file_entry_get_deletion_time(
1065
     libfsext_file_entry_t *file_entry,
1066
     int32_t *posix_time,
1067
     libcerror_error_t **error )
1068
437
{
1069
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
1070
437
  static char *function                               = "libfsext_file_entry_get_deletion_time";
1071
437
  int result                                          = 1;
1072
1073
437
  if( file_entry == NULL )
1074
0
  {
1075
0
    libcerror_error_set(
1076
0
     error,
1077
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1078
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1079
0
     "%s: invalid file entry.",
1080
0
     function );
1081
1082
0
    return( -1 );
1083
0
  }
1084
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
1085
1086
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1087
437
  if( libcthreads_read_write_lock_grab_for_read(
1088
437
       internal_file_entry->read_write_lock,
1089
437
       error ) != 1 )
1090
0
  {
1091
0
    libcerror_error_set(
1092
0
     error,
1093
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1094
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1095
0
     "%s: unable to grab read/write lock for reading.",
1096
0
     function );
1097
1098
0
    return( -1 );
1099
0
  }
1100
437
#endif
1101
437
  if( libfsext_inode_get_deletion_time(
1102
437
       internal_file_entry->inode,
1103
437
       posix_time,
1104
437
       error ) != 1 )
1105
0
  {
1106
0
    libcerror_error_set(
1107
0
     error,
1108
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1109
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1110
0
     "%s: unable to retrieve deletion time from inode.",
1111
0
     function );
1112
1113
0
    result = -1;
1114
0
  }
1115
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1116
437
  if( libcthreads_read_write_lock_release_for_read(
1117
437
       internal_file_entry->read_write_lock,
1118
437
       error ) != 1 )
1119
0
  {
1120
0
    libcerror_error_set(
1121
0
     error,
1122
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1123
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1124
0
     "%s: unable to release read/write lock for reading.",
1125
0
     function );
1126
1127
0
    return( -1 );
1128
0
  }
1129
437
#endif
1130
437
  return( result );
1131
437
}
1132
1133
/* Retrieves the file mode
1134
 * This value is retrieved from the inode
1135
 * Returns 1 if successful or -1 on error
1136
 */
1137
int libfsext_file_entry_get_file_mode(
1138
     libfsext_file_entry_t *file_entry,
1139
     uint16_t *file_mode,
1140
     libcerror_error_t **error )
1141
437
{
1142
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
1143
437
  static char *function                               = "libfsext_file_entry_get_file_mode";
1144
437
  int result                                          = 1;
1145
1146
437
  if( file_entry == NULL )
1147
0
  {
1148
0
    libcerror_error_set(
1149
0
     error,
1150
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1151
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1152
0
     "%s: invalid file entry.",
1153
0
     function );
1154
1155
0
    return( -1 );
1156
0
  }
1157
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
1158
1159
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1160
437
  if( libcthreads_read_write_lock_grab_for_read(
1161
437
       internal_file_entry->read_write_lock,
1162
437
       error ) != 1 )
1163
0
  {
1164
0
    libcerror_error_set(
1165
0
     error,
1166
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1167
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1168
0
     "%s: unable to grab read/write lock for reading.",
1169
0
     function );
1170
1171
0
    return( -1 );
1172
0
  }
1173
437
#endif
1174
437
  if( libfsext_inode_get_file_mode(
1175
437
       internal_file_entry->inode,
1176
437
       file_mode,
1177
437
       error ) != 1 )
1178
0
  {
1179
0
    libcerror_error_set(
1180
0
     error,
1181
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1182
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1183
0
     "%s: unable to retrieve file mode from inode.",
1184
0
     function );
1185
1186
0
    result = -1;
1187
0
  }
1188
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1189
437
  if( libcthreads_read_write_lock_release_for_read(
1190
437
       internal_file_entry->read_write_lock,
1191
437
       error ) != 1 )
1192
0
  {
1193
0
    libcerror_error_set(
1194
0
     error,
1195
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1196
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1197
0
     "%s: unable to release read/write lock for reading.",
1198
0
     function );
1199
1200
0
    return( -1 );
1201
0
  }
1202
437
#endif
1203
437
  return( result );
1204
437
}
1205
1206
/* Retrieves the number of links
1207
 * This value is retrieved from the inode
1208
 * Returns 1 if successful or -1 on error
1209
 */
1210
int libfsext_file_entry_get_number_of_links(
1211
     libfsext_file_entry_t *file_entry,
1212
     uint16_t *number_of_links,
1213
     libcerror_error_t **error )
1214
437
{
1215
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
1216
437
  static char *function                               = "libfsext_file_entry_get_number_of_links";
1217
437
  int result                                          = 1;
1218
1219
437
  if( file_entry == NULL )
1220
0
  {
1221
0
    libcerror_error_set(
1222
0
     error,
1223
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1224
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1225
0
     "%s: invalid file entry.",
1226
0
     function );
1227
1228
0
    return( -1 );
1229
0
  }
1230
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
1231
1232
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1233
437
  if( libcthreads_read_write_lock_grab_for_read(
1234
437
       internal_file_entry->read_write_lock,
1235
437
       error ) != 1 )
1236
0
  {
1237
0
    libcerror_error_set(
1238
0
     error,
1239
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1240
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1241
0
     "%s: unable to grab read/write lock for reading.",
1242
0
     function );
1243
1244
0
    return( -1 );
1245
0
  }
1246
437
#endif
1247
437
  if( libfsext_inode_get_number_of_links(
1248
437
       internal_file_entry->inode,
1249
437
       number_of_links,
1250
437
       error ) != 1 )
1251
0
  {
1252
0
    libcerror_error_set(
1253
0
     error,
1254
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1255
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1256
0
     "%s: unable to retrieve number of links from inode.",
1257
0
     function );
1258
1259
0
    result = -1;
1260
0
  }
1261
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1262
437
  if( libcthreads_read_write_lock_release_for_read(
1263
437
       internal_file_entry->read_write_lock,
1264
437
       error ) != 1 )
1265
0
  {
1266
0
    libcerror_error_set(
1267
0
     error,
1268
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1269
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1270
0
     "%s: unable to release read/write lock for reading.",
1271
0
     function );
1272
1273
0
    return( -1 );
1274
0
  }
1275
437
#endif
1276
437
  return( result );
1277
437
}
1278
1279
/* Retrieves the owner identifier
1280
 * This value is retrieved from the inode
1281
 * Returns 1 if successful or -1 on error
1282
 */
1283
int libfsext_file_entry_get_owner_identifier(
1284
     libfsext_file_entry_t *file_entry,
1285
     uint32_t *owner_identifier,
1286
     libcerror_error_t **error )
1287
437
{
1288
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
1289
437
  static char *function                               = "libfsext_file_entry_get_owner_identifier";
1290
437
  int result                                          = 1;
1291
1292
437
  if( file_entry == NULL )
1293
0
  {
1294
0
    libcerror_error_set(
1295
0
     error,
1296
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1297
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1298
0
     "%s: invalid file entry.",
1299
0
     function );
1300
1301
0
    return( -1 );
1302
0
  }
1303
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
1304
1305
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1306
437
  if( libcthreads_read_write_lock_grab_for_read(
1307
437
       internal_file_entry->read_write_lock,
1308
437
       error ) != 1 )
1309
0
  {
1310
0
    libcerror_error_set(
1311
0
     error,
1312
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1313
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1314
0
     "%s: unable to grab read/write lock for reading.",
1315
0
     function );
1316
1317
0
    return( -1 );
1318
0
  }
1319
437
#endif
1320
437
  if( libfsext_inode_get_owner_identifier(
1321
437
       internal_file_entry->inode,
1322
437
       owner_identifier,
1323
437
       error ) != 1 )
1324
0
  {
1325
0
    libcerror_error_set(
1326
0
     error,
1327
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1328
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1329
0
     "%s: unable to retrieve owner identifier from inode.",
1330
0
     function );
1331
1332
0
    result = -1;
1333
0
  }
1334
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1335
437
  if( libcthreads_read_write_lock_release_for_read(
1336
437
       internal_file_entry->read_write_lock,
1337
437
       error ) != 1 )
1338
0
  {
1339
0
    libcerror_error_set(
1340
0
     error,
1341
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1342
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1343
0
     "%s: unable to release read/write lock for reading.",
1344
0
     function );
1345
1346
0
    return( -1 );
1347
0
  }
1348
437
#endif
1349
437
  return( result );
1350
437
}
1351
1352
/* Retrieves the group identifier
1353
 * This value is retrieved from the inode
1354
 * Returns 1 if successful or -1 on error
1355
 */
1356
int libfsext_file_entry_get_group_identifier(
1357
     libfsext_file_entry_t *file_entry,
1358
     uint32_t *group_identifier,
1359
     libcerror_error_t **error )
1360
437
{
1361
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
1362
437
  static char *function                               = "libfsext_file_entry_get_group_identifier";
1363
437
  int result                                          = 1;
1364
1365
437
  if( file_entry == NULL )
1366
0
  {
1367
0
    libcerror_error_set(
1368
0
     error,
1369
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1370
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1371
0
     "%s: invalid file entry.",
1372
0
     function );
1373
1374
0
    return( -1 );
1375
0
  }
1376
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
1377
1378
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1379
437
  if( libcthreads_read_write_lock_grab_for_read(
1380
437
       internal_file_entry->read_write_lock,
1381
437
       error ) != 1 )
1382
0
  {
1383
0
    libcerror_error_set(
1384
0
     error,
1385
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1386
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1387
0
     "%s: unable to grab read/write lock for reading.",
1388
0
     function );
1389
1390
0
    return( -1 );
1391
0
  }
1392
437
#endif
1393
437
  if( libfsext_inode_get_group_identifier(
1394
437
       internal_file_entry->inode,
1395
437
       group_identifier,
1396
437
       error ) != 1 )
1397
0
  {
1398
0
    libcerror_error_set(
1399
0
     error,
1400
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1401
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1402
0
     "%s: unable to retrieve group identifier from inode.",
1403
0
     function );
1404
1405
0
    result = -1;
1406
0
  }
1407
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1408
437
  if( libcthreads_read_write_lock_release_for_read(
1409
437
       internal_file_entry->read_write_lock,
1410
437
       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
437
#endif
1422
437
  return( result );
1423
437
}
1424
1425
/* Retrieves the device identifier
1426
 * This value is retrieved from the inode
1427
 * Returns 1 if successful, 0 if not available or -1 on error
1428
 */
1429
int libfsext_file_entry_get_device_identifier(
1430
     libfsext_file_entry_t *file_entry,
1431
     uint32_t *device_identifier,
1432
     libcerror_error_t **error )
1433
437
{
1434
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
1435
437
  static char *function                               = "libfsext_file_entry_get_device_identifier";
1436
437
  int result                                          = 0;
1437
1438
437
  if( file_entry == NULL )
1439
0
  {
1440
0
    libcerror_error_set(
1441
0
     error,
1442
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1443
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1444
0
     "%s: invalid file entry.",
1445
0
     function );
1446
1447
0
    return( -1 );
1448
0
  }
1449
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
1450
1451
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1452
437
  if( libcthreads_read_write_lock_grab_for_read(
1453
437
       internal_file_entry->read_write_lock,
1454
437
       error ) != 1 )
1455
0
  {
1456
0
    libcerror_error_set(
1457
0
     error,
1458
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1459
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1460
0
     "%s: unable to grab read/write lock for reading.",
1461
0
     function );
1462
1463
0
    return( -1 );
1464
0
  }
1465
437
#endif
1466
437
  result = libfsext_inode_get_device_identifier(
1467
437
            internal_file_entry->inode,
1468
437
            device_identifier,
1469
437
            error );
1470
1471
437
  if( result == -1 )
1472
0
  {
1473
0
    libcerror_error_set(
1474
0
     error,
1475
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1476
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1477
0
     "%s: unable to retrieve device identifier from inode.",
1478
0
     function );
1479
1480
0
    result = -1;
1481
0
  }
1482
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1483
437
  if( libcthreads_read_write_lock_release_for_read(
1484
437
       internal_file_entry->read_write_lock,
1485
437
       error ) != 1 )
1486
0
  {
1487
0
    libcerror_error_set(
1488
0
     error,
1489
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1490
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1491
0
     "%s: unable to release read/write lock for reading.",
1492
0
     function );
1493
1494
0
    return( -1 );
1495
0
  }
1496
437
#endif
1497
437
  return( result );
1498
437
}
1499
1500
/* Retrieves the device number
1501
 * This value is retrieved from the inode
1502
 * Returns 1 if successful, 0 if not available or -1 on error
1503
 */
1504
int libfsext_file_entry_get_device_number(
1505
     libfsext_file_entry_t *file_entry,
1506
     uint8_t *major_device_number,
1507
     uint8_t *minor_device_number,
1508
     libcerror_error_t **error )
1509
437
{
1510
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
1511
437
  static char *function                               = "libfsext_file_entry_get_device_number";
1512
437
  int result                                          = 0;
1513
1514
437
  if( file_entry == NULL )
1515
0
  {
1516
0
    libcerror_error_set(
1517
0
     error,
1518
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1519
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1520
0
     "%s: invalid file entry.",
1521
0
     function );
1522
1523
0
    return( -1 );
1524
0
  }
1525
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
1526
1527
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1528
437
  if( libcthreads_read_write_lock_grab_for_read(
1529
437
       internal_file_entry->read_write_lock,
1530
437
       error ) != 1 )
1531
0
  {
1532
0
    libcerror_error_set(
1533
0
     error,
1534
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1535
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1536
0
     "%s: unable to grab read/write lock for reading.",
1537
0
     function );
1538
1539
0
    return( -1 );
1540
0
  }
1541
437
#endif
1542
437
  result = libfsext_inode_get_device_number(
1543
437
            internal_file_entry->inode,
1544
437
            major_device_number,
1545
437
            minor_device_number,
1546
437
            error );
1547
1548
437
  if( result == -1 )
1549
0
  {
1550
0
    libcerror_error_set(
1551
0
     error,
1552
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1553
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1554
0
     "%s: unable to retrieve device number from inode.",
1555
0
     function );
1556
1557
0
    result = -1;
1558
0
  }
1559
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1560
437
  if( libcthreads_read_write_lock_release_for_read(
1561
437
       internal_file_entry->read_write_lock,
1562
437
       error ) != 1 )
1563
0
  {
1564
0
    libcerror_error_set(
1565
0
     error,
1566
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1567
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1568
0
     "%s: unable to release read/write lock for reading.",
1569
0
     function );
1570
1571
0
    return( -1 );
1572
0
  }
1573
437
#endif
1574
437
  return( result );
1575
437
}
1576
1577
/* Retrieves the size of the UTF-8 encoded name
1578
 * The returned size includes the end of string character
1579
 * This value is retrieved from the directory entry
1580
 * Returns 1 if successful, 0 if not available or -1 on error
1581
 */
1582
int libfsext_file_entry_get_utf8_name_size(
1583
     libfsext_file_entry_t *file_entry,
1584
     size_t *utf8_string_size,
1585
     libcerror_error_t **error )
1586
437
{
1587
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
1588
437
  static char *function                               = "libfsext_file_entry_get_utf8_name_size";
1589
437
  int result                                          = 0;
1590
1591
437
  if( file_entry == NULL )
1592
0
  {
1593
0
    libcerror_error_set(
1594
0
     error,
1595
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1596
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1597
0
     "%s: invalid file entry.",
1598
0
     function );
1599
1600
0
    return( -1 );
1601
0
  }
1602
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
1603
1604
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1605
437
  if( libcthreads_read_write_lock_grab_for_read(
1606
437
       internal_file_entry->read_write_lock,
1607
437
       error ) != 1 )
1608
0
  {
1609
0
    libcerror_error_set(
1610
0
     error,
1611
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1612
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1613
0
     "%s: unable to grab read/write lock for reading.",
1614
0
     function );
1615
1616
0
    return( -1 );
1617
0
  }
1618
437
#endif
1619
437
  if( internal_file_entry->directory_entry != NULL )
1620
437
  {
1621
437
    result = libfsext_directory_entry_get_utf8_name_size(
1622
437
              internal_file_entry->directory_entry,
1623
437
              utf8_string_size,
1624
437
              error );
1625
1626
437
    if( result != 1 )
1627
267
    {
1628
267
      libcerror_error_set(
1629
267
       error,
1630
267
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1631
267
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1632
267
       "%s: unable to retrieve size of UTF-8 name from directory entry.",
1633
267
       function );
1634
1635
267
      result = -1;
1636
267
    }
1637
437
  }
1638
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1639
437
  if( libcthreads_read_write_lock_release_for_read(
1640
437
       internal_file_entry->read_write_lock,
1641
437
       error ) != 1 )
1642
0
  {
1643
0
    libcerror_error_set(
1644
0
     error,
1645
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1646
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1647
0
     "%s: unable to release read/write lock for reading.",
1648
0
     function );
1649
1650
0
    return( -1 );
1651
0
  }
1652
437
#endif
1653
437
  return( result );
1654
437
}
1655
1656
/* Retrieves the UTF-8 encoded name
1657
 * The size should include the end of string character
1658
 * This value is retrieved from the directory entry
1659
 * Returns 1 if successful, 0 if not available or -1 on error
1660
 */
1661
int libfsext_file_entry_get_utf8_name(
1662
     libfsext_file_entry_t *file_entry,
1663
     uint8_t *utf8_string,
1664
     size_t utf8_string_size,
1665
     libcerror_error_t **error )
1666
437
{
1667
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
1668
437
  static char *function                               = "libfsext_file_entry_get_utf8_name";
1669
437
  int result                                          = 0;
1670
1671
437
  if( file_entry == NULL )
1672
0
  {
1673
0
    libcerror_error_set(
1674
0
     error,
1675
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1676
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1677
0
     "%s: invalid file entry.",
1678
0
     function );
1679
1680
0
    return( -1 );
1681
0
  }
1682
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
1683
1684
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1685
437
  if( libcthreads_read_write_lock_grab_for_read(
1686
437
       internal_file_entry->read_write_lock,
1687
437
       error ) != 1 )
1688
0
  {
1689
0
    libcerror_error_set(
1690
0
     error,
1691
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1692
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1693
0
     "%s: unable to grab read/write lock for reading.",
1694
0
     function );
1695
1696
0
    return( -1 );
1697
0
  }
1698
437
#endif
1699
437
  if( internal_file_entry->directory_entry != NULL )
1700
437
  {
1701
437
    result = libfsext_directory_entry_get_utf8_name(
1702
437
              internal_file_entry->directory_entry,
1703
437
              utf8_string,
1704
437
              utf8_string_size,
1705
437
              error );
1706
1707
437
    if( result != 1 )
1708
269
    {
1709
269
      libcerror_error_set(
1710
269
       error,
1711
269
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1712
269
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1713
269
       "%s: unable to retrieve UTF-8 name from directory entry.",
1714
269
       function );
1715
1716
269
      result = -1;
1717
269
    }
1718
437
  }
1719
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1720
437
  if( libcthreads_read_write_lock_release_for_read(
1721
437
       internal_file_entry->read_write_lock,
1722
437
       error ) != 1 )
1723
0
  {
1724
0
    libcerror_error_set(
1725
0
     error,
1726
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1727
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1728
0
     "%s: unable to release read/write lock for reading.",
1729
0
     function );
1730
1731
0
    return( -1 );
1732
0
  }
1733
437
#endif
1734
437
  return( result );
1735
437
}
1736
1737
/* Retrieves the size of the UTF-16 encoded name
1738
 * The returned size includes the end of string character
1739
 * This value is retrieved from the directory entry
1740
 * Returns 1 if successful, 0 if not available or -1 on error
1741
 */
1742
int libfsext_file_entry_get_utf16_name_size(
1743
     libfsext_file_entry_t *file_entry,
1744
     size_t *utf16_string_size,
1745
     libcerror_error_t **error )
1746
0
{
1747
0
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
1748
0
  static char *function                               = "libfsext_file_entry_get_utf16_name_size";
1749
0
  int result                                          = 0;
1750
1751
0
  if( file_entry == NULL )
1752
0
  {
1753
0
    libcerror_error_set(
1754
0
     error,
1755
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1756
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1757
0
     "%s: invalid file entry.",
1758
0
     function );
1759
1760
0
    return( -1 );
1761
0
  }
1762
0
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
1763
1764
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1765
0
  if( libcthreads_read_write_lock_grab_for_read(
1766
0
       internal_file_entry->read_write_lock,
1767
0
       error ) != 1 )
1768
0
  {
1769
0
    libcerror_error_set(
1770
0
     error,
1771
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1772
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1773
0
     "%s: unable to grab read/write lock for reading.",
1774
0
     function );
1775
1776
0
    return( -1 );
1777
0
  }
1778
0
#endif
1779
0
  if( internal_file_entry->directory_entry != NULL )
1780
0
  {
1781
0
    result = libfsext_directory_entry_get_utf16_name_size(
1782
0
              internal_file_entry->directory_entry,
1783
0
              utf16_string_size,
1784
0
              error );
1785
1786
0
    if( result != 1 )
1787
0
    {
1788
0
      libcerror_error_set(
1789
0
       error,
1790
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1791
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1792
0
       "%s: unable to retrieve size of UTF-16 name from directory entry.",
1793
0
       function );
1794
1795
0
      result = -1;
1796
0
    }
1797
0
  }
1798
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1799
0
  if( libcthreads_read_write_lock_release_for_read(
1800
0
       internal_file_entry->read_write_lock,
1801
0
       error ) != 1 )
1802
0
  {
1803
0
    libcerror_error_set(
1804
0
     error,
1805
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1806
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1807
0
     "%s: unable to release read/write lock for reading.",
1808
0
     function );
1809
1810
0
    return( -1 );
1811
0
  }
1812
0
#endif
1813
0
  return( result );
1814
0
}
1815
1816
/* Retrieves the UTF-16 encoded name
1817
 * The size should include the end of string character
1818
 * This value is retrieved from the directory entry
1819
 * Returns 1 if successful, 0 if not available or -1 on error
1820
 */
1821
int libfsext_file_entry_get_utf16_name(
1822
     libfsext_file_entry_t *file_entry,
1823
     uint16_t *utf16_string,
1824
     size_t utf16_string_size,
1825
     libcerror_error_t **error )
1826
0
{
1827
0
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
1828
0
  static char *function                               = "libfsext_file_entry_get_utf16_name";
1829
0
  int result                                          = 0;
1830
1831
0
  if( file_entry == NULL )
1832
0
  {
1833
0
    libcerror_error_set(
1834
0
     error,
1835
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1836
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1837
0
     "%s: invalid file entry.",
1838
0
     function );
1839
1840
0
    return( -1 );
1841
0
  }
1842
0
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
1843
1844
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1845
0
  if( libcthreads_read_write_lock_grab_for_read(
1846
0
       internal_file_entry->read_write_lock,
1847
0
       error ) != 1 )
1848
0
  {
1849
0
    libcerror_error_set(
1850
0
     error,
1851
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1852
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1853
0
     "%s: unable to grab read/write lock for reading.",
1854
0
     function );
1855
1856
0
    return( -1 );
1857
0
  }
1858
0
#endif
1859
0
  if( internal_file_entry->directory_entry != NULL )
1860
0
  {
1861
0
    result = libfsext_directory_entry_get_utf16_name(
1862
0
              internal_file_entry->directory_entry,
1863
0
              utf16_string,
1864
0
              utf16_string_size,
1865
0
              error );
1866
1867
0
    if( result != 1 )
1868
0
    {
1869
0
      libcerror_error_set(
1870
0
       error,
1871
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1872
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1873
0
       "%s: unable to retrieve UTF-16 name from directory entry.",
1874
0
       function );
1875
1876
0
      result = -1;
1877
0
    }
1878
0
  }
1879
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1880
0
  if( libcthreads_read_write_lock_release_for_read(
1881
0
       internal_file_entry->read_write_lock,
1882
0
       error ) != 1 )
1883
0
  {
1884
0
    libcerror_error_set(
1885
0
     error,
1886
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1887
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1888
0
     "%s: unable to release read/write lock for reading.",
1889
0
     function );
1890
1891
0
    return( -1 );
1892
0
  }
1893
0
#endif
1894
0
  return( result );
1895
0
}
1896
1897
/* Retrieves the size of the UTF-8 encoded symbolic link target
1898
 * The size should include the end of string character
1899
 * Returns 1 if successful, 0 if not available or -1 on error
1900
 */
1901
int libfsext_file_entry_get_utf8_symbolic_link_target_size(
1902
     libfsext_file_entry_t *file_entry,
1903
     size_t *utf8_string_size,
1904
     libcerror_error_t **error )
1905
437
{
1906
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
1907
437
  static char *function                               = "libfsext_file_entry_get_utf8_symbolic_link_target_size";
1908
437
  int result                                          = 0;
1909
1910
437
  if( file_entry == NULL )
1911
0
  {
1912
0
    libcerror_error_set(
1913
0
     error,
1914
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1915
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1916
0
     "%s: invalid file entry.",
1917
0
     function );
1918
1919
0
    return( -1 );
1920
0
  }
1921
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
1922
1923
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1924
437
  if( libcthreads_read_write_lock_grab_for_write(
1925
437
       internal_file_entry->read_write_lock,
1926
437
       error ) != 1 )
1927
0
  {
1928
0
    libcerror_error_set(
1929
0
     error,
1930
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1931
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1932
0
     "%s: unable to grab read/write lock for writing.",
1933
0
     function );
1934
1935
0
    return( -1 );
1936
0
  }
1937
437
#endif
1938
437
  if( internal_file_entry->symbolic_link_data == NULL )
1939
437
  {
1940
437
    if( libfsext_internal_file_entry_get_symbolic_link_data(
1941
437
         internal_file_entry,
1942
437
         error ) != 1 )
1943
167
    {
1944
167
      libcerror_error_set(
1945
167
       error,
1946
167
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1947
167
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1948
167
       "%s: unable to determine symbolic link data.",
1949
167
       function );
1950
1951
167
      result = -1;
1952
167
    }
1953
437
  }
1954
437
  if( internal_file_entry->symbolic_link_data != NULL )
1955
163
  {
1956
163
    result = libuna_utf8_string_size_from_utf8_stream(
1957
163
              internal_file_entry->symbolic_link_data,
1958
163
              internal_file_entry->symbolic_link_data_size,
1959
163
              utf8_string_size,
1960
163
              error );
1961
1962
163
    if( result != 1 )
1963
77
    {
1964
77
      libcerror_error_set(
1965
77
       error,
1966
77
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1967
77
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1968
77
       "%s: unable to retrieve UTF-8 string size.",
1969
77
       function );
1970
1971
77
      result = -1;
1972
77
    }
1973
163
  }
1974
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
1975
437
  if( libcthreads_read_write_lock_release_for_write(
1976
437
       internal_file_entry->read_write_lock,
1977
437
       error ) != 1 )
1978
0
  {
1979
0
    libcerror_error_set(
1980
0
     error,
1981
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1982
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1983
0
     "%s: unable to release read/write lock for writing.",
1984
0
     function );
1985
1986
0
    return( -1 );
1987
0
  }
1988
437
#endif
1989
437
  return( result );
1990
437
}
1991
1992
/* Retrieves the UTF-8 encoded symbolic link target
1993
 * The size should include the end of string character
1994
 * Returns 1 if successful, 0 if not available or -1 on error
1995
 */
1996
int libfsext_file_entry_get_utf8_symbolic_link_target(
1997
     libfsext_file_entry_t *file_entry,
1998
     uint8_t *utf8_string,
1999
     size_t utf8_string_size,
2000
     libcerror_error_t **error )
2001
437
{
2002
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
2003
437
  static char *function                               = "libfsext_file_entry_get_utf8_symbolic_link_target";
2004
437
  int result                                          = 0;
2005
2006
437
  if( file_entry == NULL )
2007
0
  {
2008
0
    libcerror_error_set(
2009
0
     error,
2010
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2011
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2012
0
     "%s: invalid file entry.",
2013
0
     function );
2014
2015
0
    return( -1 );
2016
0
  }
2017
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
2018
2019
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
2020
437
  if( libcthreads_read_write_lock_grab_for_write(
2021
437
       internal_file_entry->read_write_lock,
2022
437
       error ) != 1 )
2023
0
  {
2024
0
    libcerror_error_set(
2025
0
     error,
2026
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2027
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2028
0
     "%s: unable to grab read/write lock for writing.",
2029
0
     function );
2030
2031
0
    return( -1 );
2032
0
  }
2033
437
#endif
2034
437
  if( internal_file_entry->symbolic_link_data == NULL )
2035
274
  {
2036
274
    if( libfsext_internal_file_entry_get_symbolic_link_data(
2037
274
         internal_file_entry,
2038
274
         error ) != 1 )
2039
167
    {
2040
167
      libcerror_error_set(
2041
167
       error,
2042
167
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2043
167
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2044
167
       "%s: unable to determine symbolic link data.",
2045
167
       function );
2046
2047
167
      result = -1;
2048
167
    }
2049
274
  }
2050
437
  if( internal_file_entry->symbolic_link_data != NULL )
2051
163
  {
2052
163
    result = libuna_utf8_string_copy_from_utf8_stream(
2053
163
              utf8_string,
2054
163
              utf8_string_size,
2055
163
              internal_file_entry->symbolic_link_data,
2056
163
              internal_file_entry->symbolic_link_data_size,
2057
163
              error );
2058
2059
163
    if( result != 1 )
2060
84
    {
2061
84
      libcerror_error_set(
2062
84
       error,
2063
84
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2064
84
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2065
84
       "%s: unable to retrieve UTF-8 string.",
2066
84
       function );
2067
2068
84
      result = -1;
2069
84
    }
2070
163
  }
2071
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
2072
437
  if( libcthreads_read_write_lock_release_for_write(
2073
437
       internal_file_entry->read_write_lock,
2074
437
       error ) != 1 )
2075
0
  {
2076
0
    libcerror_error_set(
2077
0
     error,
2078
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2079
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2080
0
     "%s: unable to release read/write lock for writing.",
2081
0
     function );
2082
2083
0
    return( -1 );
2084
0
  }
2085
437
#endif
2086
437
  return( result );
2087
437
}
2088
2089
/* Retrieves the size of the UTF-16 encoded symbolic link target
2090
 * The size should include the end of string character
2091
 * Returns 1 if successful, 0 if not available or -1 on error
2092
 */
2093
int libfsext_file_entry_get_utf16_symbolic_link_target_size(
2094
     libfsext_file_entry_t *file_entry,
2095
     size_t *utf16_string_size,
2096
     libcerror_error_t **error )
2097
0
{
2098
0
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
2099
0
  static char *function                               = "libfsext_file_entry_get_utf16_symbolic_link_target_size";
2100
0
  int result                                          = 0;
2101
2102
0
  if( file_entry == NULL )
2103
0
  {
2104
0
    libcerror_error_set(
2105
0
     error,
2106
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2107
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2108
0
     "%s: invalid file entry.",
2109
0
     function );
2110
2111
0
    return( -1 );
2112
0
  }
2113
0
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
2114
2115
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
2116
0
  if( libcthreads_read_write_lock_grab_for_write(
2117
0
       internal_file_entry->read_write_lock,
2118
0
       error ) != 1 )
2119
0
  {
2120
0
    libcerror_error_set(
2121
0
     error,
2122
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2123
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2124
0
     "%s: unable to grab read/write lock for writing.",
2125
0
     function );
2126
2127
0
    return( -1 );
2128
0
  }
2129
0
#endif
2130
0
  if( internal_file_entry->symbolic_link_data == NULL )
2131
0
  {
2132
0
    if( libfsext_internal_file_entry_get_symbolic_link_data(
2133
0
         internal_file_entry,
2134
0
         error ) != 1 )
2135
0
    {
2136
0
      libcerror_error_set(
2137
0
       error,
2138
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2139
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2140
0
       "%s: unable to determine symbolic link data.",
2141
0
       function );
2142
2143
0
      result = -1;
2144
0
    }
2145
0
  }
2146
0
  if( internal_file_entry->symbolic_link_data != NULL )
2147
0
  {
2148
0
    result = libuna_utf16_string_size_from_utf8_stream(
2149
0
              internal_file_entry->symbolic_link_data,
2150
0
              internal_file_entry->symbolic_link_data_size,
2151
0
              utf16_string_size,
2152
0
              error );
2153
2154
0
    if( result != 1 )
2155
0
    {
2156
0
      libcerror_error_set(
2157
0
       error,
2158
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2159
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2160
0
       "%s: unable to retrieve UTF-16 string size.",
2161
0
       function );
2162
2163
0
      result = -1;
2164
0
    }
2165
0
  }
2166
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
2167
0
  if( libcthreads_read_write_lock_release_for_write(
2168
0
       internal_file_entry->read_write_lock,
2169
0
       error ) != 1 )
2170
0
  {
2171
0
    libcerror_error_set(
2172
0
     error,
2173
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2174
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2175
0
     "%s: unable to release read/write lock for writing.",
2176
0
     function );
2177
2178
0
    return( -1 );
2179
0
  }
2180
0
#endif
2181
0
  return( result );
2182
0
}
2183
2184
/* Retrieves the UTF-16 encoded symbolic link target
2185
 * The size should include the end of string character
2186
 * Returns 1 if successful, 0 if not available or -1 on error
2187
 */
2188
int libfsext_file_entry_get_utf16_symbolic_link_target(
2189
     libfsext_file_entry_t *file_entry,
2190
     uint16_t *utf16_string,
2191
     size_t utf16_string_size,
2192
     libcerror_error_t **error )
2193
0
{
2194
0
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
2195
0
  static char *function                               = "libfsext_file_entry_get_utf16_symbolic_link_target";
2196
0
  int result                                          = 0;
2197
2198
0
  if( file_entry == NULL )
2199
0
  {
2200
0
    libcerror_error_set(
2201
0
     error,
2202
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2203
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2204
0
     "%s: invalid file entry.",
2205
0
     function );
2206
2207
0
    return( -1 );
2208
0
  }
2209
0
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
2210
2211
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
2212
0
  if( libcthreads_read_write_lock_grab_for_write(
2213
0
       internal_file_entry->read_write_lock,
2214
0
       error ) != 1 )
2215
0
  {
2216
0
    libcerror_error_set(
2217
0
     error,
2218
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2219
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2220
0
     "%s: unable to grab read/write lock for writing.",
2221
0
     function );
2222
2223
0
    return( -1 );
2224
0
  }
2225
0
#endif
2226
0
  if( internal_file_entry->symbolic_link_data == NULL )
2227
0
  {
2228
0
    if( libfsext_internal_file_entry_get_symbolic_link_data(
2229
0
         internal_file_entry,
2230
0
         error ) != 1 )
2231
0
    {
2232
0
      libcerror_error_set(
2233
0
       error,
2234
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2235
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2236
0
       "%s: unable to determine symbolic link data.",
2237
0
       function );
2238
2239
0
      result = -1;
2240
0
    }
2241
0
  }
2242
0
  if( internal_file_entry->symbolic_link_data != NULL )
2243
0
  {
2244
0
    result = libuna_utf16_string_copy_from_utf8_stream(
2245
0
              utf16_string,
2246
0
              utf16_string_size,
2247
0
              internal_file_entry->symbolic_link_data,
2248
0
              internal_file_entry->symbolic_link_data_size,
2249
0
              error );
2250
2251
0
    if( result != 1 )
2252
0
    {
2253
0
      libcerror_error_set(
2254
0
       error,
2255
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2256
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2257
0
       "%s: unable to retrieve UTF-16 string.",
2258
0
       function );
2259
2260
0
      result = -1;
2261
0
    }
2262
0
  }
2263
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
2264
0
  if( libcthreads_read_write_lock_release_for_write(
2265
0
       internal_file_entry->read_write_lock,
2266
0
       error ) != 1 )
2267
0
  {
2268
0
    libcerror_error_set(
2269
0
     error,
2270
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2271
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2272
0
     "%s: unable to release read/write lock for writing.",
2273
0
     function );
2274
2275
0
    return( -1 );
2276
0
  }
2277
0
#endif
2278
0
  return( result );
2279
0
}
2280
2281
/* Determines the extended attributes
2282
 * Returns 1 if successful or -1 on error
2283
 */
2284
int libfsext_internal_file_entry_get_extended_attributes(
2285
     libfsext_internal_file_entry_t *internal_file_entry,
2286
     libcerror_error_t **error )
2287
274
{
2288
274
  static char *function          = "libfsext_internal_file_entry_get_extended_attributes";
2289
274
  uint32_t file_acl_block_number = 0;
2290
2291
274
  if( internal_file_entry == NULL )
2292
0
  {
2293
0
    libcerror_error_set(
2294
0
     error,
2295
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2296
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2297
0
     "%s: invalid file entry.",
2298
0
     function );
2299
2300
0
    return( -1 );
2301
0
  }
2302
274
  if( internal_file_entry->io_handle == NULL )
2303
0
  {
2304
0
    libcerror_error_set(
2305
0
     error,
2306
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2307
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2308
0
     "%s: invalid file entry - missing IO handle.",
2309
0
     function );
2310
2311
0
    return( -1 );
2312
0
  }
2313
274
  if( internal_file_entry->inode == NULL )
2314
0
  {
2315
0
    libcerror_error_set(
2316
0
     error,
2317
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2318
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2319
0
     "%s: invalid file entry - missing inode.",
2320
0
     function );
2321
2322
0
    return( -1 );
2323
0
  }
2324
274
  if( internal_file_entry->extended_attributes_array != NULL )
2325
0
  {
2326
0
    libcerror_error_set(
2327
0
     error,
2328
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2329
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2330
0
     "%s: invalid file entry - extended attributes array value already set.",
2331
0
     function );
2332
2333
0
    return( -1 );
2334
0
  }
2335
274
  if( internal_file_entry->inode->extended_attributes_array != NULL )
2336
2
  {
2337
2
    internal_file_entry->extended_attributes_array        = internal_file_entry->inode->extended_attributes_array;
2338
2
    internal_file_entry->inode->extended_attributes_array = NULL;
2339
2
  }
2340
272
  else
2341
272
  {
2342
272
    if( libcdata_array_initialize(
2343
272
         &( internal_file_entry->extended_attributes_array ),
2344
272
         0,
2345
272
         error ) != 1 )
2346
0
    {
2347
0
      libcerror_error_set(
2348
0
       error,
2349
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2350
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2351
0
       "%s: unable to create extended attributes array.",
2352
0
       function );
2353
2354
0
      goto on_error;
2355
0
    }
2356
272
  }
2357
274
  if( libfsext_inode_get_file_acl_block_number(
2358
274
       internal_file_entry->inode,
2359
274
       &file_acl_block_number,
2360
274
       error ) != 1 )
2361
0
  {
2362
0
    libcerror_error_set(
2363
0
     error,
2364
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2365
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2366
0
     "%s: unable to retrieve file ACL block number from inode.",
2367
0
     function );
2368
2369
0
    goto on_error;
2370
0
  }
2371
274
  if( file_acl_block_number != 0 )
2372
256
  {
2373
256
    if( libfsext_attributes_block_read_file_io_handle(
2374
256
         internal_file_entry->extended_attributes_array,
2375
256
         internal_file_entry->io_handle,
2376
256
         internal_file_entry->file_io_handle,
2377
256
         (off64_t) file_acl_block_number * internal_file_entry->io_handle->block_size,
2378
256
         error ) != 1 )
2379
254
    {
2380
254
      libcerror_error_set(
2381
254
       error,
2382
254
       LIBCERROR_ERROR_DOMAIN_IO,
2383
254
       LIBCERROR_IO_ERROR_READ_FAILED,
2384
254
       "%s: unable to read extended attributes block: %" PRIu32 ".",
2385
254
       function,
2386
254
       file_acl_block_number );
2387
2388
254
      goto on_error;
2389
254
    }
2390
256
  }
2391
20
  return( 1 );
2392
2393
254
on_error:
2394
254
  if( internal_file_entry->extended_attributes_array != NULL )
2395
254
  {
2396
254
    libcdata_array_free(
2397
254
     &( internal_file_entry->extended_attributes_array ),
2398
254
     (int (*)(intptr_t **, libcerror_error_t **)) &libfsext_attribute_values_free,
2399
254
     NULL );
2400
254
  }
2401
254
  return( -1 );
2402
274
}
2403
2404
/* Retrieves the number of extended attributes
2405
 * Returns 1 if successful or -1 on error
2406
 */
2407
int libfsext_file_entry_get_number_of_extended_attributes(
2408
     libfsext_file_entry_t *file_entry,
2409
     int *number_of_extended_attributes,
2410
     libcerror_error_t **error )
2411
274
{
2412
274
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
2413
274
  static char *function                               = "libfsext_file_entry_get_number_of_extended_attributes";
2414
274
  int result                                          = 1;
2415
2416
274
  if( file_entry == NULL )
2417
0
  {
2418
0
    libcerror_error_set(
2419
0
     error,
2420
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2421
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2422
0
     "%s: invalid file entry.",
2423
0
     function );
2424
2425
0
    return( -1 );
2426
0
  }
2427
274
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
2428
2429
274
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
2430
274
  if( libcthreads_read_write_lock_grab_for_write(
2431
274
       internal_file_entry->read_write_lock,
2432
274
       error ) != 1 )
2433
0
  {
2434
0
    libcerror_error_set(
2435
0
     error,
2436
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2437
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2438
0
     "%s: unable to grab read/write lock for writing.",
2439
0
     function );
2440
2441
0
    return( -1 );
2442
0
  }
2443
274
#endif
2444
274
  if( internal_file_entry->extended_attributes_array == NULL )
2445
274
  {
2446
274
    if( libfsext_internal_file_entry_get_extended_attributes(
2447
274
         internal_file_entry,
2448
274
         error ) != 1 )
2449
254
    {
2450
254
      libcerror_error_set(
2451
254
       error,
2452
254
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2453
254
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2454
254
       "%s: unable to determine extended attributes.",
2455
254
       function );
2456
2457
254
      result = -1;
2458
254
    }
2459
274
  }
2460
274
  if( result != -1 )
2461
20
  {
2462
20
    if( libcdata_array_get_number_of_entries(
2463
20
         internal_file_entry->extended_attributes_array,
2464
20
         number_of_extended_attributes,
2465
20
         error ) != 1 )
2466
0
    {
2467
0
      libcerror_error_set(
2468
0
       error,
2469
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2470
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2471
0
       "%s: unable to retrieve number of entries from extended attributes array.",
2472
0
       function );
2473
2474
0
      result = -1;
2475
0
    }
2476
20
  }
2477
274
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
2478
274
  if( libcthreads_read_write_lock_release_for_write(
2479
274
       internal_file_entry->read_write_lock,
2480
274
       error ) != 1 )
2481
0
  {
2482
0
    libcerror_error_set(
2483
0
     error,
2484
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2485
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2486
0
     "%s: unable to release read/write lock for writing.",
2487
0
     function );
2488
2489
0
    return( -1 );
2490
0
  }
2491
274
#endif
2492
274
  return( result );
2493
274
}
2494
2495
/* Retrieves the extended attribute for the specific index
2496
 * Returns 1 if successful or -1 on error
2497
 */
2498
int libfsext_file_entry_get_extended_attribute_by_index(
2499
     libfsext_file_entry_t *file_entry,
2500
     int extended_attribute_index,
2501
     libfsext_extended_attribute_t **extended_attribute,
2502
     libcerror_error_t **error )
2503
3
{
2504
3
  libfsext_attribute_values_t *attribute_values       = NULL;
2505
3
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
2506
3
  static char *function                               = "libfsext_file_entry_get_extended_attribute_by_index";
2507
3
  int result                                          = 1;
2508
2509
3
  if( file_entry == NULL )
2510
0
  {
2511
0
    libcerror_error_set(
2512
0
     error,
2513
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2514
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2515
0
     "%s: invalid file entry.",
2516
0
     function );
2517
2518
0
    return( -1 );
2519
0
  }
2520
3
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
2521
2522
3
  if( extended_attribute == NULL )
2523
0
  {
2524
0
    libcerror_error_set(
2525
0
     error,
2526
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2527
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2528
0
     "%s: invalid extended attribute.",
2529
0
     function );
2530
2531
0
    return( -1 );
2532
0
  }
2533
3
  if( *extended_attribute != NULL )
2534
0
  {
2535
0
    libcerror_error_set(
2536
0
     error,
2537
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2538
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
2539
0
     "%s: invalid extended attribute value already set.",
2540
0
     function );
2541
2542
0
    return( -1 );
2543
0
  }
2544
3
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
2545
3
  if( libcthreads_read_write_lock_grab_for_write(
2546
3
       internal_file_entry->read_write_lock,
2547
3
       error ) != 1 )
2548
0
  {
2549
0
    libcerror_error_set(
2550
0
     error,
2551
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2552
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2553
0
     "%s: unable to grab read/write lock for writing.",
2554
0
     function );
2555
2556
0
    return( -1 );
2557
0
  }
2558
3
#endif
2559
3
  if( internal_file_entry->extended_attributes_array == NULL )
2560
0
  {
2561
0
    if( libfsext_internal_file_entry_get_extended_attributes(
2562
0
         internal_file_entry,
2563
0
         error ) != 1 )
2564
0
    {
2565
0
      libcerror_error_set(
2566
0
       error,
2567
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2568
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2569
0
       "%s: unable to determine extended attributes.",
2570
0
       function );
2571
2572
0
      result = -1;
2573
0
    }
2574
0
  }
2575
3
  if( result != -1 )
2576
3
  {
2577
3
    if( libcdata_array_get_entry_by_index(
2578
3
         internal_file_entry->extended_attributes_array,
2579
3
         extended_attribute_index,
2580
3
         (intptr_t **) &attribute_values,
2581
3
         error ) != 1 )
2582
0
    {
2583
0
      libcerror_error_set(
2584
0
       error,
2585
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2586
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2587
0
       "%s: unable to retrieve attribute: %d values.",
2588
0
       function,
2589
0
       extended_attribute_index );
2590
2591
0
      result = -1;
2592
0
    }
2593
3
    else
2594
3
    {
2595
3
      if( libfsext_extended_attribute_initialize(
2596
3
           extended_attribute,
2597
3
           internal_file_entry->io_handle,
2598
3
           internal_file_entry->file_io_handle,
2599
3
           internal_file_entry->inode_table,
2600
3
           attribute_values,
2601
3
           error ) != 1 )
2602
0
      {
2603
0
        libcerror_error_set(
2604
0
         error,
2605
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2606
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2607
0
         "%s: unable to create extended attribute.",
2608
0
         function );
2609
2610
0
        result = -1;
2611
0
      }
2612
3
    }
2613
3
  }
2614
3
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
2615
3
  if( libcthreads_read_write_lock_release_for_write(
2616
3
       internal_file_entry->read_write_lock,
2617
3
       error ) != 1 )
2618
0
  {
2619
0
    libcerror_error_set(
2620
0
     error,
2621
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2622
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2623
0
     "%s: unable to release read/write lock for writing.",
2624
0
     function );
2625
2626
0
    return( -1 );
2627
0
  }
2628
3
#endif
2629
3
  return( result );
2630
3
}
2631
2632
/* Retrieves the attribute values for an UTF-8 encoded name
2633
 * Returns 1 if successful, 0 if no such file entry or -1 on error
2634
 */
2635
int libfsext_internal_file_entry_get_attribute_values_by_utf8_name(
2636
     libfsext_internal_file_entry_t *internal_file_entry,
2637
     const uint8_t *utf8_string,
2638
     size_t utf8_string_length,
2639
     libfsext_attribute_values_t **attribute_values,
2640
     libcerror_error_t **error )
2641
0
{
2642
0
  libfsext_attribute_values_t *safe_attribute_values = NULL;
2643
0
  static char *function                              = "libfsext_internal_file_entry_get_attribute_values_by_utf8_name";
2644
0
  int attribute_index                                = 0;
2645
0
  int number_of_attributes                           = 0;
2646
0
  int result                                         = 0;
2647
2648
0
  if( internal_file_entry == NULL )
2649
0
  {
2650
0
    libcerror_error_set(
2651
0
     error,
2652
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2653
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2654
0
     "%s: invalid file entry.",
2655
0
     function );
2656
2657
0
    return( -1 );
2658
0
  }
2659
0
  if( internal_file_entry->extended_attributes_array == NULL )
2660
0
  {
2661
0
    if( libfsext_internal_file_entry_get_extended_attributes(
2662
0
         internal_file_entry,
2663
0
         error ) != 1 )
2664
0
    {
2665
0
      libcerror_error_set(
2666
0
       error,
2667
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2668
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2669
0
       "%s: unable to determine extended attributes.",
2670
0
       function );
2671
2672
0
      return( -1 );
2673
0
    }
2674
0
  }
2675
0
  if( libcdata_array_get_number_of_entries(
2676
0
       internal_file_entry->extended_attributes_array,
2677
0
       &number_of_attributes,
2678
0
       error ) != 1 )
2679
0
  {
2680
0
    libcerror_error_set(
2681
0
     error,
2682
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2683
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2684
0
     "%s: unable to retrieve number of entries from extended attributes array.",
2685
0
     function );
2686
2687
0
    return( -1 );
2688
0
  }
2689
0
  for( attribute_index = 0;
2690
0
       attribute_index < number_of_attributes;
2691
0
       attribute_index++ )
2692
0
  {
2693
0
    if( libcdata_array_get_entry_by_index(
2694
0
         internal_file_entry->extended_attributes_array,
2695
0
         attribute_index,
2696
0
         (intptr_t **) &safe_attribute_values,
2697
0
         error ) != 1 )
2698
0
    {
2699
0
      libcerror_error_set(
2700
0
       error,
2701
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2702
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2703
0
       "%s: unable to retrieve attribute: %d values.",
2704
0
       function,
2705
0
       attribute_index );
2706
2707
0
      return( -1 );
2708
0
    }
2709
0
    result = libfsext_attribute_values_compare_name_with_utf8_string(
2710
0
              safe_attribute_values,
2711
0
              utf8_string,
2712
0
              utf8_string_length,
2713
0
              error );
2714
2715
0
    if( result == -1 )
2716
0
    {
2717
0
      libcerror_error_set(
2718
0
       error,
2719
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2720
0
       LIBCERROR_RUNTIME_ERROR_GENERIC,
2721
0
       "%s: unable to compare UTF-8 string with name of attribute: %d values.",
2722
0
       function,
2723
0
       attribute_index );
2724
2725
0
      return( -1 );
2726
0
    }
2727
0
    else if( result == LIBUNA_COMPARE_EQUAL )
2728
0
    {
2729
0
      *attribute_values = safe_attribute_values;
2730
2731
0
      return( 1 );
2732
0
    }
2733
0
  }
2734
0
  return( 0 );
2735
0
}
2736
2737
/* Retrieves the attribute values for an UTF-16 encoded name
2738
 * Returns 1 if successful, 0 if no such file entry or -1 on error
2739
 */
2740
int libfsext_internal_file_entry_get_attribute_values_by_utf16_name(
2741
     libfsext_internal_file_entry_t *internal_file_entry,
2742
     const uint16_t *utf16_string,
2743
     size_t utf16_string_length,
2744
     libfsext_attribute_values_t **attribute_values,
2745
     libcerror_error_t **error )
2746
0
{
2747
0
  libfsext_attribute_values_t *safe_attribute_values = NULL;
2748
0
  static char *function                              = "libfsext_internal_file_entry_get_attribute_values_by_utf16_name";
2749
0
  int attribute_index                                = 0;
2750
0
  int number_of_attributes                           = 0;
2751
0
  int result                                         = 0;
2752
2753
0
  if( internal_file_entry == NULL )
2754
0
  {
2755
0
    libcerror_error_set(
2756
0
     error,
2757
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2758
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2759
0
     "%s: invalid file entry.",
2760
0
     function );
2761
2762
0
    return( -1 );
2763
0
  }
2764
0
  if( internal_file_entry->extended_attributes_array == NULL )
2765
0
  {
2766
0
    if( libfsext_internal_file_entry_get_extended_attributes(
2767
0
         internal_file_entry,
2768
0
         error ) != 1 )
2769
0
    {
2770
0
      libcerror_error_set(
2771
0
       error,
2772
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2773
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2774
0
       "%s: unable to determine extended attributes.",
2775
0
       function );
2776
2777
0
      return( -1 );
2778
0
    }
2779
0
  }
2780
0
  if( libcdata_array_get_number_of_entries(
2781
0
       internal_file_entry->extended_attributes_array,
2782
0
       &number_of_attributes,
2783
0
       error ) != 1 )
2784
0
  {
2785
0
    libcerror_error_set(
2786
0
     error,
2787
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2788
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2789
0
     "%s: unable to retrieve number of entries from extended attributes array.",
2790
0
     function );
2791
2792
0
    return( -1 );
2793
0
  }
2794
0
  for( attribute_index = 0;
2795
0
       attribute_index < number_of_attributes;
2796
0
       attribute_index++ )
2797
0
  {
2798
0
    if( libcdata_array_get_entry_by_index(
2799
0
         internal_file_entry->extended_attributes_array,
2800
0
         attribute_index,
2801
0
         (intptr_t **) &safe_attribute_values,
2802
0
         error ) != 1 )
2803
0
    {
2804
0
      libcerror_error_set(
2805
0
       error,
2806
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2807
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2808
0
       "%s: unable to retrieve attribute: %d values.",
2809
0
       function,
2810
0
       attribute_index );
2811
2812
0
      return( -1 );
2813
0
    }
2814
0
    result = libfsext_attribute_values_compare_name_with_utf16_string(
2815
0
              safe_attribute_values,
2816
0
              utf16_string,
2817
0
              utf16_string_length,
2818
0
              error );
2819
2820
0
    if( result == -1 )
2821
0
    {
2822
0
      libcerror_error_set(
2823
0
       error,
2824
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2825
0
       LIBCERROR_RUNTIME_ERROR_GENERIC,
2826
0
       "%s: unable to compare UTF-16 string with name of attribute: %d values.",
2827
0
       function,
2828
0
       attribute_index );
2829
2830
0
      return( -1 );
2831
0
    }
2832
0
    else if( result == LIBUNA_COMPARE_EQUAL )
2833
0
    {
2834
0
      *attribute_values = safe_attribute_values;
2835
2836
0
      return( 1 );
2837
0
    }
2838
0
  }
2839
0
  return( 0 );
2840
0
}
2841
2842
/* Determines if there is an extended attribute for an UTF-8 encoded name
2843
 * Returns 1 if available, 0 if not or -1 on error
2844
 */
2845
int libfsext_file_entry_has_extended_attribute_by_utf8_name(
2846
     libfsext_file_entry_t *file_entry,
2847
     const uint8_t *utf8_string,
2848
     size_t utf8_string_length,
2849
     libcerror_error_t **error )
2850
0
{
2851
0
  libfsext_attribute_values_t *attribute_values       = NULL;
2852
0
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
2853
0
  static char *function                               = "libfsext_file_entry_has_extended_attribute_by_utf8_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 = (libfsext_internal_file_entry_t *) file_entry;
2868
2869
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
2870
0
  if( libcthreads_read_write_lock_grab_for_write(
2871
0
       internal_file_entry->read_write_lock,
2872
0
       error ) != 1 )
2873
0
  {
2874
0
    libcerror_error_set(
2875
0
     error,
2876
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2877
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2878
0
     "%s: unable to grab read/write lock for writing.",
2879
0
     function );
2880
2881
0
    return( -1 );
2882
0
  }
2883
0
#endif
2884
0
  result = libfsext_internal_file_entry_get_attribute_values_by_utf8_name(
2885
0
            internal_file_entry,
2886
0
            utf8_string,
2887
0
            utf8_string_length,
2888
0
            &attribute_values,
2889
0
            error );
2890
2891
0
  if( result == -1 )
2892
0
  {
2893
0
    libcerror_error_set(
2894
0
     error,
2895
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2896
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2897
0
     "%s: unable to retrieve attribute values for UTF-8 name.",
2898
0
     function );
2899
2900
0
    result = -1;
2901
0
  }
2902
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
2903
0
  if( libcthreads_read_write_lock_release_for_write(
2904
0
       internal_file_entry->read_write_lock,
2905
0
       error ) != 1 )
2906
0
  {
2907
0
    libcerror_error_set(
2908
0
     error,
2909
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2910
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2911
0
     "%s: unable to release read/write lock for writing.",
2912
0
     function );
2913
2914
0
    return( -1 );
2915
0
  }
2916
0
#endif
2917
0
  return( result );
2918
0
}
2919
2920
/* Determines if there is an extended attribute for an UTF-8 encoded name
2921
 * Returns 1 if available, 0 if not or -1 on error
2922
 */
2923
int libfsext_file_entry_has_extended_attribute_by_utf16_name(
2924
     libfsext_file_entry_t *file_entry,
2925
     const uint16_t *utf16_string,
2926
     size_t utf16_string_length,
2927
     libcerror_error_t **error )
2928
0
{
2929
0
  libfsext_attribute_values_t *attribute_values       = NULL;
2930
0
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
2931
0
  static char *function                               = "libfsext_file_entry_has_extended_attribute_by_utf16_name";
2932
0
  int result                                          = 0;
2933
2934
0
  if( file_entry == NULL )
2935
0
  {
2936
0
    libcerror_error_set(
2937
0
     error,
2938
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2939
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2940
0
     "%s: invalid file entry.",
2941
0
     function );
2942
2943
0
    return( -1 );
2944
0
  }
2945
0
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
2946
2947
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
2948
0
  if( libcthreads_read_write_lock_grab_for_write(
2949
0
       internal_file_entry->read_write_lock,
2950
0
       error ) != 1 )
2951
0
  {
2952
0
    libcerror_error_set(
2953
0
     error,
2954
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2955
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2956
0
     "%s: unable to grab read/write lock for writing.",
2957
0
     function );
2958
2959
0
    return( -1 );
2960
0
  }
2961
0
#endif
2962
0
  result = libfsext_internal_file_entry_get_attribute_values_by_utf16_name(
2963
0
            internal_file_entry,
2964
0
            utf16_string,
2965
0
            utf16_string_length,
2966
0
            &attribute_values,
2967
0
            error );
2968
2969
0
  if( result == -1 )
2970
0
  {
2971
0
    libcerror_error_set(
2972
0
     error,
2973
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2974
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2975
0
     "%s: unable to retrieve attribute values for UTF-16 name.",
2976
0
     function );
2977
2978
0
    result = -1;
2979
0
  }
2980
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
2981
0
  if( libcthreads_read_write_lock_release_for_write(
2982
0
       internal_file_entry->read_write_lock,
2983
0
       error ) != 1 )
2984
0
  {
2985
0
    libcerror_error_set(
2986
0
     error,
2987
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2988
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2989
0
     "%s: unable to release read/write lock for writing.",
2990
0
     function );
2991
2992
0
    return( -1 );
2993
0
  }
2994
0
#endif
2995
0
  return( result );
2996
0
}
2997
2998
/* Retrieves the extended attribute for an UTF-8 encoded name
2999
 * Returns 1 if successful, 0 if no such file entry or -1 on error
3000
 */
3001
int libfsext_file_entry_get_extended_attribute_by_utf8_name(
3002
     libfsext_file_entry_t *file_entry,
3003
     const uint8_t *utf8_string,
3004
     size_t utf8_string_length,
3005
     libfsext_extended_attribute_t **extended_attribute,
3006
     libcerror_error_t **error )
3007
0
{
3008
0
  libfsext_attribute_values_t *attribute_values       = NULL;
3009
0
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
3010
0
  static char *function                               = "libfsext_file_entry_get_extended_attribute_by_utf8_name";
3011
0
  int result                                          = 0;
3012
3013
0
  if( file_entry == NULL )
3014
0
  {
3015
0
    libcerror_error_set(
3016
0
     error,
3017
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3018
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3019
0
     "%s: invalid file entry.",
3020
0
     function );
3021
3022
0
    return( -1 );
3023
0
  }
3024
0
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
3025
3026
0
  if( extended_attribute == NULL )
3027
0
  {
3028
0
    libcerror_error_set(
3029
0
     error,
3030
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3031
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3032
0
     "%s: invalid extended attribute.",
3033
0
     function );
3034
3035
0
    return( -1 );
3036
0
  }
3037
0
  if( *extended_attribute != NULL )
3038
0
  {
3039
0
    libcerror_error_set(
3040
0
     error,
3041
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3042
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3043
0
     "%s: invalid extended attribute value already set.",
3044
0
     function );
3045
3046
0
    return( -1 );
3047
0
  }
3048
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
3049
0
  if( libcthreads_read_write_lock_grab_for_write(
3050
0
       internal_file_entry->read_write_lock,
3051
0
       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 grab read/write lock for writing.",
3058
0
     function );
3059
3060
0
    return( -1 );
3061
0
  }
3062
0
#endif
3063
0
  result = libfsext_internal_file_entry_get_attribute_values_by_utf8_name(
3064
0
            internal_file_entry,
3065
0
            utf8_string,
3066
0
            utf8_string_length,
3067
0
            &attribute_values,
3068
0
            error );
3069
3070
0
  if( result == -1 )
3071
0
  {
3072
0
    libcerror_error_set(
3073
0
     error,
3074
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3075
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3076
0
     "%s: unable to retrieve attribute values for UTF-8 name.",
3077
0
     function );
3078
3079
0
    result = -1;
3080
0
  }
3081
0
  else if( result != 0 )
3082
0
  {
3083
0
    if( libfsext_extended_attribute_initialize(
3084
0
         extended_attribute,
3085
0
         internal_file_entry->io_handle,
3086
0
         internal_file_entry->file_io_handle,
3087
0
         internal_file_entry->inode_table,
3088
0
         attribute_values,
3089
0
         error ) != 1 )
3090
0
    {
3091
0
      libcerror_error_set(
3092
0
       error,
3093
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3094
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3095
0
       "%s: unable to create extended attribute.",
3096
0
       function );
3097
3098
0
      result = -1;
3099
0
    }
3100
0
  }
3101
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
3102
0
  if( libcthreads_read_write_lock_release_for_write(
3103
0
       internal_file_entry->read_write_lock,
3104
0
       error ) != 1 )
3105
0
  {
3106
0
    libcerror_error_set(
3107
0
     error,
3108
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3109
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3110
0
     "%s: unable to release read/write lock for writing.",
3111
0
     function );
3112
3113
0
    return( -1 );
3114
0
  }
3115
0
#endif
3116
0
  return( result );
3117
0
}
3118
3119
/* Retrieves the extended attribute for an UTF-16 encoded name
3120
 * Returns 1 if successful, 0 if no such file entry or -1 on error
3121
 */
3122
int libfsext_file_entry_get_extended_attribute_by_utf16_name(
3123
     libfsext_file_entry_t *file_entry,
3124
     const uint16_t *utf16_string,
3125
     size_t utf16_string_length,
3126
     libfsext_extended_attribute_t **extended_attribute,
3127
     libcerror_error_t **error )
3128
0
{
3129
0
  libfsext_attribute_values_t *attribute_values       = NULL;
3130
0
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
3131
0
  static char *function                               = "libfsext_file_entry_get_extended_attribute_by_utf16_name";
3132
0
  int result                                          = 0;
3133
3134
0
  if( file_entry == NULL )
3135
0
  {
3136
0
    libcerror_error_set(
3137
0
     error,
3138
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3139
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3140
0
     "%s: invalid file entry.",
3141
0
     function );
3142
3143
0
    return( -1 );
3144
0
  }
3145
0
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
3146
3147
0
  if( extended_attribute == NULL )
3148
0
  {
3149
0
    libcerror_error_set(
3150
0
     error,
3151
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3152
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3153
0
     "%s: invalid extended attribute.",
3154
0
     function );
3155
3156
0
    return( -1 );
3157
0
  }
3158
0
  if( *extended_attribute != NULL )
3159
0
  {
3160
0
    libcerror_error_set(
3161
0
     error,
3162
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3163
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3164
0
     "%s: invalid extended attribute value already set.",
3165
0
     function );
3166
3167
0
    return( -1 );
3168
0
  }
3169
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
3170
0
  if( libcthreads_read_write_lock_grab_for_write(
3171
0
       internal_file_entry->read_write_lock,
3172
0
       error ) != 1 )
3173
0
  {
3174
0
    libcerror_error_set(
3175
0
     error,
3176
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3177
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3178
0
     "%s: unable to grab read/write lock for writing.",
3179
0
     function );
3180
3181
0
    return( -1 );
3182
0
  }
3183
0
#endif
3184
0
  result = libfsext_internal_file_entry_get_attribute_values_by_utf16_name(
3185
0
            internal_file_entry,
3186
0
            utf16_string,
3187
0
            utf16_string_length,
3188
0
            &attribute_values,
3189
0
            error );
3190
3191
0
  if( result == -1 )
3192
0
  {
3193
0
    libcerror_error_set(
3194
0
     error,
3195
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3196
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3197
0
     "%s: unable to retrieve attribute values for UTF-16 name.",
3198
0
     function );
3199
3200
0
    result = -1;
3201
0
  }
3202
0
  else if( result != 0 )
3203
0
  {
3204
0
    if( libfsext_extended_attribute_initialize(
3205
0
         extended_attribute,
3206
0
         internal_file_entry->io_handle,
3207
0
         internal_file_entry->file_io_handle,
3208
0
         internal_file_entry->inode_table,
3209
0
         attribute_values,
3210
0
         error ) != 1 )
3211
0
    {
3212
0
      libcerror_error_set(
3213
0
       error,
3214
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3215
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3216
0
       "%s: unable to create extended attribute.",
3217
0
       function );
3218
3219
0
      result = -1;
3220
0
    }
3221
0
  }
3222
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
3223
0
  if( libcthreads_read_write_lock_release_for_write(
3224
0
       internal_file_entry->read_write_lock,
3225
0
       error ) != 1 )
3226
0
  {
3227
0
    libcerror_error_set(
3228
0
     error,
3229
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3230
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3231
0
     "%s: unable to release read/write lock for writing.",
3232
0
     function );
3233
3234
0
    return( -1 );
3235
0
  }
3236
0
#endif
3237
0
  return( result );
3238
0
}
3239
3240
/* Retrieves the number of sub file entries
3241
 * Returns 1 if successful or -1 on error
3242
 */
3243
int libfsext_file_entry_get_number_of_sub_file_entries(
3244
     libfsext_file_entry_t *file_entry,
3245
     int *number_of_sub_file_entries,
3246
     libcerror_error_t **error )
3247
1.14k
{
3248
1.14k
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
3249
1.14k
  static char *function                               = "libfsext_file_entry_get_number_of_sub_file_entries";
3250
1.14k
  int result                                          = 1;
3251
1.14k
  int safe_number_of_sub_file_entries                 = 0;
3252
3253
1.14k
  if( file_entry == NULL )
3254
0
  {
3255
0
    libcerror_error_set(
3256
0
     error,
3257
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3258
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3259
0
     "%s: invalid file entry.",
3260
0
     function );
3261
3262
0
    return( -1 );
3263
0
  }
3264
1.14k
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
3265
3266
1.14k
  if( number_of_sub_file_entries == NULL )
3267
0
  {
3268
0
    libcerror_error_set(
3269
0
     error,
3270
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3271
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3272
0
     "%s: invalid number of sub file entries.",
3273
0
     function );
3274
3275
0
    return( -1 );
3276
0
  }
3277
1.14k
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
3278
1.14k
  if( libcthreads_read_write_lock_grab_for_read(
3279
1.14k
       internal_file_entry->read_write_lock,
3280
1.14k
       error ) != 1 )
3281
0
  {
3282
0
    libcerror_error_set(
3283
0
     error,
3284
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3285
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3286
0
     "%s: unable to grab read/write lock for reading.",
3287
0
     function );
3288
3289
0
    return( -1 );
3290
0
  }
3291
1.14k
#endif
3292
1.14k
  if( internal_file_entry->directory == NULL )
3293
1.14k
  {
3294
1.14k
    if( libfsext_internal_file_entry_get_directory(
3295
1.14k
         internal_file_entry,
3296
1.14k
         error ) != 1 )
3297
253
    {
3298
253
      libcerror_error_set(
3299
253
       error,
3300
253
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3301
253
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3302
253
       "%s: unable to determine directory.",
3303
253
       function );
3304
3305
253
      result = -1;
3306
253
    }
3307
1.14k
  }
3308
1.14k
  if( internal_file_entry->directory != NULL )
3309
765
  {
3310
765
    if( libfsext_directory_get_number_of_entries(
3311
765
         internal_file_entry->directory,
3312
765
         &safe_number_of_sub_file_entries,
3313
765
         error ) != 1 )
3314
0
    {
3315
0
      libcerror_error_set(
3316
0
       error,
3317
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3318
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3319
0
       "%s: unable to retrieve number of entries from directory.",
3320
0
       function );
3321
3322
0
      result = -1;
3323
0
    }
3324
765
  }
3325
1.14k
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
3326
1.14k
  if( libcthreads_read_write_lock_release_for_read(
3327
1.14k
       internal_file_entry->read_write_lock,
3328
1.14k
       error ) != 1 )
3329
0
  {
3330
0
    libcerror_error_set(
3331
0
     error,
3332
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3333
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3334
0
     "%s: unable to release read/write lock for reading.",
3335
0
     function );
3336
3337
0
    return( -1 );
3338
0
  }
3339
1.14k
#endif
3340
1.14k
  if( result == 1 )
3341
891
  {
3342
891
    *number_of_sub_file_entries = safe_number_of_sub_file_entries;
3343
891
  }
3344
1.14k
  return( result );
3345
1.14k
}
3346
3347
/* Retrieves the sub file entry for the specific index
3348
 * Returns 1 if successful or -1 on error
3349
 */
3350
int libfsext_internal_file_entry_get_sub_file_entry_by_index(
3351
     libfsext_internal_file_entry_t *internal_file_entry,
3352
     int sub_file_entry_index,
3353
     libfsext_file_entry_t **sub_file_entry,
3354
     libcerror_error_t **error )
3355
744
{
3356
744
  libfsext_directory_t *directory                  = NULL;
3357
744
  libfsext_directory_entry_t *directory_entry      = NULL;
3358
744
  libfsext_directory_entry_t *safe_directory_entry = NULL;
3359
744
  libfsext_inode_t *inode                          = NULL;
3360
744
  libfsext_inode_t *safe_inode                     = NULL;
3361
744
  static char *function                            = "libfsext_file_entry_get_sub_file_entry_by_index";
3362
3363
744
  if( internal_file_entry == NULL )
3364
0
  {
3365
0
    libcerror_error_set(
3366
0
     error,
3367
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3368
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3369
0
     "%s: invalid file entry.",
3370
0
     function );
3371
3372
0
    return( -1 );
3373
0
  }
3374
744
  if( sub_file_entry == NULL )
3375
0
  {
3376
0
    libcerror_error_set(
3377
0
     error,
3378
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3379
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3380
0
     "%s: invalid sub file entry.",
3381
0
     function );
3382
3383
0
    return( -1 );
3384
0
  }
3385
744
  if( *sub_file_entry != NULL )
3386
0
  {
3387
0
    libcerror_error_set(
3388
0
     error,
3389
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3390
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3391
0
     "%s: invalid sub file entry value already set.",
3392
0
     function );
3393
3394
0
    return( -1 );
3395
0
  }
3396
744
  if( internal_file_entry->directory == NULL )
3397
0
  {
3398
0
    if( libfsext_internal_file_entry_get_directory(
3399
0
         internal_file_entry,
3400
0
         error ) != 1 )
3401
0
    {
3402
0
      libcerror_error_set(
3403
0
       error,
3404
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3405
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3406
0
       "%s: unable to determine directory.",
3407
0
       function );
3408
3409
0
      goto on_error;
3410
0
    }
3411
0
  }
3412
744
  if( libfsext_directory_get_entry_by_index(
3413
744
       internal_file_entry->directory,
3414
744
       sub_file_entry_index,
3415
744
       &directory_entry,
3416
744
       error ) != 1 )
3417
0
  {
3418
0
    libcerror_error_set(
3419
0
     error,
3420
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3421
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3422
0
     "%s: unable to retrieve entry: %d from directory.",
3423
0
     function,
3424
0
     sub_file_entry_index );
3425
3426
0
    goto on_error;
3427
0
  }
3428
744
  if( directory_entry == NULL )
3429
0
  {
3430
0
    libcerror_error_set(
3431
0
     error,
3432
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3433
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3434
0
     "%s: missing directory entry: %d.",
3435
0
     function,
3436
0
     sub_file_entry_index );
3437
3438
0
    goto on_error;
3439
0
  }
3440
744
  if( libfsext_inode_table_get_inode_by_number(
3441
744
       internal_file_entry->inode_table,
3442
744
       internal_file_entry->file_io_handle,
3443
744
       directory_entry->inode_number,
3444
744
       &inode,
3445
744
       error ) != 1 )
3446
306
  {
3447
306
    libcerror_error_set(
3448
306
     error,
3449
306
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3450
306
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3451
306
     "%s: unable to retrieve inode number: %" PRIu32 ".",
3452
306
     function,
3453
306
     directory_entry->inode_number );
3454
3455
306
    goto on_error;
3456
306
  }
3457
438
  if( inode == NULL )
3458
0
  {
3459
0
    libcerror_error_set(
3460
0
     error,
3461
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3462
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3463
0
     "%s: missing inode: %" PRIu32 ".",
3464
0
     function,
3465
0
     directory_entry->inode_number );
3466
3467
0
    goto on_error;
3468
0
  }
3469
438
  if( libfsext_inode_clone(
3470
438
       &safe_inode,
3471
438
       inode,
3472
438
       error ) != 1 )
3473
0
  {
3474
0
    libcerror_error_set(
3475
0
     error,
3476
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3477
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3478
0
     "%s: unable to create inode.",
3479
0
     function );
3480
3481
0
    goto on_error;
3482
0
  }
3483
438
  if( libfsext_directory_entry_clone(
3484
438
       &safe_directory_entry,
3485
438
       directory_entry,
3486
438
       error ) != 1 )
3487
0
  {
3488
0
    libcerror_error_set(
3489
0
     error,
3490
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3491
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3492
0
     "%s: unable to create directory entry.",
3493
0
     function );
3494
3495
0
    goto on_error;
3496
0
  }
3497
  /* libfsext_file_entry_initialize takes over management of safe_inode and safe_directory_entry
3498
   */
3499
438
  if( libfsext_file_entry_initialize(
3500
438
       sub_file_entry,
3501
438
       internal_file_entry->io_handle,
3502
438
       internal_file_entry->file_io_handle,
3503
438
       internal_file_entry->inode_table,
3504
438
       directory_entry->inode_number,
3505
438
       safe_inode,
3506
438
       safe_directory_entry,
3507
438
       error ) != 1 )
3508
1
  {
3509
1
    libcerror_error_set(
3510
1
     error,
3511
1
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3512
1
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3513
1
     "%s: unable to create sub file entry.",
3514
1
     function );
3515
3516
1
    goto on_error;
3517
1
  }
3518
437
  return( 1 );
3519
3520
307
on_error:
3521
307
  if( safe_directory_entry != NULL )
3522
1
  {
3523
1
    libfsext_directory_entry_free(
3524
1
     &safe_directory_entry,
3525
1
     NULL );
3526
1
  }
3527
307
  if( safe_inode != NULL )
3528
1
  {
3529
1
    libfsext_inode_free(
3530
1
     &safe_inode,
3531
1
     NULL );
3532
1
  }
3533
307
  if( directory != NULL )
3534
0
  {
3535
0
    libfsext_directory_free(
3536
0
     &directory,
3537
0
     NULL );
3538
0
  }
3539
307
  return( -1 );
3540
438
}
3541
3542
/* Retrieves the sub file entry for the specific index
3543
 * Returns 1 if successful or -1 on error
3544
 */
3545
int libfsext_file_entry_get_sub_file_entry_by_index(
3546
     libfsext_file_entry_t *file_entry,
3547
     int sub_file_entry_index,
3548
     libfsext_file_entry_t **sub_file_entry,
3549
     libcerror_error_t **error )
3550
744
{
3551
744
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
3552
744
  static char *function                               = "libfsext_file_entry_get_sub_file_entry_by_index";
3553
744
  int result                                          = 1;
3554
3555
744
  if( file_entry == NULL )
3556
0
  {
3557
0
    libcerror_error_set(
3558
0
     error,
3559
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3560
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3561
0
     "%s: invalid file entry.",
3562
0
     function );
3563
3564
0
    return( -1 );
3565
0
  }
3566
744
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
3567
3568
744
  if( sub_file_entry == NULL )
3569
0
  {
3570
0
    libcerror_error_set(
3571
0
     error,
3572
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3573
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3574
0
     "%s: invalid sub file entry.",
3575
0
     function );
3576
3577
0
    return( -1 );
3578
0
  }
3579
744
  if( *sub_file_entry != NULL )
3580
0
  {
3581
0
    libcerror_error_set(
3582
0
     error,
3583
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3584
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3585
0
     "%s: invalid sub file entry value already set.",
3586
0
     function );
3587
3588
0
    return( -1 );
3589
0
  }
3590
744
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
3591
744
  if( libcthreads_read_write_lock_grab_for_read(
3592
744
       internal_file_entry->read_write_lock,
3593
744
       error ) != 1 )
3594
0
  {
3595
0
    libcerror_error_set(
3596
0
     error,
3597
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3598
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3599
0
     "%s: unable to grab read/write lock for reading.",
3600
0
     function );
3601
3602
0
    return( -1 );
3603
0
  }
3604
744
#endif
3605
744
  if( libfsext_internal_file_entry_get_sub_file_entry_by_index(
3606
744
       internal_file_entry,
3607
744
       sub_file_entry_index,
3608
744
       sub_file_entry,
3609
744
       error ) != 1 )
3610
307
  {
3611
307
    libcerror_error_set(
3612
307
     error,
3613
307
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3614
307
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3615
307
     "%s: unable to retrieve sub file entry: %d.",
3616
307
     function,
3617
307
     sub_file_entry_index );
3618
3619
307
    result = -1;
3620
307
  }
3621
744
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
3622
744
  if( libcthreads_read_write_lock_release_for_read(
3623
744
       internal_file_entry->read_write_lock,
3624
744
       error ) != 1 )
3625
0
  {
3626
0
    libcerror_error_set(
3627
0
     error,
3628
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3629
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3630
0
     "%s: unable to release read/write lock for reading.",
3631
0
     function );
3632
3633
0
    return( -1 );
3634
0
  }
3635
744
#endif
3636
744
  return( result );
3637
744
}
3638
3639
/* Retrieves the sub file entry for an UTF-8 encoded name
3640
 * Returns 1 if successful, 0 if no such file entry or -1 on error
3641
 */
3642
int libfsext_internal_file_entry_get_sub_file_entry_by_utf8_name(
3643
     libfsext_internal_file_entry_t *internal_file_entry,
3644
     const uint8_t *utf8_string,
3645
     size_t utf8_string_length,
3646
     libfsext_file_entry_t **sub_file_entry,
3647
     libcerror_error_t **error )
3648
0
{
3649
0
  libfsext_directory_entry_t *directory_entry     = NULL;
3650
0
  libfsext_directory_entry_t *sub_directory_entry = NULL;
3651
0
  libfsext_inode_t *inode                         = NULL;
3652
0
  static char *function                           = "libfsext_internal_file_entry_get_sub_file_entry_by_utf8_name";
3653
0
  int result                                      = 0;
3654
3655
0
  if( internal_file_entry == NULL )
3656
0
  {
3657
0
    libcerror_error_set(
3658
0
     error,
3659
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3660
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3661
0
     "%s: invalid file entry.",
3662
0
     function );
3663
3664
0
    return( -1 );
3665
0
  }
3666
0
  if( sub_file_entry == NULL )
3667
0
  {
3668
0
    libcerror_error_set(
3669
0
     error,
3670
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3671
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3672
0
     "%s: invalid sub file entry.",
3673
0
     function );
3674
3675
0
    return( -1 );
3676
0
  }
3677
0
  if( *sub_file_entry != NULL )
3678
0
  {
3679
0
    libcerror_error_set(
3680
0
     error,
3681
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3682
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3683
0
     "%s: invalid sub file entry value already set.",
3684
0
     function );
3685
3686
0
    return( -1 );
3687
0
  }
3688
0
  if( internal_file_entry->directory == NULL )
3689
0
  {
3690
0
    if( libfsext_internal_file_entry_get_directory(
3691
0
         internal_file_entry,
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_GET_FAILED,
3698
0
       "%s: unable to determine directory.",
3699
0
       function );
3700
3701
0
      goto on_error;
3702
0
    }
3703
0
  }
3704
0
  result = libfsext_directory_get_entry_by_utf8_name(
3705
0
            internal_file_entry->directory,
3706
0
            utf8_string,
3707
0
            utf8_string_length,
3708
0
            &directory_entry,
3709
0
            error );
3710
3711
0
  if( result == -1 )
3712
0
  {
3713
0
    libcerror_error_set(
3714
0
     error,
3715
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3716
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3717
0
     "%s: unable to retrieve directory entry.",
3718
0
     function );
3719
3720
0
    goto on_error;
3721
0
  }
3722
0
  else if( result == 0 )
3723
0
  {
3724
0
    return( 0 );
3725
0
  }
3726
0
  if( libfsext_directory_entry_clone(
3727
0
       &sub_directory_entry,
3728
0
       directory_entry,
3729
0
       error ) != 1 )
3730
0
  {
3731
0
    libcerror_error_set(
3732
0
     error,
3733
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3734
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3735
0
     "%s: unable to create sub directory entry.",
3736
0
     function );
3737
3738
0
    goto on_error;
3739
0
  }
3740
/* TODO set inode */
3741
  /* libfsext_file_entry_initialize takes over management of sub_directory_entry
3742
   */
3743
0
  if( libfsext_file_entry_initialize(
3744
0
       sub_file_entry,
3745
0
       internal_file_entry->io_handle,
3746
0
       internal_file_entry->file_io_handle,
3747
0
       internal_file_entry->inode_table,
3748
0
       sub_directory_entry->inode_number,
3749
0
       inode,
3750
0
       sub_directory_entry,
3751
0
       error ) != 1 )
3752
0
  {
3753
0
    libcerror_error_set(
3754
0
     error,
3755
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3756
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3757
0
     "%s: unable to create sub file entry.",
3758
0
     function );
3759
3760
0
    goto on_error;
3761
0
  }
3762
0
  return( 1 );
3763
3764
0
on_error:
3765
0
  if( sub_directory_entry != NULL )
3766
0
  {
3767
0
    libfsext_directory_entry_free(
3768
0
     &sub_directory_entry,
3769
0
     NULL );
3770
0
  }
3771
0
  return( -1 );
3772
0
}
3773
3774
/* Retrieves the sub file entry for an UTF-8 encoded name
3775
 * Returns 1 if successful, 0 if no such file entry or -1 on error
3776
 */
3777
int libfsext_file_entry_get_sub_file_entry_by_utf8_name(
3778
     libfsext_file_entry_t *file_entry,
3779
     const uint8_t *utf8_string,
3780
     size_t utf8_string_length,
3781
     libfsext_file_entry_t **sub_file_entry,
3782
     libcerror_error_t **error )
3783
0
{
3784
0
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
3785
0
  static char *function                               = "libfsext_file_entry_get_sub_file_entry_by_utf8_name";
3786
0
  int result                                          = 1;
3787
3788
0
  if( file_entry == NULL )
3789
0
  {
3790
0
    libcerror_error_set(
3791
0
     error,
3792
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3793
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3794
0
     "%s: invalid file entry.",
3795
0
     function );
3796
3797
0
    return( -1 );
3798
0
  }
3799
0
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
3800
3801
0
  if( sub_file_entry == NULL )
3802
0
  {
3803
0
    libcerror_error_set(
3804
0
     error,
3805
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3806
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3807
0
     "%s: invalid sub file entry.",
3808
0
     function );
3809
3810
0
    return( -1 );
3811
0
  }
3812
0
  if( *sub_file_entry != NULL )
3813
0
  {
3814
0
    libcerror_error_set(
3815
0
     error,
3816
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3817
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3818
0
     "%s: invalid sub file entry value already set.",
3819
0
     function );
3820
3821
0
    return( -1 );
3822
0
  }
3823
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
3824
0
  if( libcthreads_read_write_lock_grab_for_read(
3825
0
       internal_file_entry->read_write_lock,
3826
0
       error ) != 1 )
3827
0
  {
3828
0
    libcerror_error_set(
3829
0
     error,
3830
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3831
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3832
0
     "%s: unable to grab read/write lock for reading.",
3833
0
     function );
3834
3835
0
    return( -1 );
3836
0
  }
3837
0
#endif
3838
0
  if( libfsext_internal_file_entry_get_sub_file_entry_by_utf8_name(
3839
0
       internal_file_entry,
3840
0
       utf8_string,
3841
0
       utf8_string_length,
3842
0
       sub_file_entry,
3843
0
       error ) != 1 )
3844
0
  {
3845
0
    libcerror_error_set(
3846
0
     error,
3847
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3848
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3849
0
     "%s: unable to retrieve sub file entry.",
3850
0
     function );
3851
3852
0
    result = -1;
3853
0
  }
3854
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
3855
0
  if( libcthreads_read_write_lock_release_for_read(
3856
0
       internal_file_entry->read_write_lock,
3857
0
       error ) != 1 )
3858
0
  {
3859
0
    libcerror_error_set(
3860
0
     error,
3861
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3862
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3863
0
     "%s: unable to release read/write lock for reading.",
3864
0
     function );
3865
3866
0
    return( -1 );
3867
0
  }
3868
0
#endif
3869
0
  return( result );
3870
0
}
3871
3872
/* Retrieves the sub file entry for an UTF-16 encoded name
3873
 * Returns 1 if successful, 0 if no such file entry or -1 on error
3874
 */
3875
int libfsext_internal_file_entry_get_sub_file_entry_by_utf16_name(
3876
     libfsext_internal_file_entry_t *internal_file_entry,
3877
     const uint16_t *utf16_string,
3878
     size_t utf16_string_length,
3879
     libfsext_file_entry_t **sub_file_entry,
3880
     libcerror_error_t **error )
3881
0
{
3882
0
  libfsext_directory_entry_t *directory_entry     = NULL;
3883
0
  libfsext_directory_entry_t *sub_directory_entry = NULL;
3884
0
  libfsext_inode_t *inode                         = NULL;
3885
0
  static char *function                           = "libfsext_internal_file_entry_get_sub_file_entry_by_utf16_name";
3886
0
  int result                                      = 0;
3887
3888
0
  if( internal_file_entry == NULL )
3889
0
  {
3890
0
    libcerror_error_set(
3891
0
     error,
3892
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3893
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3894
0
     "%s: invalid file entry.",
3895
0
     function );
3896
3897
0
    return( -1 );
3898
0
  }
3899
0
  if( sub_file_entry == NULL )
3900
0
  {
3901
0
    libcerror_error_set(
3902
0
     error,
3903
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3904
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3905
0
     "%s: invalid sub file entry.",
3906
0
     function );
3907
3908
0
    return( -1 );
3909
0
  }
3910
0
  if( *sub_file_entry != NULL )
3911
0
  {
3912
0
    libcerror_error_set(
3913
0
     error,
3914
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3915
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
3916
0
     "%s: invalid sub file entry value already set.",
3917
0
     function );
3918
3919
0
    return( -1 );
3920
0
  }
3921
0
  if( internal_file_entry->directory == NULL )
3922
0
  {
3923
0
    if( libfsext_internal_file_entry_get_directory(
3924
0
         internal_file_entry,
3925
0
         error ) != 1 )
3926
0
    {
3927
0
      libcerror_error_set(
3928
0
       error,
3929
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3930
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3931
0
       "%s: unable to determine directory.",
3932
0
       function );
3933
3934
0
      goto on_error;
3935
0
    }
3936
0
  }
3937
0
  result = libfsext_directory_get_entry_by_utf16_name(
3938
0
            internal_file_entry->directory,
3939
0
            utf16_string,
3940
0
            utf16_string_length,
3941
0
            &directory_entry,
3942
0
            error );
3943
3944
0
  if( result == -1 )
3945
0
  {
3946
0
    libcerror_error_set(
3947
0
     error,
3948
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3949
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3950
0
     "%s: unable to retrieve directory entry.",
3951
0
     function );
3952
3953
0
    goto on_error;
3954
0
  }
3955
0
  else if( result == 0 )
3956
0
  {
3957
0
    return( 0 );
3958
0
  }
3959
0
  if( libfsext_directory_entry_clone(
3960
0
       &sub_directory_entry,
3961
0
       directory_entry,
3962
0
       error ) != 1 )
3963
0
  {
3964
0
    libcerror_error_set(
3965
0
     error,
3966
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3967
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3968
0
     "%s: unable to create sub directory entry.",
3969
0
     function );
3970
3971
0
    goto on_error;
3972
0
  }
3973
/* TODO set inode */
3974
  /* libfsext_file_entry_initialize takes over management of sub_directory_entry
3975
   */
3976
0
  if( libfsext_file_entry_initialize(
3977
0
       sub_file_entry,
3978
0
       internal_file_entry->io_handle,
3979
0
       internal_file_entry->file_io_handle,
3980
0
       internal_file_entry->inode_table,
3981
0
       sub_directory_entry->inode_number,
3982
0
       inode,
3983
0
       sub_directory_entry,
3984
0
       error ) != 1 )
3985
0
  {
3986
0
    libcerror_error_set(
3987
0
     error,
3988
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3989
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3990
0
     "%s: unable to create sub file entry.",
3991
0
     function );
3992
3993
0
    goto on_error;
3994
0
  }
3995
0
  return( 1 );
3996
3997
0
on_error:
3998
0
  if( sub_directory_entry != NULL )
3999
0
  {
4000
0
    libfsext_directory_entry_free(
4001
0
     &sub_directory_entry,
4002
0
     NULL );
4003
0
  }
4004
0
  return( -1 );
4005
0
}
4006
4007
/* Retrieves the sub file entry for an UTF-16 encoded name
4008
 * Returns 1 if successful, 0 if no such file entry or -1 on error
4009
 */
4010
int libfsext_file_entry_get_sub_file_entry_by_utf16_name(
4011
     libfsext_file_entry_t *file_entry,
4012
     const uint16_t *utf16_string,
4013
     size_t utf16_string_length,
4014
     libfsext_file_entry_t **sub_file_entry,
4015
     libcerror_error_t **error )
4016
0
{
4017
0
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
4018
0
  static char *function                               = "libfsext_file_entry_get_sub_file_entry_by_utf16_name";
4019
0
  int result                                          = 1;
4020
4021
0
  if( file_entry == NULL )
4022
0
  {
4023
0
    libcerror_error_set(
4024
0
     error,
4025
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4026
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4027
0
     "%s: invalid file entry.",
4028
0
     function );
4029
4030
0
    return( -1 );
4031
0
  }
4032
0
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
4033
4034
0
  if( sub_file_entry == NULL )
4035
0
  {
4036
0
    libcerror_error_set(
4037
0
     error,
4038
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4039
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4040
0
     "%s: invalid sub file entry.",
4041
0
     function );
4042
4043
0
    return( -1 );
4044
0
  }
4045
0
  if( *sub_file_entry != NULL )
4046
0
  {
4047
0
    libcerror_error_set(
4048
0
     error,
4049
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4050
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
4051
0
     "%s: invalid sub file entry value already set.",
4052
0
     function );
4053
4054
0
    return( -1 );
4055
0
  }
4056
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
4057
0
  if( libcthreads_read_write_lock_grab_for_read(
4058
0
       internal_file_entry->read_write_lock,
4059
0
       error ) != 1 )
4060
0
  {
4061
0
    libcerror_error_set(
4062
0
     error,
4063
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4064
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4065
0
     "%s: unable to grab read/write lock for reading.",
4066
0
     function );
4067
4068
0
    return( -1 );
4069
0
  }
4070
0
#endif
4071
0
  if( libfsext_internal_file_entry_get_sub_file_entry_by_utf16_name(
4072
0
       internal_file_entry,
4073
0
       utf16_string,
4074
0
       utf16_string_length,
4075
0
       sub_file_entry,
4076
0
       error ) != 1 )
4077
0
  {
4078
0
    libcerror_error_set(
4079
0
     error,
4080
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4081
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4082
0
     "%s: unable to retrieve sub file entry.",
4083
0
     function );
4084
4085
0
    result = -1;
4086
0
  }
4087
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
4088
0
  if( libcthreads_read_write_lock_release_for_read(
4089
0
       internal_file_entry->read_write_lock,
4090
0
       error ) != 1 )
4091
0
  {
4092
0
    libcerror_error_set(
4093
0
     error,
4094
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4095
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4096
0
     "%s: unable to release read/write lock for reading.",
4097
0
     function );
4098
4099
0
    return( -1 );
4100
0
  }
4101
0
#endif
4102
0
  return( result );
4103
0
}
4104
4105
/* Reads data at the current offset
4106
 * Returns the number of bytes read or -1 on error
4107
 */
4108
ssize_t libfsext_file_entry_read_buffer(
4109
         libfsext_file_entry_t *file_entry,
4110
         void *buffer,
4111
         size_t buffer_size,
4112
         libcerror_error_t **error )
4113
0
{
4114
0
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
4115
0
  static char *function                               = "libfsext_file_entry_read_buffer";
4116
0
  ssize_t read_count                                  = 0;
4117
4118
0
  if( file_entry == NULL )
4119
0
  {
4120
0
    libcerror_error_set(
4121
0
     error,
4122
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4123
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4124
0
     "%s: invalid file entry.",
4125
0
     function );
4126
4127
0
    return( -1 );
4128
0
  }
4129
0
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
4130
4131
0
  if( internal_file_entry->inode == NULL )
4132
0
  {
4133
0
    libcerror_error_set(
4134
0
     error,
4135
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4136
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4137
0
     "%s: invalid file entry - missing inode.",
4138
0
     function );
4139
4140
0
    return( -1 );
4141
0
  }
4142
0
  if( ( internal_file_entry->inode->file_mode & 0xf000 ) != LIBFSEXT_FILE_TYPE_REGULAR_FILE )
4143
0
  {
4144
0
    libcerror_error_set(
4145
0
     error,
4146
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4147
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4148
0
     "%s: invalid file entry - invalid inode - unsupported file mode not a regular file.",
4149
0
     function );
4150
4151
0
    return( -1 );
4152
0
  }
4153
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
4154
0
  if( libcthreads_read_write_lock_grab_for_write(
4155
0
       internal_file_entry->read_write_lock,
4156
0
       error ) != 1 )
4157
0
  {
4158
0
    libcerror_error_set(
4159
0
     error,
4160
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4161
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4162
0
     "%s: unable to grab read/write lock for writing.",
4163
0
     function );
4164
4165
0
    return( -1 );
4166
0
  }
4167
0
#endif
4168
0
  read_count = libfdata_stream_read_buffer(
4169
0
                internal_file_entry->data_block_stream,
4170
0
                (intptr_t *) internal_file_entry->file_io_handle,
4171
0
                buffer,
4172
0
                buffer_size,
4173
0
                0,
4174
0
                error );
4175
4176
0
  if( read_count < 0 )
4177
0
  {
4178
0
    libcerror_error_set(
4179
0
     error,
4180
0
     LIBCERROR_ERROR_DOMAIN_IO,
4181
0
     LIBCERROR_IO_ERROR_READ_FAILED,
4182
0
     "%s: unable to read from data block stream.",
4183
0
     function );
4184
4185
0
    read_count = -1;
4186
0
  }
4187
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
4188
0
  if( libcthreads_read_write_lock_release_for_write(
4189
0
       internal_file_entry->read_write_lock,
4190
0
       error ) != 1 )
4191
0
  {
4192
0
    libcerror_error_set(
4193
0
     error,
4194
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4195
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4196
0
     "%s: unable to release read/write lock for writing.",
4197
0
     function );
4198
4199
0
    return( -1 );
4200
0
  }
4201
0
#endif
4202
0
  return( read_count );
4203
0
}
4204
4205
/* Reads data at a specific offset
4206
 * Returns the number of bytes read or -1 on error
4207
 */
4208
ssize_t libfsext_file_entry_read_buffer_at_offset(
4209
         libfsext_file_entry_t *file_entry,
4210
         void *buffer,
4211
         size_t buffer_size,
4212
         off64_t offset,
4213
         libcerror_error_t **error )
4214
0
{
4215
0
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
4216
0
  static char *function                               = "libfsext_file_entry_read_buffer_at_offset";
4217
0
  ssize_t read_count                                  = 0;
4218
4219
0
  if( file_entry == NULL )
4220
0
  {
4221
0
    libcerror_error_set(
4222
0
     error,
4223
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4224
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4225
0
     "%s: invalid file entry.",
4226
0
     function );
4227
4228
0
    return( -1 );
4229
0
  }
4230
0
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
4231
4232
0
  if( internal_file_entry->inode == NULL )
4233
0
  {
4234
0
    libcerror_error_set(
4235
0
     error,
4236
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4237
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4238
0
     "%s: invalid file entry - missing inode.",
4239
0
     function );
4240
4241
0
    return( -1 );
4242
0
  }
4243
0
  if( ( internal_file_entry->inode->file_mode & 0xf000 ) != LIBFSEXT_FILE_TYPE_REGULAR_FILE )
4244
0
  {
4245
0
    libcerror_error_set(
4246
0
     error,
4247
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4248
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4249
0
     "%s: invalid file entry - invalid inode - unsupported file mode not a regular file.",
4250
0
     function );
4251
4252
0
    return( -1 );
4253
0
  }
4254
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
4255
0
  if( libcthreads_read_write_lock_grab_for_write(
4256
0
       internal_file_entry->read_write_lock,
4257
0
       error ) != 1 )
4258
0
  {
4259
0
    libcerror_error_set(
4260
0
     error,
4261
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4262
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4263
0
     "%s: unable to grab read/write lock for writing.",
4264
0
     function );
4265
4266
0
    return( -1 );
4267
0
  }
4268
0
#endif
4269
0
  read_count = libfdata_stream_read_buffer_at_offset(
4270
0
                internal_file_entry->data_block_stream,
4271
0
                (intptr_t *) internal_file_entry->file_io_handle,
4272
0
                buffer,
4273
0
                buffer_size,
4274
0
                offset,
4275
0
                0,
4276
0
                error );
4277
4278
0
  if( read_count < 0 )
4279
0
  {
4280
0
    libcerror_error_set(
4281
0
     error,
4282
0
     LIBCERROR_ERROR_DOMAIN_IO,
4283
0
     LIBCERROR_IO_ERROR_READ_FAILED,
4284
0
     "%s: unable to read from data block stream.",
4285
0
     function );
4286
4287
0
    read_count = -1;
4288
0
  }
4289
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
4290
0
  if( libcthreads_read_write_lock_release_for_write(
4291
0
       internal_file_entry->read_write_lock,
4292
0
       error ) != 1 )
4293
0
  {
4294
0
    libcerror_error_set(
4295
0
     error,
4296
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4297
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4298
0
     "%s: unable to release read/write lock for writing.",
4299
0
     function );
4300
4301
0
    return( -1 );
4302
0
  }
4303
0
#endif
4304
0
  return( read_count );
4305
0
}
4306
4307
/* Seeks a certain offset in the data
4308
 * Returns the offset if seek is successful or -1 on error
4309
 */
4310
off64_t libfsext_file_entry_seek_offset(
4311
         libfsext_file_entry_t *file_entry,
4312
         off64_t offset,
4313
         int whence,
4314
         libcerror_error_t **error )
4315
0
{
4316
0
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
4317
0
  static char *function                                = "libfsext_file_entry_seek_offset";
4318
4319
0
  if( file_entry == NULL )
4320
0
  {
4321
0
    libcerror_error_set(
4322
0
     error,
4323
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4324
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4325
0
     "%s: invalid file entry.",
4326
0
     function );
4327
4328
0
    return( -1 );
4329
0
  }
4330
0
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
4331
4332
0
  if( internal_file_entry->inode == NULL )
4333
0
  {
4334
0
    libcerror_error_set(
4335
0
     error,
4336
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4337
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4338
0
     "%s: invalid file entry - missing inode.",
4339
0
     function );
4340
4341
0
    return( -1 );
4342
0
  }
4343
0
  if( ( internal_file_entry->inode->file_mode & 0xf000 ) != LIBFSEXT_FILE_TYPE_REGULAR_FILE )
4344
0
  {
4345
0
    libcerror_error_set(
4346
0
     error,
4347
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4348
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4349
0
     "%s: invalid file entry - invalid inode - unsupported file mode not a regular file.",
4350
0
     function );
4351
4352
0
    return( -1 );
4353
0
  }
4354
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
4355
0
  if( libcthreads_read_write_lock_grab_for_write(
4356
0
       internal_file_entry->read_write_lock,
4357
0
       error ) != 1 )
4358
0
  {
4359
0
    libcerror_error_set(
4360
0
     error,
4361
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4362
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4363
0
     "%s: unable to grab read/write lock for writing.",
4364
0
     function );
4365
4366
0
    return( -1 );
4367
0
  }
4368
0
#endif
4369
0
  offset = libfdata_stream_seek_offset(
4370
0
            internal_file_entry->data_block_stream,
4371
0
            offset,
4372
0
            whence,
4373
0
            error );
4374
4375
0
  if( offset == -1 )
4376
0
  {
4377
0
    libcerror_error_set(
4378
0
     error,
4379
0
     LIBCERROR_ERROR_DOMAIN_IO,
4380
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
4381
0
     "%s: unable to seek offset in data block stream.",
4382
0
     function );
4383
4384
0
    offset = -1;
4385
0
  }
4386
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
4387
0
  if( libcthreads_read_write_lock_release_for_write(
4388
0
       internal_file_entry->read_write_lock,
4389
0
       error ) != 1 )
4390
0
  {
4391
0
    libcerror_error_set(
4392
0
     error,
4393
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4394
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4395
0
     "%s: unable to release read/write lock for writing.",
4396
0
     function );
4397
4398
0
    return( -1 );
4399
0
  }
4400
0
#endif
4401
0
  return( offset );
4402
0
}
4403
4404
/* Retrieves the current offset of the data
4405
 * Returns the offset if successful or -1 on error
4406
 */
4407
int libfsext_file_entry_get_offset(
4408
     libfsext_file_entry_t *file_entry,
4409
     off64_t *offset,
4410
     libcerror_error_t **error )
4411
437
{
4412
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
4413
437
  static char *function                               = "libfsext_file_entry_get_offset";
4414
437
  int result                                          = 1;
4415
4416
437
  if( file_entry == NULL )
4417
0
  {
4418
0
    libcerror_error_set(
4419
0
     error,
4420
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4421
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4422
0
     "%s: invalid file entry.",
4423
0
     function );
4424
4425
0
    return( -1 );
4426
0
  }
4427
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
4428
4429
437
  if( internal_file_entry->inode == NULL )
4430
0
  {
4431
0
    libcerror_error_set(
4432
0
     error,
4433
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4434
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4435
0
     "%s: invalid file entry - missing inode.",
4436
0
     function );
4437
4438
0
    return( -1 );
4439
0
  }
4440
437
  if( ( internal_file_entry->inode->file_mode & 0xf000 ) != LIBFSEXT_FILE_TYPE_REGULAR_FILE )
4441
435
  {
4442
435
    libcerror_error_set(
4443
435
     error,
4444
435
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4445
435
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4446
435
     "%s: invalid file entry - invalid inode - unsupported file mode not a regular file.",
4447
435
     function );
4448
4449
435
    return( -1 );
4450
435
  }
4451
2
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
4452
2
  if( libcthreads_read_write_lock_grab_for_read(
4453
2
       internal_file_entry->read_write_lock,
4454
2
       error ) != 1 )
4455
0
  {
4456
0
    libcerror_error_set(
4457
0
     error,
4458
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4459
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4460
0
     "%s: unable to grab read/write lock for reading.",
4461
0
     function );
4462
4463
0
    return( -1 );
4464
0
  }
4465
2
#endif
4466
2
  if( libfdata_stream_get_offset(
4467
2
       internal_file_entry->data_block_stream,
4468
2
       offset,
4469
2
       error ) != 1 )
4470
0
  {
4471
0
    libcerror_error_set(
4472
0
     error,
4473
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4474
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4475
0
     "%s: unable to retrieve offset from data block stream.",
4476
0
     function );
4477
4478
0
    result = -1;
4479
0
  }
4480
2
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
4481
2
  if( libcthreads_read_write_lock_release_for_read(
4482
2
       internal_file_entry->read_write_lock,
4483
2
       error ) != 1 )
4484
0
  {
4485
0
    libcerror_error_set(
4486
0
     error,
4487
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4488
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4489
0
     "%s: unable to release read/write lock for reading.",
4490
0
     function );
4491
4492
0
    return( -1 );
4493
0
  }
4494
2
#endif
4495
2
  return( result );
4496
2
}
4497
4498
/* Retrieves the size of the data
4499
 * Returns 1 if successful or -1 on error
4500
 */
4501
int libfsext_file_entry_get_size(
4502
     libfsext_file_entry_t *file_entry,
4503
     size64_t *size,
4504
     libcerror_error_t **error )
4505
437
{
4506
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
4507
437
  static char *function                               = "libfsext_file_entry_get_size";
4508
4509
437
  if( file_entry == NULL )
4510
0
  {
4511
0
    libcerror_error_set(
4512
0
     error,
4513
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4514
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4515
0
     "%s: invalid file entry.",
4516
0
     function );
4517
4518
0
    return( -1 );
4519
0
  }
4520
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
4521
4522
437
  if( size == NULL )
4523
0
  {
4524
0
    libcerror_error_set(
4525
0
     error,
4526
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4527
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4528
0
     "%s: invalid size.",
4529
0
     function );
4530
4531
0
    return( -1 );
4532
0
  }
4533
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
4534
437
  if( libcthreads_read_write_lock_grab_for_read(
4535
437
       internal_file_entry->read_write_lock,
4536
437
       error ) != 1 )
4537
0
  {
4538
0
    libcerror_error_set(
4539
0
     error,
4540
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4541
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4542
0
     "%s: unable to grab read/write lock for reading.",
4543
0
     function );
4544
4545
0
    return( -1 );
4546
0
  }
4547
437
#endif
4548
437
  *size = internal_file_entry->data_size;
4549
4550
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
4551
437
  if( libcthreads_read_write_lock_release_for_read(
4552
437
       internal_file_entry->read_write_lock,
4553
437
       error ) != 1 )
4554
0
  {
4555
0
    libcerror_error_set(
4556
0
     error,
4557
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4558
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4559
0
     "%s: unable to release read/write lock for reading.",
4560
0
     function );
4561
4562
0
    return( -1 );
4563
0
  }
4564
437
#endif
4565
437
  return( 1 );
4566
437
}
4567
4568
/* Retrieves the number of extents of the data
4569
 * Returns 1 if successful or -1 on error
4570
 */
4571
int libfsext_file_entry_get_number_of_extents(
4572
     libfsext_file_entry_t *file_entry,
4573
     int *number_of_extents,
4574
     libcerror_error_t **error )
4575
437
{
4576
437
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
4577
437
  static char *function                               = "libfsext_file_entry_get_number_of_extents";
4578
437
  int result                                           = 1;
4579
4580
437
  if( file_entry == NULL )
4581
0
  {
4582
0
    libcerror_error_set(
4583
0
     error,
4584
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4585
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4586
0
     "%s: invalid file entry.",
4587
0
     function );
4588
4589
0
    return( -1 );
4590
0
  }
4591
437
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
4592
4593
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
4594
437
  if( libcthreads_read_write_lock_grab_for_read(
4595
437
       internal_file_entry->read_write_lock,
4596
437
       error ) != 1 )
4597
0
  {
4598
0
    libcerror_error_set(
4599
0
     error,
4600
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4601
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4602
0
     "%s: unable to grab read/write lock for reading.",
4603
0
     function );
4604
4605
0
    return( -1 );
4606
0
  }
4607
437
#endif
4608
437
  if( libfsext_inode_get_number_of_extents(
4609
437
       internal_file_entry->inode,
4610
437
       number_of_extents,
4611
437
       error ) != 1 )
4612
0
  {
4613
0
    libcerror_error_set(
4614
0
     error,
4615
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4616
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4617
0
     "%s: unable to retrieve number of extents from inode.",
4618
0
     function );
4619
4620
0
    result = -1;
4621
0
  }
4622
437
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
4623
437
  if( libcthreads_read_write_lock_release_for_read(
4624
437
       internal_file_entry->read_write_lock,
4625
437
       error ) != 1 )
4626
0
  {
4627
0
    libcerror_error_set(
4628
0
     error,
4629
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4630
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4631
0
     "%s: unable to release read/write lock for reading.",
4632
0
     function );
4633
4634
0
    return( -1 );
4635
0
  }
4636
437
#endif
4637
437
  return( result );
4638
437
}
4639
4640
/* Retrieves a specific extent of the data
4641
 * Returns 1 if successful or -1 on error
4642
 */
4643
int libfsext_file_entry_get_extent_by_index(
4644
     libfsext_file_entry_t *file_entry,
4645
     int extent_index,
4646
     off64_t *extent_offset,
4647
     size64_t *extent_size,
4648
     uint32_t *extent_flags,
4649
     libcerror_error_t **error )
4650
0
{
4651
0
  libfsext_extent_t *extent                           = NULL;
4652
0
  libfsext_internal_file_entry_t *internal_file_entry = NULL;
4653
0
  static char *function                               = "libfsext_file_entry_get_extent_by_index";
4654
0
  int result                                          = 1;
4655
4656
0
  if( file_entry == NULL )
4657
0
  {
4658
0
    libcerror_error_set(
4659
0
     error,
4660
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4661
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4662
0
     "%s: invalid file entry.",
4663
0
     function );
4664
4665
0
    return( -1 );
4666
0
  }
4667
0
  internal_file_entry = (libfsext_internal_file_entry_t *) file_entry;
4668
4669
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
4670
0
  if( libcthreads_read_write_lock_grab_for_read(
4671
0
       internal_file_entry->read_write_lock,
4672
0
       error ) != 1 )
4673
0
  {
4674
0
    libcerror_error_set(
4675
0
     error,
4676
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4677
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4678
0
     "%s: unable to grab read/write lock for reading.",
4679
0
     function );
4680
4681
0
    return( -1 );
4682
0
  }
4683
0
#endif
4684
0
  if( libfsext_inode_get_extent_by_index(
4685
0
       internal_file_entry->inode,
4686
0
       extent_index,
4687
0
       &extent,
4688
0
       error ) != 1 )
4689
0
  {
4690
0
    libcerror_error_set(
4691
0
     error,
4692
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4693
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4694
0
     "%s: unable to retrieve extent: %d from inode.",
4695
0
     function,
4696
0
     extent_index );
4697
4698
0
    result = -1;
4699
0
  }
4700
0
  if( result == 1 )
4701
0
  {
4702
0
    if( libfsext_extent_get_values(
4703
0
         extent,
4704
0
         internal_file_entry->io_handle,
4705
0
         extent_offset,
4706
0
         extent_size,
4707
0
         extent_flags,
4708
0
         error ) != 1 )
4709
0
    {
4710
0
      libcerror_error_set(
4711
0
       error,
4712
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4713
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4714
0
       "%s: unable to retrieve extent: %d values.",
4715
0
       function,
4716
0
       extent_index );
4717
4718
0
      result = -1;
4719
0
    }
4720
0
  }
4721
0
#if defined( HAVE_LIBFSEXT_MULTI_THREAD_SUPPORT )
4722
0
  if( libcthreads_read_write_lock_release_for_read(
4723
0
       internal_file_entry->read_write_lock,
4724
0
       error ) != 1 )
4725
0
  {
4726
0
    libcerror_error_set(
4727
0
     error,
4728
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4729
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
4730
0
     "%s: unable to release read/write lock for reading.",
4731
0
     function );
4732
4733
0
    return( -1 );
4734
0
  }
4735
0
#endif
4736
0
  return( result );
4737
0
}
4738