Coverage Report

Created: 2025-10-14 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libfshfs/libfshfs/libfshfs_file_system.c
Line
Count
Source
1
/*
2
 * File system functions
3
 *
4
 * Copyright (C) 2009-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 <narrow_string.h>
25
#include <types.h>
26
27
#include "libfshfs_attribute_record.h"
28
#include "libfshfs_attributes_btree_file.h"
29
#include "libfshfs_btree_file.h"
30
#include "libfshfs_btree_node_cache.h"
31
#include "libfshfs_catalog_btree_file.h"
32
#include "libfshfs_definitions.h"
33
#include "libfshfs_directory_entry.h"
34
#include "libfshfs_extent.h"
35
#include "libfshfs_extents_btree_file.h"
36
#include "libfshfs_file_system.h"
37
#include "libfshfs_fork_descriptor.h"
38
#include "libfshfs_io_handle.h"
39
#include "libfshfs_libbfio.h"
40
#include "libfshfs_libcerror.h"
41
#include "libfshfs_libcthreads.h"
42
#include "libfshfs_libuna.h"
43
#include "libfshfs_name.h"
44
45
/* Creates a file system
46
 * Make sure the value file_system is referencing, is set to NULL
47
 * Returns 1 if successful or -1 on error
48
 */
49
int libfshfs_file_system_initialize(
50
     libfshfs_file_system_t **file_system,
51
     uint8_t use_case_folding,
52
     libcerror_error_t **error )
53
4.41k
{
54
4.41k
  static char *function = "libfshfs_file_system_initialize";
55
56
4.41k
  if( file_system == NULL )
57
0
  {
58
0
    libcerror_error_set(
59
0
     error,
60
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
61
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
62
0
     "%s: invalid file system.",
63
0
     function );
64
65
0
    return( -1 );
66
0
  }
67
4.41k
  if( *file_system != NULL )
68
0
  {
69
0
    libcerror_error_set(
70
0
     error,
71
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
72
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
73
0
     "%s: invalid file system value already set.",
74
0
     function );
75
76
0
    return( -1 );
77
0
  }
78
4.41k
  *file_system = memory_allocate_structure(
79
4.41k
                  libfshfs_file_system_t );
80
81
4.41k
  if( *file_system == NULL )
82
0
  {
83
0
    libcerror_error_set(
84
0
     error,
85
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
86
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
87
0
     "%s: unable to create file system.",
88
0
     function );
89
90
0
    goto on_error;
91
0
  }
92
4.41k
  if( memory_set(
93
4.41k
       *file_system,
94
4.41k
       0,
95
4.41k
       sizeof( libfshfs_file_system_t ) ) == NULL )
96
0
  {
97
0
    libcerror_error_set(
98
0
     error,
99
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
100
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
101
0
     "%s: unable to clear file system.",
102
0
     function );
103
104
0
    memory_free(
105
0
     *file_system );
106
107
0
    *file_system = NULL;
108
109
0
    return( -1 );
110
0
  }
111
4.41k
#if defined( HAVE_LIBFSHFS_MULTI_THREAD_SUPPORT )
112
4.41k
  if( libcthreads_read_write_lock_initialize(
113
4.41k
       &( ( *file_system )->read_write_lock ),
114
4.41k
       error ) != 1 )
115
0
  {
116
0
    libcerror_error_set(
117
0
     error,
118
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
119
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
120
0
     "%s: unable to initialize read/write lock.",
121
0
     function );
122
123
0
    goto on_error;
124
0
  }
125
4.41k
#endif
126
4.41k
  ( *file_system )->use_case_folding = use_case_folding;
127
128
4.41k
  return( 1 );
129
130
0
on_error:
131
0
  if( *file_system != NULL )
132
0
  {
133
0
    memory_free(
134
0
     *file_system );
135
136
0
    *file_system = NULL;
137
0
  }
138
0
  return( -1 );
139
4.41k
}
140
141
/* Frees a file system
142
 * Returns 1 if successful or -1 on error
143
 */
144
int libfshfs_file_system_free(
145
     libfshfs_file_system_t **file_system,
146
     libcerror_error_t **error )
