Coverage Report

Created: 2025-10-14 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libfshfs/libfshfs/libfshfs_volume_header.c
Line
Count
Source
1
/*
2
 * Volume header 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 <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "libfshfs_debug.h"
28
#include "libfshfs_definitions.h"
29
#include "libfshfs_libbfio.h"
30
#include "libfshfs_libcerror.h"
31
#include "libfshfs_libcnotify.h"
32
#include "libfshfs_libfdatetime.h"
33
#include "libfshfs_volume_header.h"
34
35
#include "fshfs_volume_header.h"
36
37
/* Creates a volume header
38
 * Make sure the value volume_header is referencing, is set to NULL
39
 * Returns 1 if successful or -1 on error
40
 */
41
int libfshfs_volume_header_initialize(
42
     libfshfs_volume_header_t **volume_header,
43
     libcerror_error_t **error )
44
4.69k
{
45
4.69k
  static char *function = "libfshfs_volume_header_initialize";
46
47
4.69k
  if( volume_header == NULL )
48
0
  {
49
0
    libcerror_error_set(
50
0
     error,
51
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
52
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
53
0
     "%s: invalid volume header.",
54
0
     function );
55
56
0
    return( -1 );
57
0
  }
58
4.69k
  if( *volume_header != NULL )
59
0
  {
60
0
    libcerror_error_set(
61
0
     error,
62
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
63
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
64
0
     "%s: invalid volume header value already set.",
65
0
     function );
66
67
0
    return( -1 );
68
0
  }
69
4.69k
  *volume_header = memory_allocate_structure(
70
4.69k
                    libfshfs_volume_header_t );
71
72
4.69k
  if( *volume_header == NULL )
73
0
  {
74
0
    libcerror_error_set(
75
0
     error,
76
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
77
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
78
0
     "%s: unable to create volume header.",
79
0
     function );
80
81
0
    goto on_error;
82
0
  }
83
4.69k
  if( memory_set(
84
4.69k
       *volume_header,
85
4.69k
       0,
86
4.69k
       sizeof( libfshfs_volume_header_t ) ) == NULL )
87
0
  {
88
0
    libcerror_error_set(
89
0
     error,
90
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
91
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
92
0
     "%s: unable to clear volume header.",
93
0
     function );
94
95
0
    memory_free(
96
0
     *volume_header );
97
98
0
    *volume_header = NULL;
99
100
0
    return( -1 );
101
0
  }
102
4.69k
  if( libfshfs_fork_descriptor_initialize(
103
4.69k
       &( ( *volume_header )->allocation_file_fork_descriptor ),
104
4.69k
       error ) != 1 )
105
0
  {
106
0
    libcerror_error_set(
107
0
     error,
108
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
109
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
110
0
     "%s: unable to create allocation file fork descriptor.",
111
0
     function );
112
113
0
    goto on_error;
114
0
  }
115
4.69k
  if( libfshfs_fork_descriptor_initialize(
116
4.69k
       &( ( *volume_header )->extents_file_fork_descriptor ),
117
4.69k
       error ) != 1 )
118
0
  {
119
0
    libcerror_error_set(
120
0
     error,
121
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
122
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
123
0
     "%s: unable to create extents file fork descriptor.",
124
0
     function );
125
126
0
    goto on_error;
127
0
  }
128
4.69k
  if( libfshfs_fork_descriptor_initialize(
129
4.69k
       &( ( *volume_header )->catalog_file_fork_descriptor ),
130
4.69k
       error ) != 1 )
131
0
  {
132
0
    libcerror_error_set(
133
0
     error,
134
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
135
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
136
0
     "%s: unable to create catalog file fork descriptor.",
137
0
     function );
138
139
0
    goto on_error;
140
0
  }
141
4.69k
  if( libfshfs_fork_descriptor_initialize(
142
4.69k
       &( ( *volume_header )->attributes_file_fork_descriptor ),
143
4.69k
       error ) != 1 )
144
0
  {
145
0
    libcerror_error_set(
146
0
     error,
147
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
148
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
149
0
     "%s: unable to create attributes file fork descriptor.",
150
0
     function );
151
152
0
    goto on_error;
153
0
  }
154
4.69k
  if( libfshfs_fork_descriptor_initialize(
155
4.69k
       &( ( *volume_header )->startup_file_fork_descriptor ),
156
4.69k
       error ) != 1 )
157
0
  {
158
0
    libcerror_error_set(
159
0
     error,
160
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
161
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
162
0
     "%s: unable to create startup file fork descriptor.",
163
0
     function );
164
165
0
    goto on_error;
166
0
  }
167
4.69k
  return( 1 );
168
169
0
on_error:
170
0
  if( *volume_header != NULL )
171
0
  {
172
0
    if( ( *volume_header )->attributes_file_fork_descriptor != NULL )
173
0
    {
174
0
      libfshfs_fork_descriptor_free(
175
0
       &( ( *volume_header )->attributes_file_fork_descriptor ),
176
0
       NULL );
177
0
    }
178
0
    if( ( *volume_header )->catalog_file_fork_descriptor != NULL )
179
0
    {
180
0
      libfshfs_fork_descriptor_free(
181
0
       &( ( *volume_header )->catalog_file_fork_descriptor ),
182
0
       NULL );
183
0
    }
184
0
    if( ( *volume_header )->extents_file_fork_descriptor != NULL )
185
0
    {
186
0
      libfshfs_fork_descriptor_free(
187
0
       &( ( *volume_header )->extents_file_fork_descriptor ),
188
0
       NULL );
189
0
    }
190
0
    if( ( *volume_header )->allocation_file_fork_descriptor != NULL )
191
0
    {
192
0
      libfshfs_fork_descriptor_free(
193
0
       &( ( *volume_header )->allocation_file_fork_descriptor ),
194
0
       NULL );
195
0
    }
196
0
    memory_free(
197
0
     *volume_header );
198
199
0
    *volume_header = NULL;
200
0
  }
201
0
  return( -1 );
202
4.69k
}
203
204
/* Frees a volume header
205
 * Returns 1 if successful or -1 on error
206
 */