147
4.41k
{
148
4.41k
  static char *function = "libfshfs_file_system_free";
149
4.41k
  int result            = 1;
150
151
4.41k
  if( file_system == NULL )
152
0
  {
153
0
    libcerror_error_set(
154
0
     error,
155
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
156
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
157
0
     "%s: invalid file system.",
158
0
     function );
159
160
0
    return( -1 );
161
0
  }
162
4.41k
  if( *file_system != NULL )
163
4.41k
  {
164
4.41k
#if defined( HAVE_LIBFSHFS_MULTI_THREAD_SUPPORT )
165
4.41k
    if( libcthreads_read_write_lock_free(
166
4.41k
         &( ( *file_system )->read_write_lock ),
167
4.41k
         error ) != 1 )
168
0
    {
169
0
      libcerror_error_set(
170
0
       error,
171
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
172
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
173
0
       "%s: unable to free read/write lock.",
174
0
       function );
175
176
0
      result = -1;
177
0
    }
178
4.41k
#endif
179
4.41k
    if( ( *file_system )->extents_btree_node_cache != NULL )
180
4.21k
    {
181
4.21k
      if( libfshfs_btree_node_cache_free(
182
4.21k
           &( ( *file_system )->extents_btree_node_cache ),
183
4.21k
           error ) != 1 )
184
0
      {
185
0
        libcerror_error_set(
186
0
         error,
187
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
188
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
189
0
         "%s: unable to free extents B-tree node cache.",
190
0
         function );
191
192
0
        result = -1;
193
0
      }
194
4.21k
    }
195
4.41k
    if( ( *file_system )->extents_btree_file != NULL )
196
4.21k
    {
197
4.21k
      if( libfshfs_btree_file_free(
198
4.21k
           &( ( *file_system )->extents_btree_file ),
199
4.21k
           error ) != 1 )
200
0
      {
201
0
        libcerror_error_set(
202
0
         error,
203
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
204
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
205
0
         "%s: unable to free extents B-tree file.",
206
0
         function );
207
208
0
        result = -1;
209
0
      }
210
4.21k
    }
211
4.41k
    if( ( *file_system )->indirect_node_catalog_btree_node_cache != NULL )
212
3.48k
    {
213
3.48k
      if( libfshfs_btree_node_cache_free(
214
3.48k
           &( ( *file_system )->indirect_node_catalog_btree_node_cache ),
215
3.48k
           error ) != 1 )
216
0
      {
217
0
        libcerror_error_set(
218
0
         error,
219
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
220
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
221
0
         "%s: unable to free indirect node catalog B-tree node cache.",
222
0
         function );
223
224
0
        result = -1;
225
0
      }
226
3.48k
    }
227
4.41k
    if( ( *file_system )->catalog_btree_node_cache != NULL )
228
3.48k
    {
229
3.48k
      if( libfshfs_btree_node_cache_free(
230
3.48k
           &( ( *file_system )->catalog_btree_node_cache ),
231
3.48k
           error ) != 1 )
232
0
      {
233
0
        libcerror_error_set(
234
0
         error,
235
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
236
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
237
0
         "%s: unable to free catalog B-tree node cache.",
238
0
         function );
239
240
0
        result = -1;
241
0
      }
242
3.48k
    }
243
4.41k
    if( ( *file_system )->catalog_btree_file != NULL )
244
3.48k
    {
245
3.48k
      if( libfshfs_btree_file_free(
246
3.48k
           &( ( *file_system )->catalog_btree_file ),
247
3.48k
           error ) != 1 )
248
0
      {
249
0
        libcerror_error_set(
250
0
         error,
251
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
252
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
253
0
         "%s: unable to free catalog B-tree file.",
254
0
         function );
255
256
0
        result = -1;
257
0
      }
258
3.48k
    }
259
4.41k
    if( ( *file_system )->attributes_btree_node_cache != NULL )
260
3.30k
    {
261
3.30k
      if( libfshfs_btree_node_cache_free(
262
3.30k
           &( ( *file_system )->attributes_btree_node_cache ),
263
3.30k
           error ) != 1 )
264
0
      {
265
0
        libcerror_error_set(
266
0
         error,
267
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
268
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
269
0
         "%s: unable to free attributes B-tree node cache.",
270
0
         function );
271
272
0
        result = -1;
273
0
      }
274
3.30k
    }
275
4.41k
    if( ( *file_system )->attributes_btree_file != NULL )
276
3.30k
    {
277
3.30k
      if( libfshfs_btree_file_free(
278
3.30k
           &( ( *file_system )->attributes_btree_file ),
279
3.30k
           error ) != 1 )
280
0
      {
281
0
        libcerror_error_set(
282
0
         error,
283
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
284
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
285
0
         "%s: unable to free attributes B-tree file.",
286
0
         function );
287
288
0
        result = -1;
289
0
      }
290
3.30k
    }
291
4.41k
    memory_free(
292
4.41k
     *file_system );
293
294
4.41k
    *file_system = NULL;
295
4.41k
  }
296
4.41k
  return( result );
297
4.41k
}
298
299
/* Reads the attributes B-tree file
300
 * Returns 1 if successful or -1 on error
301
 */
302
int libfshfs_file_system_read_attributes_file(
303
     libfshfs_file_system_t *file_system,
304
     libfshfs_io_handle_t *io_handle,
305
     libbfio_handle_t *file_io_handle,
306
     libfshfs_fork_descriptor_t *fork_descriptor,
307
     libcerror_error_t **error )
308
3.48k
{
309
3.48k
  static char *function = "libfshfs_file_system_read_attributes_file";
310
3.48k
  int result            = 0;
311
312
3.48k
  if( file_system == NULL )
313
0
  {
314
0
    libcerror_error_set(
315
0
     error,
316
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
317
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
318
0
     "%s: invalid file system.",
319
0
     function );
320
321
0
    return( -1 );
322
0
  }
323
3.48k
  if( file_system->attributes_btree_file != NULL )
324
0
  {
325
0
    libcerror_error_set(
326
0
     error,
327
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
328
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
329
0
     "%s: invalid file system - attributes B-tree file value already set.",
330
0
     function );
331
332
0
    return( -1 );
333
0
  }
334
3.48k
  if( fork_descriptor == NULL )
335
0
  {
336
0
    libcerror_error_set(
337
0
     error,
338
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
339
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
340
0
     "%s: invalid fork descriptor.",
341
0
     function );
342
343
0
    return( -1 );
344
0
  }
345
3.48k
  if( libfshfs_btree_file_initialize(
346
3.48k
       &( file_system->attributes_btree_file ),
347
3.48k
       error ) != 1 )
348
0
  {
349
0
    libcerror_error_set(
350
0
     error,
351
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
352
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
353
0
     "%s: unable to create attributes B-tree file.",
354
0
     function );
355
356
0
    goto on_error;
357
0
  }
358
3.48k
  if( libfshfs_fork_descriptor_get_extents(
359
3.48k
       fork_descriptor,
360
3.48k
       file_system->attributes_btree_file->extents,
361
3.48k
       error ) != 1 )
362
0
  {
363
0
    libcerror_error_set(
364
0
     error,
365
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
366
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
367
0
     "%s: unable to retrieve extents of attributes B-tree file.",
368
0
     function );
369
370
0
    goto on_error;
371
0
  }
372
3.48k
  result = libfshfs_fork_descriptor_has_extents_overflow(
373
3.48k
            fork_descriptor,
374
3.48k
            error );
375
376
3.48k
  if( result == -1 )
377
0
  {
378
0
    libcerror_error_set(
379
0
     error,
380
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
381
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
382
0
     "%s: unable to determine if fork descriptor has extents overflow.",
383
0
     function );
384
385
0
    goto on_error;
386
0
  }
387
3.48k
  else if( result != 0 )
388
696
  {
389
696
    if( libfshfs_extents_btree_file_get_extents(
390
696
         file_system->extents_btree_file,
391
696
         file_io_handle,
392
696
         file_system->extents_btree_node_cache,
393
696
         LIBFSHFS_ATTRIBUTES_FILE_IDENTIFIER,
394
696
         LIBFSHFS_FORK_TYPE_DATA,
395
696
         file_system->attributes_btree_file->extents,
396
696
         error ) != 1 )
397
92
    {
398
92
      libcerror_error_set(
399
92
       error,
400
92
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
401
92
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
402
92
       "%s: unable to retrieve extents for attributes B-tree file entry: %" PRIu32 " from extents (overflow) B-tree file.",
403
92
       function,
404
92
       LIBFSHFS_ATTRIBUTES_FILE_IDENTIFIER );
405
406
92
      goto on_error;
407
92
    }
408
696
  }
409
3.39k
  file_system->attributes_btree_file->size = fork_descriptor->size;
410
411
3.39k
  if( libfshfs_btree_file_read_file_io_handle(
412
3.39k
       file_system->attributes_btree_file,
413
3.39k
       io_handle,
414
3.39k
       file_io_handle,
415
3.39k
       error ) != 1 )
416
90
  {
417
90
    libcerror_error_set(
418
90
     error,
419
90
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
420
90
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
421
90
     "%s: unable to read attributes B-tree file.",
422
90
     function );
423
424
90
    goto on_error;
425
90
  }
426
3.30k
  if( libfshfs_btree_node_cache_initialize(
427
3.30k
       &( file_system->attributes_btree_node_cache ),
428
3.30k
       error ) != 1 )
429
0
  {
430
0
    libcerror_error_set(
431
0
     error,
432
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
433
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
434
0
     "%s: unable to create attributes B-tree node cache.",
435
0
     function );
436
437
0
    goto on_error;
438
0
  }
439
3.30k
  return( 1 );
440
441
182
on_error:
442
182
  if( file_system->attributes_btree_file != NULL )
443
182
  {
444
182
    libfshfs_btree_file_free(
445
182
     &( file_system->attributes_btree_file ),
446
182
     NULL );
447
182
  }
448
182
  return( -1 );
449
3.30k
}
450
451
/* Reads the catalog B-tree file
452
 * Returns 1 if successful or -1 on error
453
 */
454
int libfshfs_file_system_read_catalog_file(
455
     libfshfs_file_system_t *file_system,
456
     libfshfs_io_handle_t *io_handle,
457
     libbfio_handle_t *file_io_handle,
458
     libfshfs_fork_descriptor_t *fork_descriptor,
459
     libcerror_error_t **error )
460
4.21k
{
461
4.21k
  static char *function = "libfshfs_file_system_read_catalog_file";
462
4.21k
  int result            = 0;
463
464
4.21k
  if( file_system == NULL )
465
0
  {
466
0
    libcerror_error_set(
467
0
     error,
468
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
469
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
470
0
     "%s: invalid file system.",
471
0
     function );
472
473
0
    return( -1 );
474
0
  }
475
4.21k
  if( file_system->catalog_btree_file != NULL )
476
0
  {
477
0
    libcerror_error_set(
478
0
     error,
479
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
480
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
481
0
     "%s: invalid file system - catalog B-tree file value already set.",
482
0
     function );
483
484
0
    return( -1 );
485
0
  }
486
4.21k
  if( fork_descriptor == NULL )
487
0
  {
488
0
    libcerror_error_set(
489
0
     error,
490
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
491
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
492
0
     "%s: invalid fork descriptor.",
493
0
     function );
494
495
0
    return( -1 );
496
0
  }
497
4.21k
  if( libfshfs_btree_file_initialize(
498
4.21k
       &( file_system->catalog_btree_file ),
499
4.21k
       error ) != 1 )
500
0
  {
501
0
    libcerror_error_set(
502
0
     error,
503
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
504
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
505
0
     "%s: unable to create catalog B-tree file.",
506
0
     function );
507
508
0
    goto on_error;
509
0
  }
510
4.21k
  if( libfshfs_fork_descriptor_get_extents(
511
4.21k
       fork_descriptor,
512
4.21k
       file_system->catalog_btree_file->extents,
513
4.21k
       error ) != 1 )
514
0
  {
515
0
    libcerror_error_set(
516
0
     error,
517
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
518
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
519
0
     "%s: unable to retrieve extents of catalog B-tree file.",
520
0
     function );
521
522
0
    goto on_error;
523
0
  }
524
4.21k
  result = libfshfs_fork_descriptor_has_extents_overflow(
525
4.21k
            fork_descriptor,
526
4.21k
            error );
527
528
4.21k
  if( result == -1 )
529
0
  {
530
0
    libcerror_error_set(
531
0
     error,
532
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
533
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
534
0
     "%s: unable to determine if fork descriptor has extents overflow.",
535
0
     function );
536
537
0
    goto on_error;
538
0
  }
539
4.21k
  else if( result != 0 )
540
1.50k
  {
541
1.50k
    if( libfshfs_extents_btree_file_get_extents(
542
1.50k
         file_system->extents_btree_file,
543
1.50k
         file_io_handle,
544
1.50k
         file_system->extents_btree_node_cache,
545
1.50k
         LIBFSHFS_CATALOG_FILE_IDENTIFIER,
546
1.50k
         LIBFSHFS_FORK_TYPE_DATA,
547
1.50k
         file_system->catalog_btree_file->extents,
548
1.50k
         error ) != 1 )
549
587
    {
550
587
      libcerror_error_set(
551
587
       error,
552
587
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
553
587
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
554
587
       "%s: unable to retrieve extents for catalog B-tree file entry: %" PRIu32 " from extents (overflow) B-tree file.",
555
587
       function,
556
587
       LIBFSHFS_CATALOG_FILE_IDENTIFIER );
557
558
587
      goto on_error;
559
587
    }
560
1.50k
  }
561
3.63k
  file_system->catalog_btree_file->size = fork_descriptor->size;
562
563
3.63k
  if( libfshfs_btree_file_read_file_io_handle(
564
3.63k
       file_system->catalog_btree_file,
565
3.63k
       io_handle,
566
3.63k
       file_io_handle,
567
3.63k
       error ) != 1 )
568
144
  {
569
144
    libcerror_error_set(
570
144
     error,
571
144
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
572
144
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
573
144
     "%s: unable to read catalog B-tree file.",
574
144
     function );
575
576
144
    goto on_error;
577
144
  }
578
3.48k
  if( libfshfs_btree_node_cache_initialize(
579
3.48k
       &( file_system->catalog_btree_node_cache ),
580
3.48k
       error ) != 1 )
581
0
  {
582
0
    libcerror_error_set(
583
0
     error,
584
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
585
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
586
0
     "%s: unable to create catalog B-tree node cache.",
587
0
     function );
588
589
0
    goto on_error;
590
0
  }
591
3.48k
  if( libfshfs_btree_node_cache_initialize(
592
3.48k
       &( file_system->indirect_node_catalog_btree_node_cache ),
593
3.48k
       error ) != 1 )
594
0
  {
595
0
    libcerror_error_set(
596
0
     error,
597
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
598
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
599
0
     "%s: unable to create indirect node catalog B-tree node cache.",
600
0
     function );
601
602
0
    goto on_error;
603
0
  }
604
3.48k
  return( 1 );
605
606
731
on_error:
607
731
  if( file_system->catalog_btree_node_cache != NULL )
608
0
  {
609
0
    libfshfs_btree_node_cache_free(
610
0
     &( file_system->catalog_btree_node_cache ),
611
0
     NULL );
612
0
  }
613
731
  if( file_system->catalog_btree_file != NULL )
614
731
  {
615
731
    libfshfs_btree_file_free(
616
731
     &( file_system->catalog_btree_file ),
617
731
     NULL );
618
731
  }
619
731
  return( -1 );
620
3.48k
}
621
622
/* Reads the extents B-tree file
623
 * Returns 1 if successful or -1 on error
624
 */