207
int libfshfs_volume_header_free(
208
     libfshfs_volume_header_t **volume_header,
209
     libcerror_error_t **error )
210
4.69k
{
211
4.69k
  static char *function = "libfshfs_volume_header_free";
212
4.69k
  int result            = 1;
213
214
4.69k
  if( volume_header == NULL )
215
0
  {
216
0
    libcerror_error_set(
217
0
     error,
218
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
219
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
220
0
     "%s: invalid volume header.",
221
0
     function );
222
223
0
    return( -1 );
224
0
  }
225
4.69k
  if( *volume_header != NULL )
226
4.69k
  {
227
4.69k
    if( libfshfs_fork_descriptor_free(
228
4.69k
         &( ( *volume_header )->allocation_file_fork_descriptor ),
229
4.69k
         error ) != 1 )
230
0
    {
231
0
      libcerror_error_set(
232
0
       error,
233
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
234
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
235
0
       "%s: unable to free allocation file fork descriptor.",
236
0
       function );
237
238
0
      result = -1;
239
0
    }
240
4.69k
    if( libfshfs_fork_descriptor_free(
241
4.69k
         &( ( *volume_header )->extents_file_fork_descriptor ),
242
4.69k
         error ) != 1 )
243
0
    {
244
0
      libcerror_error_set(
245
0
       error,
246
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
247
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
248
0
       "%s: unable to free extents file fork descriptor.",
249
0
       function );
250
251
0
      result = -1;
252
0
    }
253
4.69k
    if( libfshfs_fork_descriptor_free(
254
4.69k
         &( ( *volume_header )->catalog_file_fork_descriptor ),
255
4.69k
         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 catalog file fork descriptor.",
262
0
       function );
263
264
0
      result = -1;
265
0
    }
266
4.69k
    if( libfshfs_fork_descriptor_free(
267
4.69k
         &( ( *volume_header )->attributes_file_fork_descriptor ),
268
4.69k
         error ) != 1 )
269
0
    {
270
0
      libcerror_error_set(
271
0
       error,
272
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
273
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
274
0
       "%s: unable to free attributes file fork descriptor.",
275
0
       function );
276
277
0
      result = -1;
278
0
    }
279
4.69k
    if( libfshfs_fork_descriptor_free(
280
4.69k
         &( ( *volume_header )->startup_file_fork_descriptor ),
281
4.69k
         error ) != 1 )
282
0
    {
283
0
      libcerror_error_set(
284
0
       error,
285
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
286
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
287
0
       "%s: unable to free startup file fork descriptor.",
288
0
       function );
289
290
0
      result = -1;
291
0
    }
292
4.69k
    memory_free(
293
4.69k
     *volume_header );
294
295
4.69k
    *volume_header = NULL;
296
4.69k
  }
297
4.69k
  return( result );
298
4.69k
}
299
300
/* Reads a volume header
301
 * Returns 1 if successful or -1 on error
302
 */