625
int libfshfs_file_system_read_extents_file(
626
     libfshfs_file_system_t *file_system,
627
     libfshfs_io_handle_t *io_handle,
628
     libbfio_handle_t *file_io_handle,
629
     libfshfs_fork_descriptor_t *fork_descriptor,
630
     libcerror_error_t **error )
631
4.41k
{
632
4.41k
  static char *function = "libfshfs_file_system_read_extents_file";
633
4.41k
  int result            = 0;
634
635
4.41k
  if( file_system == NULL )
636
0
  {
637
0
    libcerror_error_set(
638
0
     error,
639
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
640
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
641
0
     "%s: invalid file system.",
642
0
     function );
643
644
0
    return( -1 );
645
0
  }
646
4.41k
  if( file_system->extents_btree_file != NULL )
647
0
  {
648
0
    libcerror_error_set(
649
0
     error,
650
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
651
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
652
0
     "%s: invalid file system - extents B-tree file value already set.",
653
0
     function );
654
655
0
    return( -1 );
656
0
  }
657
4.41k
  if( fork_descriptor == NULL )
658
0
  {
659
0
    libcerror_error_set(
660
0
     error,
661
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
662
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
663
0
     "%s: invalid fork descriptor.",
664
0
     function );
665
666
0
    return( -1 );
667
0
  }
668
4.41k
  result = libfshfs_fork_descriptor_has_extents_overflow(
669
4.41k
            fork_descriptor,
670
4.41k
            error );
671
672
4.41k
  if( result == -1 )
673
0
  {
674
0
    libcerror_error_set(
675
0
     error,
676
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
677
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
678
0
     "%s: unable to determine if fork descriptor has extents overflow.",
679
0
     function );
680
681
0
    goto on_error;
682
0
  }
683
4.41k
  else if( result != 0 )
684
5
  {
685
5
    libcerror_error_set(
686
5
     error,
687
5
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
688
5
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
689
5
     "%s: unsupported fork descriptor has extents overflow.",
690
5
     function );
691
692
5
    goto on_error;
693
5
  }
694
4.40k
  if( libfshfs_btree_file_initialize(
695
4.40k
       &( file_system->extents_btree_file ),
696
4.40k
       error ) != 1 )
697
0
  {
698
0
    libcerror_error_set(
699
0
     error,
700
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
701
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
702
0
     "%s: unable to create extents B-tree file.",
703
0
     function );
704
705
0
    goto on_error;
706
0
  }
707
4.40k
  if( libfshfs_fork_descriptor_get_extents(
708
4.40k
       fork_descriptor,
709
4.40k
       file_system->extents_btree_file->extents,
710
4.40k
       error ) != 1 )
711
0
  {
712
0
    libcerror_error_set(
713
0
     error,
714
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
715
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
716
0
     "%s: unable to retrieve extents of extents B-tree file.",
717
0
     function );
718
719
0
    goto on_error;
720
0
  }
721
4.40k
  file_system->extents_btree_file->size = fork_descriptor->size;
722
723
4.40k
  if( libfshfs_btree_file_read_file_io_handle(
724
4.40k
       file_system->extents_btree_file,
725
4.40k
       io_handle,
726
4.40k
       file_io_handle,
727
4.40k
       error ) != 1 )
728
186
  {
729
186
    libcerror_error_set(
730
186
     error,
731
186
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
732
186
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
733
186
     "%s: unable to read extents B-tree file.",
734
186
     function );
735
736
186
    goto on_error;
737
186
  }
738
4.21k
  if( libfshfs_btree_node_cache_initialize(
739
4.21k
       &( file_system->extents_btree_node_cache ),
740
4.21k
       error ) != 1 )
741
0
  {
742
0
    libcerror_error_set(
743
0
     error,
744
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
745
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
746
0
     "%s: unable to create extents B-tree node cache.",
747
0
     function );
748
749
0
    goto on_error;
750
0
  }
751
4.21k
  return( 1 );
752
753
191
on_error:
754
191
  if( file_system->extents_btree_file != NULL )
755
186
  {
756
186
    libfshfs_btree_file_free(
757
186
     &( file_system->extents_btree_file ),
758
186
     NULL );
759
186
  }
760
191
  return( -1 );
761
4.21k
}
762
763
/* Retrieves a directory entry for a specific identifier
764
 * Returns 1 if successful, 0 if not found or -1 on error
765
 */
766
int libfshfs_file_system_get_directory_entry_by_identifier(
767
     libfshfs_file_system_t *file_system,
768
     libfshfs_io_handle_t *io_handle,
769
     libbfio_handle_t *file_io_handle,
770
     uint32_t identifier,
771
     libfshfs_directory_entry_t **directory_entry,
772
     libcerror_error_t **error )
773
3.30k
{
774
3.30k
  static char *function = "libfshfs_file_system_get_directory_entry_by_identifier";
775
3.30k
  int result            = 0;
776
777
3.30k
  if( file_system == NULL )
778
0
  {
779
0
    libcerror_error_set(
780
0
     error,
781
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
782
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
783
0
     "%s: invalid file system.",
784
0
     function );
785
786
0
    return( -1 );
787
0
  }
788
3.30k
  result = libfshfs_catalog_btree_file_get_directory_entry_by_identifier(
789
3.30k
            file_system->catalog_btree_file,
790
3.30k
            io_handle,
791
3.30k
            file_io_handle,
792
3.30k
            file_system->catalog_btree_node_cache,
793
3.30k
            identifier,
794
3.30k
            file_system->use_case_folding,
795
3.30k
            directory_entry,
796
3.30k
            error );
797
798
3.30k
  if( result == -1 )
799
786
  {
800
786
    libcerror_error_set(
801
786
     error,
802
786
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
803
786
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
804
786
     "%s: unable to retrieve directory entry: %" PRIu32 ".",
805
786
     function,
806
786
     identifier );
807
808
786
    return( -1 );
809
786
  }
810
2.52k
  return( result );
811
3.30k
}
812
813
/* Retrieves an indirect node directory entry for a specific identifier
814
 * Returns 1 if successful, 0 if not found or -1 on error
815
 */
816
int libfshfs_file_system_get_indirect_node_directory_entry_by_identifier(
817
     libfshfs_file_system_t *file_system,
818
     libfshfs_io_handle_t *io_handle,
819
     libbfio_handle_t *file_io_handle,
820
     uint32_t identifier,
821
     libfshfs_directory_entry_t **directory_entry,
822
     libcerror_error_t **error )
823
1.98k
{
824
1.98k
  static char *function = "libfshfs_file_system_get_indirect_node_directory_entry_by_identifier";
825
1.98k
  int result            = 0;
826
827
1.98k
  if( file_system == NULL )
828
0
  {
829
0
    libcerror_error_set(
830
0
     error,
831
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
832
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
833
0
     "%s: invalid file system.",
834
0
     function );
835
836
0
    return( -1 );
837
0
  }
838
1.98k
  result = libfshfs_catalog_btree_file_get_directory_entry_by_identifier(
839
1.98k
            file_system->catalog_btree_file,
840
1.98k
            io_handle,
841
1.98k
            file_io_handle,
842
1.98k
            file_system->indirect_node_catalog_btree_node_cache,
843
1.98k
            identifier,
844
1.98k
            file_system->use_case_folding,
845
1.98k
            directory_entry,
846
1.98k
            error );
847
848
1.98k
  if( result == -1 )
849
905
  {
850
905
    libcerror_error_set(
851
905
     error,
852
905
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
853
905
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
854
905
     "%s: unable to retrieve indirect node directory entry: %" PRIu32 ".",
855
905
     function,
856
905
     identifier );
857
858
905
    return( -1 );
859
905
  }
860
1.07k
  return( result );
861
1.98k
}
862
863
/* Retrieves a directory entry for an UTF-8 encoded name
864
 * Returns 1 if successful, 0 if not found or -1 on error
865
 */
866
int libfshfs_file_system_get_directory_entry_by_utf8_name(
867
     libfshfs_file_system_t *file_system,
868
     libfshfs_io_handle_t *io_handle,
869
     libbfio_handle_t *file_io_handle,
870
     uint32_t parent_identifier,
871
     const uint8_t *utf8_string,
872
     size_t utf8_string_length,
873
     libfshfs_directory_entry_t **directory_entry,
874
     libcerror_error_t **error )
875
0
{
876
0
  libfshfs_directory_entry_t *safe_directory_entry = NULL;
877
0
  static char *function                            = "libfshfs_file_system_get_directory_entry_by_utf8_name";
878
0
  uint32_t name_hash                               = 0;
879
0
  int result                                       = 0;
880
881
0
  if( file_system == NULL )
882
0
  {
883
0
    libcerror_error_set(
884
0
     error,
885
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
886
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
887
0
     "%s: invalid file system.",
888
0
     function );
889
890
0
    return( -1 );
891
0
  }
892
0
  if( directory_entry == NULL )
893
0
  {
894
0
    libcerror_error_set(
895
0
     error,
896
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
897
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
898
0
     "%s: invalid directory entry.",
899
0
     function );
900
901
0
    return( -1 );
902
0
  }
903
0
  if( libfshfs_name_calculate_hash_utf8_string(
904
0
       (libuna_utf8_character_t *) utf8_string,
905
0
       utf8_string_length,
906
0
       file_system->use_case_folding,
907
0
       &name_hash,
908
0
       error ) != 1 )
909
0
  {
910
0
    libcerror_error_set(
911
0
     error,
912
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
913
0
     LIBCERROR_RUNTIME_ERROR_GENERIC,
914
0
     "%s: unable to calculate name hash.",
915
0
     function );
916
917
0
    goto on_error;
918
0
  }
919
0
  result = libfshfs_catalog_btree_file_get_directory_entry_by_utf8_name(
920
0
            file_system->catalog_btree_file,
921
0
            io_handle,
922
0
            file_io_handle,
923
0
            file_system->catalog_btree_node_cache,
924
0
            parent_identifier,
925
0
            name_hash,
926
0
            utf8_string,
927
0
            utf8_string_length,
928
0
            file_system->use_case_folding,
929
0
            &safe_directory_entry,
930
0
            error );
931
932
0
  if( result == -1 )
933
0
  {
934
0
    libcerror_error_set(
935
0
     error,
936
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
937
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
938
0
     "%s: unable to retrieve directory entry by UTF-8 name.",
939
0
     function );
940
941
0
    goto on_error;
942
0
  }
943
0
  else if( result != 0 )
944
0
  {
945
0
    *directory_entry = safe_directory_entry;
946
0
  }
947
0
  return( result );
948
949
0
on_error:
950
0
  if( safe_directory_entry != NULL )
951
0
  {
952
0
    libfshfs_directory_entry_free(
953
0
     &safe_directory_entry,
954
0
     NULL );
955
0
  }
956
0
  return( -1 );
957
0
}
958
959
/* Retrieves a directory entry for a specific identifier
960
 * Returns 1 if successful, 0 if not found or -1 on error
961
 */