303
int libfshfs_volume_header_read_data(
304
     libfshfs_volume_header_t *volume_header,
305
     const uint8_t *data,
306
     size_t data_size,
307
     libcerror_error_t **error )
308
4.52k
{
309
4.52k
  static char *function = "libfshfs_volume_header_read_data";
310
311
#if defined( HAVE_DEBUG_OUTPUT )
312
  uint32_t value_32bit  = 0;
313
  uint16_t value_16bit  = 0;
314
#endif
315
316
4.52k
  if( volume_header == NULL )
317
0
  {
318
0
    libcerror_error_set(
319
0
     error,
320
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
321
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
322
0
     "%s: invalid volume header.",
323
0
     function );
324
325
0
    return( -1 );
326
0
  }
327
4.52k
  if( data == NULL )
328
0
  {
329
0
    libcerror_error_set(
330
0
     error,
331
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
332
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
333
0
     "%s: invalid data.",
334
0
     function );
335
336
0
    return( -1 );
337
0
  }
338
4.52k
  if( ( data_size < sizeof( fshfs_volume_header_t ) )
339
4.52k
   || ( data_size > (size_t) SSIZE_MAX ) )
340
0
  {
341
0
    libcerror_error_set(
342
0
     error,
343
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
344
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
345
0
     "%s: invalid data size value out of bounds.",
346
0
     function );
347
348
0
    return( -1 );
349
0
  }
350
#if defined( HAVE_DEBUG_OUTPUT )
351
  if( libcnotify_verbose != 0 )
352
  {
353
    libcnotify_printf(
354
     "%s: volume header data:\n",
355
     function );
356
    libcnotify_print_data(
357
     data,
358
     sizeof( fshfs_volume_header_t ),
359
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
360
  }
361
#endif
362
4.52k
  if( memory_compare(
363
4.52k
       ( (fshfs_volume_header_t *) data )->signature,
364
4.52k
       "H+",
365
4.52k
       2 ) == 0 )
366
3.51k
  {
367
3.51k
    volume_header->file_system_type = LIBFSHFS_FILE_SYSTEM_TYPE_HFS_PLUS;
368
3.51k
  }
369
1.01k
  else if( memory_compare(
370
1.01k
            ( (fshfs_volume_header_t *) data )->signature,
371
1.01k
            "HX",
372
1.01k
            2 ) == 0 )
373
898
  {
374
898
    volume_header->file_system_type = LIBFSHFS_FILE_SYSTEM_TYPE_HFSX;
375
898
  }
376
113
  else
377
113
  {
378
113
    libcerror_error_set(
379
113
     error,
380
113
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
381
113
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
382
113
     "%s: unsupported volume header signature.",
383
113
     function );
384
385
113
    return( -1 );
386
113
  }
387
4.41k
  byte_stream_copy_to_uint32_big_endian(
388
4.41k
   ( (fshfs_volume_header_t *) data )->allocation_block_size,
389
4.41k
   volume_header->allocation_block_size );
390
391
#if defined( HAVE_DEBUG_OUTPUT )
392
  if( libcnotify_verbose != 0 )
393
  {
394
    libcnotify_printf(
395
     "%s: signature\t\t\t\t: %c%c\n",
396
     function,
397
     ( (fshfs_volume_header_t *) data )->signature[ 0 ],
398
     ( (fshfs_volume_header_t *) data )->signature[ 1 ] );
399
400
    byte_stream_copy_to_uint16_big_endian(
401
     ( (fshfs_volume_header_t *) data )->version,
402
     value_16bit );
403
    libcnotify_printf(
404
     "%s: version\t\t\t\t: %" PRIu16 "\n",
405
     function,
406
     value_16bit );
407
408
    byte_stream_copy_to_uint32_big_endian(
409
     ( (fshfs_volume_header_t *) data )->attribute_flags,
410
     value_32bit );
411
    libcnotify_printf(
412
     "%s: attribute flags\t\t\t: 0x%08" PRIx32 "\n",
413
     function,
414
     value_32bit );
415
    libfshfs_debug_print_volume_attribute_flags(
416
     value_32bit );
417
    libcnotify_printf(
418
     "\n" );
419
420
    libcnotify_printf(
421
     "%s: last mounted version\t\t\t: %c%c%c%c\n",
422
     function,
423
     ( (fshfs_volume_header_t *) data )->last_mounted_version[ 0 ],
424
     ( (fshfs_volume_header_t *) data )->last_mounted_version[ 1 ],
425
     ( (fshfs_volume_header_t *) data )->last_mounted_version[ 2 ],
426
     ( (fshfs_volume_header_t *) data )->last_mounted_version[ 3 ] );
427
428
    byte_stream_copy_to_uint32_big_endian(
429
     ( (fshfs_volume_header_t *) data )->journal_information_block_number,
430
     value_32bit );
431
    libcnotify_printf(
432
     "%s: journal information block number\t: %" PRIu32 "\n",
433
     function,
434
     value_32bit );
435
436
    if( libfshfs_debug_print_hfs_time_value(
437
         function,
438
         "creation time\t\t\t\t",
439
         ( (fshfs_volume_header_t *) data )->creation_time,
440
         4,
441
         LIBFDATETIME_ENDIAN_BIG,
442
         LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME,
443
         0,
444
         error ) != 1 )
445
    {
446
      libcerror_error_set(
447
       error,
448
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
449
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
450
       "%s: unable to print HFS time value.",
451
       function );
452
453
      return( -1 );
454
    }
455
    if( libfshfs_debug_print_hfs_time_value(
456
         function,
457
         "modification time\t\t\t",
458
         ( (fshfs_volume_header_t *) data )->modification_time,
459
         4,
460
         LIBFDATETIME_ENDIAN_BIG,
461
         LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME,
462
         0,
463
         error ) != 1 )
464
    {
465
      libcerror_error_set(
466
       error,
467
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
468
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
469
       "%s: unable to print HFS time value.",
470
       function );
471
472
      return( -1 );
473
    }
474
    if( libfshfs_debug_print_hfs_time_value(
475
         function,
476
         "backup time\t\t\t\t",
477
         ( (fshfs_volume_header_t *) data )->backup_time,
478
         4,
479
         LIBFDATETIME_ENDIAN_BIG,
480
         LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME,
481
         0,
482
         error ) != 1 )
483
    {
484
      libcerror_error_set(
485
       error,
486
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
487
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
488
       "%s: unable to print HFS time value.",
489
       function );
490
491
      return( -1 );
492
    }
493
    if( libfshfs_debug_print_hfs_time_value(
494
         function,
495
         "checked time\t\t\t\t",
496
         ( (fshfs_volume_header_t *) data )->checked_time,
497
         4,
498
         LIBFDATETIME_ENDIAN_BIG,
499
         LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME,
500
         0,
501
         error ) != 1 )
502
    {
503
      libcerror_error_set(
504
       error,
505
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
506
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
507
       "%s: unable to print HFS time value.",
508
       function );
509
510
      return( -1 );
511
    }
512
    byte_stream_copy_to_uint32_big_endian(
513
     ( (fshfs_volume_header_t *) data )->number_of_files,
514
     value_32bit );
515
    libcnotify_printf(
516
     "%s: number of files\t\t\t: %" PRIu32 "\n",
517
     function,
518
     value_32bit );
519
520
    byte_stream_copy_to_uint32_big_endian(
521
     ( (fshfs_volume_header_t *) data )->number_of_directories,
522
     value_32bit );
523
    libcnotify_printf(
524
     "%s: number of directories\t\t\t: %" PRIu32 "\n",
525
     function,
526
     value_32bit );
527
528
    libcnotify_printf(
529
     "%s: allocation block size\t\t\t: %" PRIu32 "\n",
530
     function,
531
     volume_header->allocation_block_size );
532
533
    byte_stream_copy_to_uint32_big_endian(
534
     ( (fshfs_volume_header_t *) data )->number_of_blocks,
535
     value_32bit );
536
    libcnotify_printf(
537
     "%s: number of blocks\t\t\t: %" PRIu32 "\n",
538
     function,
539
     value_32bit );
540
541
    byte_stream_copy_to_uint32_big_endian(
542
     ( (fshfs_volume_header_t *) data )->number_of_unused_blocks,
543
     value_32bit );
544
    libcnotify_printf(
545
     "%s: number of unused blocks\t\t: %" PRIu32 "\n",
546
     function,
547
     value_32bit );
548
549
    byte_stream_copy_to_uint32_big_endian(
550
     ( (fshfs_volume_header_t *) data )->next_available_block_number,
551
     value_32bit );
552
    libcnotify_printf(
553
     "%s: next available block number\t\t: %" PRIu32 "\n",
554
     function,
555
     value_32bit );
556
557
    byte_stream_copy_to_uint32_big_endian(
558
     ( (fshfs_volume_header_t *) data )->resource_fork_clump_size,
559
     value_32bit );
560
    libcnotify_printf(
561
     "%s: resource fork clump size\t\t: %" PRIu32 "\n",
562
     function,
563
     value_32bit );
564
565
    byte_stream_copy_to_uint32_big_endian(
566
     ( (fshfs_volume_header_t *) data )->data_fork_clump_size,
567
     value_32bit );
568
    libcnotify_printf(
569
     "%s: data fork clump size\t\t\t: %" PRIu32 "\n",
570
     function,
571
     value_32bit );
572
573
    byte_stream_copy_to_uint32_big_endian(
574
     ( (fshfs_volume_header_t *) data )->volume_write_count,
575
     value_32bit );
576
    libcnotify_printf(
577
     "%s: volume write count\t\t\t: %" PRIu32 "\n",
578
     function,
579
     value_32bit );
580
581
    libcnotify_printf(
582
     "%s: encodings bitmap:\n",
583
     function );
584
    libcnotify_print_data(
585
     ( (fshfs_volume_header_t *) data )->encodings_bitmap,
586
     8,
587
     0 );
588
589
    libcnotify_printf(
590
     "%s: finder information:\n",
591
     function );
592
    libcnotify_print_data(
593
     ( (fshfs_volume_header_t *) data )->finder_information,
594
     32,
595
     0 );
596
  }
597
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
598
599
#if defined( HAVE_DEBUG_OUTPUT )
600
  if( libcnotify_verbose != 0 )
601
  {
602
    libcnotify_printf(
603
     "%s: allocation file fork descriptor:\n",
604
     function );
605
  }
606
#endif
607
4.41k
  if( libfshfs_fork_descriptor_read_data(
608
4.41k
       volume_header->allocation_file_fork_descriptor,
609
4.41k
       ( (fshfs_volume_header_t *) data )->allocation_file_fork_descriptor,
610
4.41k
       80,
611
4.41k
       error ) != 1 )
612
0
  {
613
0
    libcerror_error_set(
614
0
     error,
615
0
     LIBCERROR_ERROR_DOMAIN_IO,
616
0
     LIBCERROR_IO_ERROR_READ_FAILED,
617
0
     "%s: unable to read allocation file fork descriptor.",
618
0
     function );
619
620
0
    return( -1 );
621
0
  }
622
#if defined( HAVE_DEBUG_OUTPUT )
623
  if( libcnotify_verbose != 0 )
624
  {
625
    libcnotify_printf(
626
     "%s: extents file fork descriptor:\n",
627
     function );
628
  }
629
#endif
630
4.41k
  if( libfshfs_fork_descriptor_read_data(
631
4.41k
       volume_header->extents_file_fork_descriptor,
632
4.41k
       ( (fshfs_volume_header_t *) data )->extents_file_fork_descriptor,
633
4.41k
       80,
634
4.41k
       error ) != 1 )
635
0
  {
636
0
    libcerror_error_set(
637
0
     error,
638
0
     LIBCERROR_ERROR_DOMAIN_IO,
639
0
     LIBCERROR_IO_ERROR_READ_FAILED,
640
0
     "%s: unable to read extents file fork descriptor.",
641
0
     function );
642
643
0
    return( -1 );
644
0
  }
645
#if defined( HAVE_DEBUG_OUTPUT )
646
  if( libcnotify_verbose != 0 )
647
  {
648
    libcnotify_printf(
649
     "%s: catalog file fork descriptor:\n",
650
     function );
651
  }
652
#endif
653
4.41k
  if( libfshfs_fork_descriptor_read_data(
654
4.41k
       volume_header->catalog_file_fork_descriptor,
655
4.41k
       ( (fshfs_volume_header_t *) data )->catalog_file_fork_descriptor,
656
4.41k
       80,
657
4.41k
       error ) != 1 )
658
0
  {
659
0
    libcerror_error_set(
660
0
     error,
661
0
     LIBCERROR_ERROR_DOMAIN_IO,
662
0
     LIBCERROR_IO_ERROR_READ_FAILED,
663
0
     "%s: unable to read catalog file fork descriptor.",
664
0
     function );
665
666
0
    return( -1 );
667
0
  }
668
#if defined( HAVE_DEBUG_OUTPUT )
669
  if( libcnotify_verbose != 0 )
670
  {
671
    libcnotify_printf(
672
     "%s: attributes file fork descriptor:\n",
673
     function );
674
  }
675
#endif
676
4.41k
  if( libfshfs_fork_descriptor_read_data(
677
4.41k
       volume_header->attributes_file_fork_descriptor,
678
4.41k
       ( (fshfs_volume_header_t *) data )->attributes_file_fork_descriptor,
679
4.41k
       80,
680
4.41k
       error ) != 1 )
681
0
  {
682
0
    libcerror_error_set(
683
0
     error,
684
0
     LIBCERROR_ERROR_DOMAIN_IO,
685
0
     LIBCERROR_IO_ERROR_READ_FAILED,
686
0
     "%s: unable to read attributes file fork descriptor.",
687
0
     function );
688
689
0
    return( -1 );
690
0
  }
691
#if defined( HAVE_DEBUG_OUTPUT )
692
  if( libcnotify_verbose != 0 )
693
  {
694
    libcnotify_printf(
695
     "%s: startup file fork descriptor:\n",
696
     function );
697
  }
698
#endif
699
4.41k
  if( libfshfs_fork_descriptor_read_data(
700
4.41k
       volume_header->startup_file_fork_descriptor,
701
4.41k
       ( (fshfs_volume_header_t *) data )->startup_file_fork_descriptor,
702
4.41k
       80,
703
4.41k
       error ) != 1 )
704
0
  {
705
0
    libcerror_error_set(
706
0
     error,
707
0
     LIBCERROR_ERROR_DOMAIN_IO,
708
0
     LIBCERROR_IO_ERROR_READ_FAILED,
709
0
     "%s: unable to read startup file fork descriptor.",
710
0
     function );
711
712
0
    return( -1 );
713
0
  }
714
4.41k
  return( 1 );
715
4.41k
}
716
717
/* Reads the volume header
718
 * Returns 1 if successful or -1 on error
719
 */
720
int libfshfs_volume_header_read_file_io_handle(
721
     libfshfs_volume_header_t *volume_header,
722
     libbfio_handle_t *file_io_handle,
723
     off64_t file_offset,
724
     libcerror_error_t **error )
725
4.69k
{
726
4.69k
  uint8_t volume_header_data[ 1024 ];
727
728
4.69k
  static char *function = "libfshfs_volume_header_read_file_io_handle";
729
4.69k
  ssize_t read_count    = 0;
730
731
4.69k
  if( volume_header == NULL )
732
0
  {
733
0
    libcerror_error_set(
734
0
     error,
735
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
736
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
737
0
     "%s: invalid volume header.",
738
0
     function );
739
740
0
    return( -1 );
741
0
  }
742
#if defined( HAVE_DEBUG_OUTPUT )
743
  if( libcnotify_verbose != 0 )
744
  {
745
    libcnotify_printf(
746
     "%s: reading volume header at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
747
     function,
748
     file_offset,
749
     file_offset );
750
  }
751
#endif
752
4.69k
  read_count = libbfio_handle_read_buffer_at_offset(
753
4.69k
                file_io_handle,
754
4.69k
                (uint8_t *) &volume_header_data,
755
4.69k
                1024,
756
4.69k
                file_offset,
757
4.69k
                error );
758
759
4.69k
  if( read_count != (ssize_t) 1024 )
760
172
  {
761
172
    libcerror_error_set(
762
172
     error,
763
172
     LIBCERROR_ERROR_DOMAIN_IO,
764
172
     LIBCERROR_IO_ERROR_READ_FAILED,
765
172
     "%s: unable to read volume header data at offset: %" PRIi64 " (0x%08" PRIx64 ").",
766
172
     function,
767
172
     file_offset,
768
172
     file_offset );
769
770
172
    return( -1 );
771
172
  }
772
4.52k
  if( libfshfs_volume_header_read_data(
773
4.52k
       volume_header,
774
4.52k
       (uint8_t *) &volume_header_data,
775
4.52k
       1024,
776
4.52k
       error ) != 1)
777
113
  {
778
113
    libcerror_error_set(
779
113
     error,
780
113
     LIBCERROR_ERROR_DOMAIN_IO,
781
113
     LIBCERROR_IO_ERROR_READ_FAILED,
782
113
     "%s: unable to read volume header data.",
783
113
     function );
784
785
113
    return( -1 );
786
113
  }
787
4.41k
  return( 1 );
788
4.52k
}
789