962
int libfshfs_file_system_get_directory_entry_by_utf8_path(
963
     libfshfs_file_system_t *file_system,
964
     libfshfs_io_handle_t *io_handle,
965
     libbfio_handle_t *file_io_handle,
966
     const uint8_t *utf8_string,
967
     size_t utf8_string_length,
968
     libfshfs_directory_entry_t **directory_entry,
969
     libcerror_error_t **error )
970
977
{
971
977
  libfshfs_directory_entry_t *safe_directory_entry = NULL;
972
977
  static char *function                            = "libfshfs_file_system_get_directory_entry_by_utf8_path";
973
977
  int result                                       = 0;
974
975
977
  if( file_system == NULL )
976
0
  {
977
0
    libcerror_error_set(
978
0
     error,
979
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
980
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
981
0
     "%s: invalid file system.",
982
0
     function );
983
984
0
    return( -1 );
985
0
  }
986
977
  if( directory_entry == NULL )
987
0
  {
988
0
    libcerror_error_set(
989
0
     error,
990
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
991
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
992
0
     "%s: invalid directory entry.",
993
0
     function );
994
995
0
    return( -1 );
996
0
  }
997
977
  result = libfshfs_catalog_btree_file_get_directory_entry_by_utf8_path(
998
977
            file_system->catalog_btree_file,
999
977
            io_handle,
1000
977
            file_io_handle,
1001
977
            file_system->catalog_btree_node_cache,
1002
977
            utf8_string,
1003
977
            utf8_string_length,
1004
977
            file_system->use_case_folding,
1005
977
            &safe_directory_entry,
1006
977
            error );
1007
1008
977
  if( result == -1 )
1009
259
  {
1010
259
    libcerror_error_set(
1011
259
     error,
1012
259
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1013
259
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1014
259
     "%s: unable to retrieve directory entry by UTF-8 path.",
1015
259
     function );
1016
1017
259
    goto on_error;
1018
259
  }
1019
718
  else if( result != 0 )
1020
310
  {
1021
310
    *directory_entry = safe_directory_entry;
1022
310
  }
1023
718
  return( result );
1024
1025
259
on_error:
1026
259
  if( safe_directory_entry != NULL )
1027
0
  {
1028
0
    libfshfs_directory_entry_free(
1029
0
     &safe_directory_entry,
1030
0
     NULL );
1031
0
  }
1032
259
  return( -1 );
1033
977
}
1034
1035
/* Retrieves a directory entry for an UTF-16 encoded name
1036
 * Returns 1 if successful, 0 if not found or -1 on error
1037
 */
1038
int libfshfs_file_system_get_directory_entry_by_utf16_name(
1039
     libfshfs_file_system_t *file_system,
1040
     libfshfs_io_handle_t *io_handle,
1041
     libbfio_handle_t *file_io_handle,
1042
     uint32_t parent_identifier,
1043
     const uint16_t *utf16_string,
1044
     size_t utf16_string_length,
1045
     libfshfs_directory_entry_t **directory_entry,
1046
     libcerror_error_t **error )
1047
0
{
1048
0
  libfshfs_directory_entry_t *safe_directory_entry = NULL;
1049
0
  static char *function                            = "libfshfs_file_system_get_directory_entry_by_utf16_name";
1050
0
  uint32_t name_hash                               = 0;
1051
0
  int result                                       = 0;
1052
1053
0
  if( file_system == NULL )
1054
0
  {
1055
0
    libcerror_error_set(
1056
0
     error,
1057
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1058
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1059
0
     "%s: invalid file system.",
1060
0
     function );
1061
1062
0
    return( -1 );
1063
0
  }
1064
0
  if( directory_entry == NULL )
1065
0
  {
1066
0
    libcerror_error_set(
1067
0
     error,
1068
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1069
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1070
0
     "%s: invalid directory entry.",
1071
0
     function );
1072
1073
0
    return( -1 );
1074
0
  }
1075
0
  if( libfshfs_name_calculate_hash_utf16_string(
1076
0
       (libuna_utf16_character_t *) utf16_string,
1077
0
       utf16_string_length,
1078
0
       file_system->use_case_folding,
1079
0
       &name_hash,
1080
0
       error ) != 1 )
1081
0
  {
1082
0
    libcerror_error_set(
1083
0
     error,
1084
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1085
0
     LIBCERROR_RUNTIME_ERROR_GENERIC,
1086
0
     "%s: unable to calculate name hash.",
1087
0
     function );
1088
1089
0
    goto on_error;
1090
0
  }
1091
0
  result = libfshfs_catalog_btree_file_get_directory_entry_by_utf16_name(
1092
0
            file_system->catalog_btree_file,
1093
0
            io_handle,
1094
0
            file_io_handle,
1095
0
            file_system->catalog_btree_node_cache,
1096
0
            parent_identifier,
1097
0
            name_hash,
1098
0
            utf16_string,
1099
0
            utf16_string_length,
1100
0
            file_system->use_case_folding,
1101
0
            &safe_directory_entry,
1102
0
            error );
1103
1104
0
  if( result == -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 directory entry by UTF-16 name.",
1111
0
     function );
1112
1113
0
    goto on_error;
1114
0
  }
1115
0
  else if( result != 0 )
1116
0
  {
1117
0
    *directory_entry = safe_directory_entry;
1118
0
  }
1119
0
  return( result );
1120
1121
0
on_error:
1122
0
  if( safe_directory_entry != NULL )
1123
0
  {
1124
0
    libfshfs_directory_entry_free(
1125
0
     &safe_directory_entry,
1126
0
     NULL );
1127
0
  }
1128
0
  return( -1 );
1129
0
}
1130
1131
/* Retrieves a directory entry for a specific identifier
1132
 * Returns 1 if successful, 0 if not found or -1 on error
1133
 */
1134
int libfshfs_file_system_get_directory_entry_by_utf16_path(
1135
     libfshfs_file_system_t *file_system,
1136
     libfshfs_io_handle_t *io_handle,
1137
     libbfio_handle_t *file_io_handle,
1138
     const uint16_t *utf16_string,
1139
     size_t utf16_string_length,
1140
     libfshfs_directory_entry_t **directory_entry,
1141
     libcerror_error_t **error )
1142
0
{
1143
0
  libfshfs_directory_entry_t *safe_directory_entry = NULL;
1144
0
  static char *function                            = "libfshfs_file_system_get_directory_entry_by_utf16_path";
1145
0
  int result                                       = 0;
1146
1147
0
  if( file_system == NULL )
1148
0
  {
1149
0
    libcerror_error_set(
1150
0
     error,
1151
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1152
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1153
0
     "%s: invalid file system.",
1154
0
     function );
1155
1156
0
    return( -1 );
1157
0
  }
1158
0
  if( directory_entry == NULL )
1159
0
  {
1160
0
    libcerror_error_set(
1161
0
     error,
1162
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1163
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1164
0
     "%s: invalid directory entry.",
1165
0
     function );
1166
1167
0
    return( -1 );
1168
0
  }
1169
0
  result = libfshfs_catalog_btree_file_get_directory_entry_by_utf16_path(
1170
0
            file_system->catalog_btree_file,
1171
0
            io_handle,
1172
0
            file_io_handle,
1173
0
            file_system->catalog_btree_node_cache,
1174
0
            utf16_string,
1175
0
            utf16_string_length,
1176
0
            file_system->use_case_folding,
1177
0
            &safe_directory_entry,
1178
0
            error );
1179
1180
0
  if( result == -1 )
1181
0
  {
1182
0
    libcerror_error_set(
1183
0
     error,
1184
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1185
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1186
0
     "%s: unable to retrieve directory entry by UTF-16 path.",
1187
0
     function );
1188
1189
0
    goto on_error;
1190
0
  }
1191
0
  else if( result != 0 )
1192
0
  {
1193
0
    *directory_entry = safe_directory_entry;
1194
0
  }
1195
0
  return( result );
1196
1197
0
on_error:
1198
0
  if( safe_directory_entry != NULL )
1199
0
  {
1200
0
    libfshfs_directory_entry_free(
1201
0
     &safe_directory_entry,
1202
0
     NULL );
1203
0
  }
1204
0
  return( -1 );
1205
0
}
1206
1207
/* Retrieves directory entries for a specific parent identifier
1208
 * Returns 1 if successful or -1 on error
1209
 */
1210
int libfshfs_file_system_get_directory_entries(
1211
     libfshfs_file_system_t *file_system,
1212
     libfshfs_io_handle_t *io_handle,
1213
     libbfio_handle_t *file_io_handle,
1214
     uint32_t parent_identifier,
1215
     libcdata_array_t **directory_entries,
1216
     libcerror_error_t **error )
1217
1.11k
{
1218
1.11k
  static char *function = "libfshfs_file_system_get_directory_entries";
1219
1220
1.11k
  if( file_system == NULL )
1221
0
  {
1222
0
    libcerror_error_set(
1223
0
     error,
1224
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1225
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1226
0
     "%s: invalid file system.",
1227
0
     function );
1228
1229
0
    return( -1 );
1230
0
  }
1231
1.11k
  if( directory_entries == NULL )
1232
0
  {
1233
0
    libcerror_error_set(
1234
0
     error,
1235
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1236
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1237
0
     "%s: invalid directory entries.",
1238
0
     function );
1239
1240
0
    return( -1 );
1241
0
  }
1242
1.11k
  if( libcdata_array_initialize(
1243
1.11k
       directory_entries,
1244
1.11k
       0,
1245
1.11k
       error ) != 1 )
1246
0
  {
1247
0
    libcerror_error_set(
1248
0
     error,
1249
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1250
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1251
0
     "%s: unable to create directory entries array.",
1252
0
     function );
1253
1254
0
    goto on_error;
1255
0
  }
1256
1.11k
  if( libfshfs_catalog_btree_file_get_directory_entries(
1257
1.11k
       file_system->catalog_btree_file,
1258
1.11k
       io_handle,
1259
1.11k
       file_io_handle,
1260
1.11k
       file_system->catalog_btree_node_cache,
1261
1.11k
       parent_identifier,
1262
1.11k
       *directory_entries,
1263
1.11k
       error ) != 1 )
1264
78
  {
1265
78
    libcerror_error_set(
1266
78
     error,
1267
78
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1268
78
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1269
78
     "%s: unable to retrieve directory entries for entry: %" PRIu32 " from catalog B-tree file.",
1270
78
     function,
1271
78
     parent_identifier );
1272
1273
78
    goto on_error;
1274
78
  }
1275
1.03k
  return( 1 );
1276
1277
78
on_error:
1278
78
  if( *directory_entries != NULL )
1279
78
  {
1280
78
    libcdata_array_free(
1281
78
     directory_entries,
1282
78
     (int (*)(intptr_t **, libcerror_error_t **)) &libfshfs_directory_entry_free,
1283
78
     NULL );
1284
78
  }
1285
78
  return( -1 );
1286
1.11k
}
1287
1288
/* Retrieves extents for a specific fork descriptor
1289
 * Returns 1 if successful or -1 on error
1290
 */
1291
int libfshfs_file_system_get_extents(
1292
     libfshfs_file_system_t *file_system,
1293
     libbfio_handle_t *file_io_handle,
1294
     uint32_t identifier,
1295
     uint8_t fork_type,
1296
     libfshfs_fork_descriptor_t *fork_descriptor,
1297
     libcdata_array_t **extents,
1298
     libcerror_error_t **error )
1299
781
{
1300
781
  static char *function = "libfshfs_file_system_get_extents";
1301
781
  int result            = 0;
1302
1303
781
  if( file_system == NULL )
1304
0
  {
1305
0
    libcerror_error_set(
1306
0
     error,
1307
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1308
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1309
0
     "%s: invalid file system.",
1310
0
     function );
1311
1312
0
    return( -1 );
1313
0
  }
1314
781
  if( extents == NULL )
1315
0
  {
1316
0
    libcerror_error_set(
1317
0
     error,
1318
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1319
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1320
0
     "%s: invalid extents.",
1321
0
     function );
1322
1323
0
    return( -1 );
1324
0
  }
1325
781
  if( libcdata_array_initialize(
1326
781
       extents,
1327
781
       0,
1328
781
       error ) != 1 )
1329
0
  {
1330
0
    libcerror_error_set(
1331
0
     error,
1332
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1333
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1334
0
     "%s: unable to create extents array.",
1335
0
     function );
1336
1337
0
    goto on_error;
1338
0
  }
1339
781
  if( libfshfs_fork_descriptor_get_extents(
1340
781
       fork_descriptor,
1341
781
       *extents,
1342
781
       error ) != 1 )
1343
0
  {
1344
0
    libcerror_error_set(
1345
0
     error,
1346
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1347
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1348
0
     "%s: unable to retrieve extents for entry: %" PRIu32 " from fork descriptor.",
1349
0
     function,
1350
0
     identifier );
1351
1352
0
    goto on_error;
1353
0
  }
1354
781
  result = libfshfs_fork_descriptor_has_extents_overflow(
1355
781
            fork_descriptor,
1356
781
            error );
1357
1358
781
  if( result == -1 )
1359
0
  {
1360
0
    libcerror_error_set(
1361
0
     error,
1362
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1363
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1364
0
     "%s: unable to determine if fork descriptor has extents overflow.",
1365
0
     function );
1366
1367
0
    goto on_error;
1368
0
  }
1369
781
  else if( result != 0 )
1370
461
  {
1371
461
    if( libfshfs_extents_btree_file_get_extents(
1372
461
         file_system->extents_btree_file,
1373
461
         file_io_handle,
1374
461
         file_system->extents_btree_node_cache,
1375
461
         identifier,
1376
461
         fork_type,
1377
461
         *extents,
1378
461
         error ) != 1 )
1379
406
    {
1380
406
      libcerror_error_set(
1381
406
       error,
1382
406
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1383
406
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1384
406
       "%s: unable to retrieve extents for entry: %" PRIu32 " from extents (overflow) B-tree file.",
1385
406
       function,
1386
406
       identifier );
1387
1388
406
      goto on_error;
1389
406
    }
1390
461
  }
1391
375
  return( 1 );
1392
1393
406
on_error:
1394
406
  if( *extents != NULL )
1395
406
  {
1396
406
    libcdata_array_free(
1397
406
     extents,
1398
406
     (int (*)(intptr_t **, libcerror_error_t **)) &libfshfs_extent_free,
1399
406
     NULL );
1400
406
  }
1401
406
  return( -1 );
1402
781
}
1403
1404
/* Retrieves attributes for a specific parent identifier
1405
 * Returns 1 if successful or -1 on error
1406
 */
1407
int libfshfs_file_system_get_attributes(
1408
     libfshfs_file_system_t *file_system,
1409
     libbfio_handle_t *file_io_handle,
1410
     uint32_t parent_identifier,
1411
     libcdata_array_t **attributes,
1412
     libcerror_error_t **error )
1413
977
{
1414
977
  static char *function = "libfshfs_file_system_get_attributes";
1415
1416
977
  if( file_system == NULL )
1417
0
  {
1418
0
    libcerror_error_set(
1419
0
     error,
1420
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1421
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1422
0
     "%s: invalid file system.",
1423
0
     function );
1424
1425
0
    return( -1 );
1426
0
  }
1427
977
  if( attributes == NULL )
1428
0
  {
1429
0
    libcerror_error_set(
1430
0
     error,
1431
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1432
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1433
0
     "%s: invalid attributes.",
1434
0
     function );
1435
1436
0
    return( -1 );
1437
0
  }
1438
977
  if( libcdata_array_initialize(
1439
977
       attributes,
1440
977
       0,
1441
977
       error ) != 1 )
1442
0
  {
1443
0
    libcerror_error_set(
1444
0
     error,
1445
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1446
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1447
0
     "%s: unable to create attributes array.",
1448
0
     function );
1449
1450
0
    goto on_error;
1451
0
  }
1452
977
  if( file_system->attributes_btree_file != NULL )
1453
977
  {
1454
977
    if( libfshfs_attributes_btree_file_get_attributes(
1455
977
         file_system->attributes_btree_file,
1456
977
         file_io_handle,
1457
977
         file_system->attributes_btree_node_cache,
1458
977
         parent_identifier,
1459
977
         *attributes,
1460
977
         error ) != 1 )
1461
720
    {
1462
720
      libcerror_error_set(
1463
720
       error,
1464
720
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1465
720
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1466
720
       "%s: unable to retrieve attributes for entry: %" PRIu32 " from attributes B-tree file.",
1467
720
       function,
1468
720
       parent_identifier );
1469
1470
720
      goto on_error;
1471
720
    }
1472
977
  }
1473
257
  return( 1 );
1474
1475
720
on_error:
1476
720
  if( *attributes != NULL )
1477
720
  {
1478
720
    libcdata_array_free(
1479
720
     attributes,
1480
720
     (int (*)(intptr_t **, libcerror_error_t **)) &libfshfs_attribute_record_free,
1481
     NULL );
1482
720
  }
1483
720
  return( -1 );
1484
977
}
1485