Coverage Report

Created: 2025-08-28 07:10

/src/libfsapfs/libfsapfs/libfsapfs_volume_superblock.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * The volume superblock functions
3
 *
4
 * Copyright (C) 2018-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 "libfsapfs_checksum.h"
28
#include "libfsapfs_debug.h"
29
#include "libfsapfs_io_handle.h"
30
#include "libfsapfs_libbfio.h"
31
#include "libfsapfs_libcerror.h"
32
#include "libfsapfs_libcnotify.h"
33
#include "libfsapfs_libfdatetime.h"
34
#include "libfsapfs_libfguid.h"
35
#include "libfsapfs_libuna.h"
36
#include "libfsapfs_volume_superblock.h"
37
38
#include "fsapfs_volume_superblock.h"
39
40
/* Creates a volume superblock
41
 * Make sure the value volume_superblock is referencing, is set to NULL
42
 * Returns 1 if successful or -1 on error
43
 */
44
int libfsapfs_volume_superblock_initialize(
45
     libfsapfs_volume_superblock_t **volume_superblock,
46
     libcerror_error_t **error )
47
3.28k
{
48
3.28k
  static char *function = "libfsapfs_volume_superblock_initialize";
49
50
3.28k
  if( volume_superblock == NULL )
51
0
  {
52
0
    libcerror_error_set(
53
0
     error,
54
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
55
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
56
0
     "%s: invalid volume superblock.",
57
0
     function );
58
59
0
    return( -1 );
60
0
  }
61
3.28k
  if( *volume_superblock != NULL )
62
0
  {
63
0
    libcerror_error_set(
64
0
     error,
65
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
66
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
67
0
     "%s: invalid volume superblock value already set.",
68
0
     function );
69
70
0
    return( -1 );
71
0
  }
72
3.28k
  *volume_superblock = memory_allocate_structure(
73
3.28k
                        libfsapfs_volume_superblock_t );
74
75
3.28k
  if( *volume_superblock == NULL )
76
0
  {
77
0
    libcerror_error_set(
78
0
     error,
79
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
80
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
81
0
     "%s: unable to create volume superblock.",
82
0
     function );
83
84
0
    goto on_error;
85
0
  }
86
3.28k
  if( memory_set(
87
3.28k
       *volume_superblock,
88
3.28k
       0,
89
3.28k
       sizeof( libfsapfs_volume_superblock_t ) ) == NULL )
90
0
  {
91
0
    libcerror_error_set(
92
0
     error,
93
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
94
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
95
0
     "%s: unable to clear volume superblock.",
96
0
     function );
97
98
0
    goto on_error;
99
0
  }
100
3.28k
  return( 1 );
101
102
0
on_error:
103
0
  if( *volume_superblock != NULL )
104
0
  {
105
0
    memory_free(
106
0
     *volume_superblock );
107
108
0
    *volume_superblock = NULL;
109
0
  }
110
0
  return( -1 );
111
3.28k
}
112
113
/* Frees a volume superblock
114
 * Returns 1 if successful or -1 on error
115
 */
116
int libfsapfs_volume_superblock_free(
117
     libfsapfs_volume_superblock_t **volume_superblock,
118
     libcerror_error_t **error )
119
3.28k
{
120
3.28k
  static char *function = "libfsapfs_volume_superblock_free";
121
122
3.28k
  if( volume_superblock == NULL )
123
0
  {
124
0
    libcerror_error_set(
125
0
     error,
126
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
127
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
128
0
     "%s: invalid volume superblock.",
129
0
     function );
130
131
0
    return( -1 );
132
0
  }
133
3.28k
  if( *volume_superblock != NULL )
134
3.28k
  {
135
3.28k
    memory_free(
136
3.28k
     *volume_superblock );
137
138
3.28k
    *volume_superblock = NULL;
139
3.28k
  }
140
3.28k
  return( 1 );
141
3.28k
}
142
143
/* Reads the volume superblock
144
 * Returns 1 if successful or -1 on error
145
 */
146
int libfsapfs_volume_superblock_read_file_io_handle(
147
     libfsapfs_volume_superblock_t *volume_superblock,
148
     libbfio_handle_t *file_io_handle,
149
     off64_t file_offset,
150
     int8_t is_snapshot,
151
     libcerror_error_t **error )
152
3.28k
{
153
3.28k
  uint8_t volume_superblock_data[ 4096 ];
154
155
3.28k
  static char *function = "libfsapfs_volume_superblock_read_file_io_handle";
156
3.28k
  ssize_t read_count    = 0;
157
158
3.28k
  if( volume_superblock == NULL )
159
0
  {
160
0
    libcerror_error_set(
161
0
     error,
162
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
163
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
164
0
     "%s: invalid volume superblock.",
165
0
     function );
166
167
0
    return( -1 );
168
0
  }
169
#if defined( HAVE_DEBUG_OUTPUT )
170
  if( libcnotify_verbose != 0 )
171
  {
172
    libcnotify_printf(
173
     "%s: reading volume superblock at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
174
     function,
175
     file_offset,
176
     file_offset );
177
  }
178
#endif
179
3.28k
  read_count = libbfio_handle_read_buffer_at_offset(
180
3.28k
                file_io_handle,
181
3.28k
                (uint8_t *) &volume_superblock_data,
182
3.28k
                4096,
183
3.28k
                file_offset,
184
3.28k
                error );
185
186
3.28k
  if( read_count != (ssize_t) 4096 )
187
177
  {
188
177
    libcerror_error_set(
189
177
     error,
190
177
     LIBCERROR_ERROR_DOMAIN_IO,
191
177
     LIBCERROR_IO_ERROR_READ_FAILED,
192
177
     "%s: unable to read volume superblock data at offset: %" PRIi64 " (0x%08" PRIx64 ").",
193
177
     function,
194
177
     file_offset,
195
177
     file_offset );
196
197
177
    return( -1 );
198
177
  }
199
3.10k
  if( libfsapfs_volume_superblock_read_data(
200
3.10k
       volume_superblock,
201
3.10k
       (uint8_t *) &volume_superblock_data,
202
3.10k
       4096,
203
3.10k
       is_snapshot,
204
3.10k
       error ) != 1 )
205
404
  {
206
404
    libcerror_error_set(
207
404
     error,
208
404
     LIBCERROR_ERROR_DOMAIN_IO,
209
404
     LIBCERROR_IO_ERROR_READ_FAILED,
210
404
     "%s: unable to read volume superblock data.",
211
404
     function );
212
213
404
    return( -1 );
214
404
  }
215
2.70k
  return( 1 );
216
3.10k
}
217
218
/* Reads the volume superblock
219
 * Returns 1 if successful or -1 on error
220
 */
221
int libfsapfs_volume_superblock_read_data(
222
     libfsapfs_volume_superblock_t *volume_superblock,
223
     const uint8_t *data,
224
     size_t data_size,
225
     int8_t is_snapshot,
226
     libcerror_error_t **error )
227
3.10k
{
228
3.10k
  static char *function         = "libfsapfs_volume_superblock_read_data";
229
3.10k
  uint64_t calculated_checksum  = 0;
230
3.10k
  uint64_t stored_checksum      = 0;
231
3.10k
  uint32_t expected_object_type = 0;
232
3.10k
  uint32_t object_subtype       = 0;
233
3.10k
  uint32_t object_type          = 0;
234
235
#if defined( HAVE_DEBUG_OUTPUT )
236
  uint64_t value_64bit          = 0;
237
  uint32_t value_32bit          = 0;
238
#endif
239
240
3.10k
  if( volume_superblock == NULL )
241
0
  {
242
0
    libcerror_error_set(
243
0
     error,
244
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
245
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
246
0
     "%s: invalid volume superblock.",
247
0
     function );
248
249
0
    return( -1 );
250
0
  }
251
3.10k
  if( data == NULL )
252
0
  {
253
0
    libcerror_error_set(
254
0
     error,
255
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
256
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
257
0
     "%s: invalid data.",
258
0
     function );
259
260
0
    return( -1 );
261
0
  }
262
3.10k
  if( ( data_size < sizeof( fsapfs_volume_superblock_t ) )
263
3.10k
   || ( data_size > (size_t) SSIZE_MAX ) )
264
0
  {
265
0
    libcerror_error_set(
266
0
     error,
267
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
268
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
269
0
     "%s: invalid data size value out of bounds.",
270
0
     function );
271
272
0
    return( -1 );
273
0
  }
274
3.10k
  if( is_snapshot == 0 )
275
3.10k
  {
276
3.10k
    expected_object_type = 0x0000000dUL;
277
3.10k
  }
278
0
  else
279
0
  {
280
0
    expected_object_type = 0x4000000dUL;
281
0
  }
282
#if defined( HAVE_DEBUG_OUTPUT )
283
  if( libcnotify_verbose != 0 )
284
  {
285
    libcnotify_printf(
286
     "%s: volume superblock data:\n",
287
     function );
288
    libcnotify_print_data(
289
     data,
290
     sizeof( fsapfs_volume_superblock_t ),
291
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
292
  }
293
#endif
294
3.10k
  byte_stream_copy_to_uint64_little_endian(
295
3.10k
   ( (fsapfs_volume_superblock_t *) data )->object_transaction_identifier,
296
3.10k
   volume_superblock->transaction_identifier );
297
298
3.10k
  byte_stream_copy_to_uint64_little_endian(
299
3.10k
   ( (fsapfs_volume_superblock_t *) data )->object_checksum,
300
3.10k
   stored_checksum );
301
302
3.10k
  byte_stream_copy_to_uint32_little_endian(
303
3.10k
   ( (fsapfs_volume_superblock_t *) data )->object_type,
304
3.10k
   object_type );
305
306
3.10k
  if( object_type != expected_object_type )
307
107
  {
308
107
    libcerror_error_set(
309
107
     error,
310
107
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
311
107
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
312
107
     "%s: invalid object type: 0x%08" PRIx32 ".",
313
107
     function,
314
107
     object_type );
315
316
107
    return( -1 );
317
107
  }
318
2.99k
  byte_stream_copy_to_uint32_little_endian(
319
2.99k
   ( (fsapfs_volume_superblock_t *) data )->object_subtype,
320
2.99k
   object_subtype );
321
322
2.99k
  if( object_subtype != 0x00000000UL )
323
86
  {
324
86
    libcerror_error_set(
325
86
     error,
326
86
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
327
86
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
328
86
     "%s: invalid object subtype: 0x%08" PRIx32 ".",
329
86
     function,
330
86
     object_subtype );
331
332
86
    return( -1 );
333
86
  }
334
2.91k
  if( memory_compare(
335
2.91k
       ( (fsapfs_volume_superblock_t *) data )->signature,
336
2.91k
       fsapfs_volume_signature,
337
2.91k
       4 ) != 0 )
338
6
  {
339
6
    libcerror_error_set(
340
6
     error,
341
6
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
342
6
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
343
6
     "%s: invalid signature.",
344
6
     function );
345
346
6
    return( -1 );
347
6
  }
348
2.90k
  byte_stream_copy_to_uint64_little_endian(
349
2.90k
   ( (fsapfs_volume_superblock_t *) data )->compatible_features_flags,
350
2.90k
   volume_superblock->compatible_features_flags );
351
352
2.90k
  byte_stream_copy_to_uint64_little_endian(
353
2.90k
   ( (fsapfs_volume_superblock_t *) data )->read_only_compatible_features_flags,
354
2.90k
   volume_superblock->read_only_compatible_features_flags );
355
356
2.90k
  byte_stream_copy_to_uint64_little_endian(
357
2.90k
   ( (fsapfs_volume_superblock_t *) data )->incompatible_features_flags,
358
2.90k
   volume_superblock->incompatible_features_flags );
359
360
2.90k
  byte_stream_copy_to_uint64_little_endian(
361
2.90k
   ( (fsapfs_volume_superblock_t *) data )->object_map_block_number,
362
2.90k
   volume_superblock->object_map_block_number );
363
364
2.90k
  byte_stream_copy_to_uint64_little_endian(
365
2.90k
   ( (fsapfs_volume_superblock_t *) data )->file_system_root_object_identifier,
366
2.90k
   volume_superblock->file_system_root_object_identifier );
367
368
2.90k
  byte_stream_copy_to_uint64_little_endian(
369
2.90k
   ( (fsapfs_volume_superblock_t *) data )->extent_reference_tree_block_number,
370
2.90k
   volume_superblock->extent_reference_tree_block_number );
371
372
2.90k
  byte_stream_copy_to_uint64_little_endian(
373
2.90k
   ( (fsapfs_volume_superblock_t *) data )->snapshot_metadata_tree_block_number,
374
2.90k
   volume_superblock->snapshot_metadata_tree_block_number );
375
376
2.90k
  byte_stream_copy_to_uint64_little_endian(
377
2.90k
   ( (fsapfs_volume_superblock_t *) data )->next_file_system_object_identifier,
378
2.90k
   volume_superblock->next_file_system_object_identifier );
379
380
2.90k
  if( memory_copy(
381
2.90k
       volume_superblock->volume_identifier,
382
2.90k
       ( (fsapfs_volume_superblock_t *) data )->volume_identifier,
383
2.90k
       16 ) == NULL )
384
0
  {
385
0
    libcerror_error_set(
386
0
     error,
387
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
388
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
389
0
     "%s: unable to copy volume identifier.",
390
0
     function );
391
392
0
    return( -1 );
393
0
  }
394
/* TODO preserve modification time */
395
396
2.90k
  byte_stream_copy_to_uint64_little_endian(
397
2.90k
   ( (fsapfs_volume_superblock_t *) data )->volume_flags,
398
2.90k
   volume_superblock->volume_flags );
399
400
2.90k
  if( memory_copy(
401
2.90k
       volume_superblock->volume_name,
402
2.90k
       ( (fsapfs_volume_superblock_t *) data )->volume_name,
403
2.90k
       256 ) == NULL )
404
0
  {
405
0
    libcerror_error_set(
406
0
     error,
407
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
408
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
409
0
     "%s: unable to copy volume name.",
410
0
     function );
411
412
0
    return( -1 );
413
0
  }
414
#if defined( HAVE_DEBUG_OUTPUT )
415
  if( libcnotify_verbose != 0 )
416
  {
417
    libcnotify_printf(
418
     "%s: object checksum\t\t\t\t: 0x%08" PRIx64 "\n",
419
     function,
420
     stored_checksum );
421
422
    byte_stream_copy_to_uint64_little_endian(
423
     ( (fsapfs_volume_superblock_t *) data )->object_identifier,
424
     value_64bit );
425
    libcnotify_printf(
426
     "%s: object identifier\t\t\t: %" PRIu64 "\n",
427
     function,
428
     value_64bit );
429
430
    libcnotify_printf(
431
     "%s: object transaction identifier\t\t: %" PRIu64 "\n",
432
     function,
433
     volume_superblock->transaction_identifier );
434
435
    libcnotify_printf(
436
     "%s: object type\t\t\t\t: 0x%08" PRIx32 "\n",
437
     function,
438
     object_type );
439
440
    libcnotify_printf(
441
     "%s: object subtype\t\t\t\t: 0x%08" PRIx32 "\n",
442
     function,
443
     object_subtype );
444
445
    libcnotify_printf(
446
     "%s: signature\t\t\t\t: %c%c%c%c\n",
447
     function,
448
     ( (fsapfs_volume_superblock_t *) data )->signature[ 0 ],
449
     ( (fsapfs_volume_superblock_t *) data )->signature[ 1 ],
450
     ( (fsapfs_volume_superblock_t *) data )->signature[ 2 ],
451
     ( (fsapfs_volume_superblock_t *) data )->signature[ 3 ] );
452
453
    byte_stream_copy_to_uint32_little_endian(
454
     ( (fsapfs_volume_superblock_t *) data )->unknown1,
455
     value_32bit );
456
    libcnotify_printf(
457
     "%s: unknown1\t\t\t\t\t: 0x%08" PRIx32 "\n",
458
     function,
459
     value_32bit );
460
461
    libcnotify_printf(
462
     "%s: compatible features flags\t\t: 0x%08" PRIx64 "\n",
463
     function,
464
     volume_superblock->compatible_features_flags );
465
    libfsapfs_debug_print_volume_compatible_features_flags(
466
     volume_superblock->compatible_features_flags );
467
    libcnotify_printf(
468
     "\n" );
469
470
    libcnotify_printf(
471
     "%s: read-only compatible features flags\t: 0x%08" PRIx64 "\n",
472
     function,
473
     volume_superblock->read_only_compatible_features_flags );
474
    libfsapfs_debug_print_volume_read_only_compatible_features_flags(
475
     volume_superblock->read_only_compatible_features_flags );
476
    libcnotify_printf(
477
     "\n" );
478
479
    libcnotify_printf(
480
     "%s: incompatible features flags\t\t: 0x%08" PRIx64 "\n",
481
     function,
482
     volume_superblock->incompatible_features_flags );
483
    libfsapfs_debug_print_volume_incompatible_features_flags(
484
     volume_superblock->incompatible_features_flags );
485
    libcnotify_printf(
486
     "\n" );
487
488
    if( libfsapfs_debug_print_posix_time_value(
489
         function,
490
         "unknown5\t\t\t\t\t",
491
         ( (fsapfs_volume_superblock_t *) data )->unknown5,
492
         8,
493
         LIBFDATETIME_ENDIAN_LITTLE,
494
         LIBFDATETIME_POSIX_TIME_VALUE_TYPE_NANO_SECONDS_64BIT_SIGNED,
495
         LIBFDATETIME_STRING_FORMAT_TYPE_ISO8601 | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
496
         error ) != 1 )
497
    {
498
      libcerror_error_set(
499
       error,
500
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
501
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
502
       "%s: unable to print POSIX time value.",
503
       function );
504
505
      return( -1 );
506
    }
507
    byte_stream_copy_to_uint64_little_endian(
508
     ( (fsapfs_volume_superblock_t *) data )->number_of_reserved_blocks,
509
     value_64bit );
510
    libcnotify_printf(
511
     "%s: number of reserved blocks\t\t: %" PRIu64 "\n",
512
     function,
513
     value_64bit );
514
515
    byte_stream_copy_to_uint64_little_endian(
516
     ( (fsapfs_volume_superblock_t *) data )->number_of_quota_blocks,
517
     value_64bit );
518
    libcnotify_printf(
519
     "%s: number of quota blocks\t\t\t: %" PRIu64 "\n",
520
     function,
521
     value_64bit );
522
523
    byte_stream_copy_to_uint64_little_endian(
524
     ( (fsapfs_volume_superblock_t *) data )->unknown8,
525
     value_64bit );
526
    libcnotify_printf(
527
     "%s: unknown8\t\t\t\t\t: 0x%08" PRIx64 "\n",
528
     function,
529
     value_64bit );
530
531
    byte_stream_copy_to_uint64_little_endian(
532
     ( (fsapfs_volume_superblock_t *) data )->unknown9,
533
     value_64bit );
534
    libcnotify_printf(
535
     "%s: unknown9\t\t\t\t\t: 0x%08" PRIx64 "\n",
536
     function,
537
     value_64bit );
538
539
    byte_stream_copy_to_uint32_little_endian(
540
     ( (fsapfs_volume_superblock_t *) data )->unknown10,
541
     value_32bit );
542
    libcnotify_printf(
543
     "%s: unknown10\t\t\t\t: 0x%08" PRIx32 "\n",
544
     function,
545
     value_32bit );
546
547
    byte_stream_copy_to_uint32_little_endian(
548
     ( (fsapfs_volume_superblock_t *) data )->unknown11,
549
     value_32bit );
550
    libcnotify_printf(
551
     "%s: unknown11\t\t\t\t: 0x%08" PRIx32 "\n",
552
     function,
553
     value_32bit );
554
555
    byte_stream_copy_to_uint32_little_endian(
556
     ( (fsapfs_volume_superblock_t *) data )->unknown12,
557
     value_32bit );
558
    libcnotify_printf(
559
     "%s: unknown12\t\t\t\t: 0x%08" PRIx32 "\n",
560
     function,
561
     value_32bit );
562
563
    byte_stream_copy_to_uint32_little_endian(
564
     ( (fsapfs_volume_superblock_t *) data )->file_system_root_tree_object_type,
565
     value_32bit );
566
    libcnotify_printf(
567
     "%s: file system root tree object type\t: 0x%08" PRIx32 "\n",
568
     function,
569
     value_32bit );
570
571
    byte_stream_copy_to_uint32_little_endian(
572
     ( (fsapfs_volume_superblock_t *) data )->extent_reference_tree_object_type,
573
     value_32bit );
574
    libcnotify_printf(
575
     "%s: extent-reference tree object type\t: 0x%08" PRIx32 "\n",
576
     function,
577
     value_32bit );
578
579
    byte_stream_copy_to_uint32_little_endian(
580
     ( (fsapfs_volume_superblock_t *) data )->snapshot_metadata_tree_object_type,
581
     value_32bit );
582
    libcnotify_printf(
583
     "%s: snapshot metadata tree object type\t: 0x%08" PRIx32 "\n",
584
     function,
585
     value_32bit );
586
587
    libcnotify_printf(
588
     "%s: object map block number\t\t\t: %" PRIu64 "\n",
589
     function,
590
     volume_superblock->object_map_block_number );
591
592
    libcnotify_printf(
593
     "%s: file system root object identifier\t: %" PRIu64 "\n",
594
     function,
595
     volume_superblock->file_system_root_object_identifier );
596
597
    libcnotify_printf(
598
     "%s: extent-reference tree block number\t: %" PRIu64 "\n",
599
     function,
600
     volume_superblock->extent_reference_tree_block_number );
601
602
    libcnotify_printf(
603
     "%s: snapshot metadata tree block number\t: %" PRIu64 "\n",
604
     function,
605
     volume_superblock->snapshot_metadata_tree_block_number );
606
607
    byte_stream_copy_to_uint64_little_endian(
608
     ( (fsapfs_volume_superblock_t *) data )->unknown20,
609
     value_64bit );
610
    libcnotify_printf(
611
     "%s: unknown20\t\t\t\t: 0x%08" PRIx64 "\n",
612
     function,
613
     value_64bit );
614
615
    byte_stream_copy_to_uint64_little_endian(
616
     ( (fsapfs_volume_superblock_t *) data )->unknown21,
617
     value_64bit );
618
    libcnotify_printf(
619
     "%s: unknown21\t\t\t\t: 0x%08" PRIx64 "\n",
620
     function,
621
     value_64bit );
622
623
    libcnotify_printf(
624
     "%s: next file system object identifier\t: %" PRIu64 "\n",
625
     function,
626
     volume_superblock->next_file_system_object_identifier );
627
628
    byte_stream_copy_to_uint64_little_endian(
629
     ( (fsapfs_volume_superblock_t *) data )->unknown23,
630
     value_64bit );
631
    libcnotify_printf(
632
     "%s: unknown23\t\t\t\t: 0x%08" PRIx64 "\n",
633
     function,
634
     value_64bit );
635
636
    byte_stream_copy_to_uint64_little_endian(
637
     ( (fsapfs_volume_superblock_t *) data )->unknown24,
638
     value_64bit );
639
    libcnotify_printf(
640
     "%s: unknown24\t\t\t\t: 0x%08" PRIx64 "\n",
641
     function,
642
     value_64bit );
643
644
    byte_stream_copy_to_uint64_little_endian(
645
     ( (fsapfs_volume_superblock_t *) data )->unknown25,
646
     value_64bit );
647
    libcnotify_printf(
648
     "%s: unknown25\t\t\t\t: 0x%08" PRIx64 "\n",
649
     function,
650
     value_64bit );
651
652
    byte_stream_copy_to_uint64_little_endian(
653
     ( (fsapfs_volume_superblock_t *) data )->unknown26,
654
     value_64bit );
655
    libcnotify_printf(
656
     "%s: unknown26\t\t\t\t: 0x%08" PRIx64 "\n",
657
     function,
658
     value_64bit );
659
660
    byte_stream_copy_to_uint64_little_endian(
661
     ( (fsapfs_volume_superblock_t *) data )->unknown27,
662
     value_64bit );
663
    libcnotify_printf(
664
     "%s: unknown27\t\t\t\t: 0x%08" PRIx64 "\n",
665
     function,
666
     value_64bit );
667
668
    byte_stream_copy_to_uint64_little_endian(
669
     ( (fsapfs_volume_superblock_t *) data )->unknown28,
670
     value_64bit );
671
    libcnotify_printf(
672
     "%s: unknown28\t\t\t\t: 0x%08" PRIx64 "\n",
673
     function,
674
     value_64bit );
675
676
    byte_stream_copy_to_uint64_little_endian(
677
     ( (fsapfs_volume_superblock_t *) data )->unknown29,
678
     value_64bit );
679
    libcnotify_printf(
680
     "%s: unknown29\t\t\t\t: 0x%08" PRIx64 "\n",
681
     function,
682
     value_64bit );
683
684
    if( libfsapfs_debug_print_guid_value(
685
         function,
686
         "volume identifier\t\t\t",
687
         ( (fsapfs_volume_superblock_t *) data )->volume_identifier,
688
         16,
689
         LIBFGUID_ENDIAN_BIG,
690
         LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
691
         error ) != 1 )
692
    {
693
      libcerror_error_set(
694
       error,
695
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
696
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
697
       "%s: unable to print UUID value.",
698
       function );
699
700
      return( -1 );
701
    }
702
    if( libfsapfs_debug_print_posix_time_value(
703
         function,
704
         "modification time\t\t\t",
705
         ( (fsapfs_volume_superblock_t *) data )->modification_time,
706
         8,
707
         LIBFDATETIME_ENDIAN_LITTLE,
708
         LIBFDATETIME_POSIX_TIME_VALUE_TYPE_NANO_SECONDS_64BIT_SIGNED,
709
         LIBFDATETIME_STRING_FORMAT_TYPE_ISO8601 | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
710
         error ) != 1 )
711
    {
712
      libcerror_error_set(
713
       error,
714
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
715
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
716
       "%s: unable to print POSIX time value.",
717
       function );
718
719
      return( -1 );
720
    }
721
    libcnotify_printf(
722
     "%s: volume flags\t\t\t\t: 0x%08" PRIx64 "\n",
723
     function,
724
     volume_superblock->volume_flags );
725
    libfsapfs_debug_print_volume_flags(
726
     volume_superblock->volume_flags );
727
    libcnotify_printf(
728
     "\n" );
729
730
    libcnotify_printf(
731
     "%s: unknown32:\n",
732
     function );
733
    libcnotify_print_data(
734
     ( (fsapfs_volume_superblock_t *) data )->unknown32,
735
     32,
736
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
737
738
    if( libfsapfs_debug_print_posix_time_value(
739
         function,
740
         "unknown33\t\t\t\t",
741
         ( (fsapfs_volume_superblock_t *) data )->unknown33,
742
         8,
743
         LIBFDATETIME_ENDIAN_LITTLE,
744
         LIBFDATETIME_POSIX_TIME_VALUE_TYPE_NANO_SECONDS_64BIT_SIGNED,
745
         LIBFDATETIME_STRING_FORMAT_TYPE_ISO8601 | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
746
         error ) != 1 )
747
    {
748
      libcerror_error_set(
749
       error,
750
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
751
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
752
       "%s: unable to print POSIX time value.",
753
       function );
754
755
      return( -1 );
756
    }
757
    byte_stream_copy_to_uint64_little_endian(
758
     ( (fsapfs_volume_superblock_t *) data )->unknown34,
759
     value_64bit );
760
    libcnotify_printf(
761
     "%s: unknown34\t\t\t\t: %" PRIu64 "\n",
762
     function,
763
     value_64bit );
764
765
    libcnotify_printf(
766
     "%s: unknown35:\n",
767
     function );
768
    libcnotify_print_data(
769
     ( (fsapfs_volume_superblock_t *) data )->unknown35,
770
     32,
771
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
772
773
    if( libfsapfs_debug_print_posix_time_value(
774
         function,
775
         "unknown36\t\t\t\t",
776
         ( (fsapfs_volume_superblock_t *) data )->unknown36,
777
         8,
778
         LIBFDATETIME_ENDIAN_LITTLE,
779
         LIBFDATETIME_POSIX_TIME_VALUE_TYPE_NANO_SECONDS_64BIT_SIGNED,
780
         LIBFDATETIME_STRING_FORMAT_TYPE_ISO8601 | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
781
         error ) != 1 )
782
    {
783
      libcerror_error_set(
784
       error,
785
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
786
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
787
       "%s: unable to print POSIX time value.",
788
       function );
789
790
      return( -1 );
791
    }
792
    byte_stream_copy_to_uint64_little_endian(
793
     ( (fsapfs_volume_superblock_t *) data )->unknown37,
794
     value_64bit );
795
    libcnotify_printf(
796
     "%s: unknown37\t\t\t\t: %" PRIu64 "\n",
797
     function,
798
     value_64bit );
799
800
    libcnotify_printf(
801
     "%s: unknown38:\n",
802
     function );
803
    libcnotify_print_data(
804
     ( (fsapfs_volume_superblock_t *) data )->unknown38,
805
     32,
806
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
807
808
    if( libfsapfs_debug_print_posix_time_value(
809
         function,
810
         "unknown39\t\t\t\t",
811
         ( (fsapfs_volume_superblock_t *) data )->unknown39,
812
         8,
813
         LIBFDATETIME_ENDIAN_LITTLE,
814
         LIBFDATETIME_POSIX_TIME_VALUE_TYPE_NANO_SECONDS_64BIT_SIGNED,
815
         LIBFDATETIME_STRING_FORMAT_TYPE_ISO8601 | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
816
         error ) != 1 )
817
    {
818
      libcerror_error_set(
819
       error,
820
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
821
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
822
       "%s: unable to print POSIX time value.",
823
       function );
824
825
      return( -1 );
826
    }
827
    byte_stream_copy_to_uint64_little_endian(
828
     ( (fsapfs_volume_superblock_t *) data )->unknown40,
829
     value_64bit );
830
    libcnotify_printf(
831
     "%s: unknown40\t\t\t\t: %" PRIu64 "\n",
832
     function,
833
     value_64bit );
834
835
    libcnotify_printf(
836
     "%s: unknown41:\n",
837
     function );
838
    libcnotify_print_data(
839
     ( (fsapfs_volume_superblock_t *) data )->unknown41,
840
     32,
841
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
842
843
    if( libfsapfs_debug_print_posix_time_value(
844
         function,
845
         "unknown42\t\t\t\t",
846
         ( (fsapfs_volume_superblock_t *) data )->unknown42,
847
         8,
848
         LIBFDATETIME_ENDIAN_LITTLE,
849
         LIBFDATETIME_POSIX_TIME_VALUE_TYPE_NANO_SECONDS_64BIT_SIGNED,
850
         LIBFDATETIME_STRING_FORMAT_TYPE_ISO8601 | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
851
         error ) != 1 )
852
    {
853
      libcerror_error_set(
854
       error,
855
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
856
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
857
       "%s: unable to print POSIX time value.",
858
       function );
859
860
      return( -1 );
861
    }
862
    byte_stream_copy_to_uint64_little_endian(
863
     ( (fsapfs_volume_superblock_t *) data )->unknown43,
864
     value_64bit );
865
    libcnotify_printf(
866
     "%s: unknown43\t\t\t\t: %" PRIu64 "\n",
867
     function,
868
     value_64bit );
869
870
    libcnotify_printf(
871
     "%s: unknown44:\n",
872
     function );
873
    libcnotify_print_data(
874
     ( (fsapfs_volume_superblock_t *) data )->unknown44,
875
     32,
876
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
877
878
    if( libfsapfs_debug_print_posix_time_value(
879
         function,
880
         "unknown45\t\t\t\t",
881
         ( (fsapfs_volume_superblock_t *) data )->unknown45,
882
         8,
883
         LIBFDATETIME_ENDIAN_LITTLE,
884
         LIBFDATETIME_POSIX_TIME_VALUE_TYPE_NANO_SECONDS_64BIT_SIGNED,
885
         LIBFDATETIME_STRING_FORMAT_TYPE_ISO8601 | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
886
         error ) != 1 )
887
    {
888
      libcerror_error_set(
889
       error,
890
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
891
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
892
       "%s: unable to print POSIX time value.",
893
       function );
894
895
      return( -1 );
896
    }
897
    byte_stream_copy_to_uint64_little_endian(
898
     ( (fsapfs_volume_superblock_t *) data )->unknown46,
899
     value_64bit );
900
    libcnotify_printf(
901
     "%s: unknown46\t\t\t\t: %" PRIu64 "\n",
902
     function,
903
     value_64bit );
904
905
    libcnotify_printf(
906
     "%s: unknown47:\n",
907
     function );
908
    libcnotify_print_data(
909
     ( (fsapfs_volume_superblock_t *) data )->unknown47,
910
     32,
911
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
912
913
    if( libfsapfs_debug_print_posix_time_value(
914
         function,
915
         "unknown48\t\t\t\t",
916
         ( (fsapfs_volume_superblock_t *) data )->unknown48,
917
         8,
918
         LIBFDATETIME_ENDIAN_LITTLE,
919
         LIBFDATETIME_POSIX_TIME_VALUE_TYPE_NANO_SECONDS_64BIT_SIGNED,
920
         LIBFDATETIME_STRING_FORMAT_TYPE_ISO8601 | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
921
         error ) != 1 )
922
    {
923
      libcerror_error_set(
924
       error,
925
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
926
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
927
       "%s: unable to print POSIX time value.",
928
       function );
929
930
      return( -1 );
931
    }
932
    byte_stream_copy_to_uint64_little_endian(
933
     ( (fsapfs_volume_superblock_t *) data )->unknown49,
934
     value_64bit );
935
    libcnotify_printf(
936
     "%s: unknown49\t\t\t\t: %" PRIu64 "\n",
937
     function,
938
     value_64bit );
939
940
    libcnotify_printf(
941
     "%s: unknown50:\n",
942
     function );
943
    libcnotify_print_data(
944
     ( (fsapfs_volume_superblock_t *) data )->unknown50,
945
     32,
946
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
947
948
    if( libfsapfs_debug_print_posix_time_value(
949
         function,
950
         "unknown51\t\t\t\t",
951
         ( (fsapfs_volume_superblock_t *) data )->unknown51,
952
         8,
953
         LIBFDATETIME_ENDIAN_LITTLE,
954
         LIBFDATETIME_POSIX_TIME_VALUE_TYPE_NANO_SECONDS_64BIT_SIGNED,
955
         LIBFDATETIME_STRING_FORMAT_TYPE_ISO8601 | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
956
         error ) != 1 )
957
    {
958
      libcerror_error_set(
959
       error,
960
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
961
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
962
       "%s: unable to print POSIX time value.",
963
       function );
964
965
      return( -1 );
966
    }
967
    byte_stream_copy_to_uint64_little_endian(
968
     ( (fsapfs_volume_superblock_t *) data )->unknown52,
969
     value_64bit );
970
    libcnotify_printf(
971
     "%s: unknown52\t\t\t\t: %" PRIu64 "\n",
972
     function,
973
     value_64bit );
974
975
    libcnotify_printf(
976
     "%s: unknown53:\n",
977
     function );
978
    libcnotify_print_data(
979
     ( (fsapfs_volume_superblock_t *) data )->unknown53,
980
     32,
981
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
982
983
    if( libfsapfs_debug_print_posix_time_value(
984
         function,
985
         "unknown54\t\t\t\t",
986
         ( (fsapfs_volume_superblock_t *) data )->unknown54,
987
         8,
988
         LIBFDATETIME_ENDIAN_LITTLE,
989
         LIBFDATETIME_POSIX_TIME_VALUE_TYPE_NANO_SECONDS_64BIT_SIGNED,
990
         LIBFDATETIME_STRING_FORMAT_TYPE_ISO8601 | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
991
         error ) != 1 )
992
    {
993
      libcerror_error_set(
994
       error,
995
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
996
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
997
       "%s: unable to print POSIX time value.",
998
       function );
999
1000
      return( -1 );
1001
    }
1002
    byte_stream_copy_to_uint64_little_endian(
1003
     ( (fsapfs_volume_superblock_t *) data )->unknown55,
1004
     value_64bit );
1005
    libcnotify_printf(
1006
     "%s: unknown55\t\t\t\t: %" PRIu64 "\n",
1007
     function,
1008
     value_64bit );
1009
1010
    libcnotify_printf(
1011
     "%s: unknown56:\n",
1012
     function );
1013
    libcnotify_print_data(
1014
     ( (fsapfs_volume_superblock_t *) data )->unknown56,
1015
     32,
1016
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1017
1018
    if( libfsapfs_debug_print_posix_time_value(
1019
         function,
1020
         "unknown57\t\t\t\t",
1021
         ( (fsapfs_volume_superblock_t *) data )->unknown57,
1022
         8,
1023
         LIBFDATETIME_ENDIAN_LITTLE,
1024
         LIBFDATETIME_POSIX_TIME_VALUE_TYPE_NANO_SECONDS_64BIT_SIGNED,
1025
         LIBFDATETIME_STRING_FORMAT_TYPE_ISO8601 | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
1026
         error ) != 1 )
1027
    {
1028
      libcerror_error_set(
1029
       error,
1030
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1031
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1032
       "%s: unable to print POSIX time value.",
1033
       function );
1034
1035
      return( -1 );
1036
    }
1037
    byte_stream_copy_to_uint64_little_endian(
1038
     ( (fsapfs_volume_superblock_t *) data )->unknown58,
1039
     value_64bit );
1040
    libcnotify_printf(
1041
     "%s: unknown58\t\t\t\t: %" PRIu64 "\n",
1042
     function,
1043
     value_64bit );
1044
1045
    libcnotify_printf(
1046
     "%s: volume name:\n",
1047
     function );
1048
    libcnotify_print_data(
1049
     ( (fsapfs_volume_superblock_t *) data )->volume_name,
1050
     256,
1051
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1052
1053
    byte_stream_copy_to_uint32_little_endian(
1054
     ( (fsapfs_volume_superblock_t *) data )->next_document_identifier,
1055
     value_32bit );
1056
    libcnotify_printf(
1057
     "%s: next document identifier\t\t\t: %" PRIu32 "\n",
1058
     function,
1059
     value_32bit );
1060
1061
    byte_stream_copy_to_uint32_little_endian(
1062
     ( (fsapfs_volume_superblock_t *) data )->unknown60,
1063
     value_32bit );
1064
    libcnotify_printf(
1065
     "%s: unknown60\t\t\t\t: 0x%08" PRIx32 "\n",
1066
     function,
1067
     value_32bit );
1068
1069
    byte_stream_copy_to_uint64_little_endian(
1070
     ( (fsapfs_volume_superblock_t *) data )->unknown61,
1071
     value_64bit );
1072
    libcnotify_printf(
1073
     "%s: unknown61\t\t\t\t: 0x%08" PRIx64 "\n",
1074
     function,
1075
     value_64bit );
1076
1077
    libcnotify_printf(
1078
     "%s: unknown62:\n",
1079
     function );
1080
    libcnotify_print_data(
1081
     ( (fsapfs_volume_superblock_t *) data )->unknown62,
1082
     32,
1083
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1084
  }
1085
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1086
1087
2.90k
  if( libfsapfs_checksum_calculate_fletcher64(
1088
2.90k
       &calculated_checksum,
1089
2.90k
       &( data[ 8 ] ),
1090
2.90k
       data_size - 8,
1091
2.90k
       0,
1092
2.90k
       error ) != 1 )
1093
0
  {
1094
0
    libcerror_error_set(
1095
0
     error,
1096
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1097
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1098
0
     "%s: unable to calculate Fletcher-64 checksum.",
1099
0
     function );
1100
1101
0
    return( -1 );
1102
0
  }
1103
2.90k
  if( stored_checksum != calculated_checksum )
1104
205
  {
1105
205
    libcerror_error_set(
1106
205
     error,
1107
205
     LIBCERROR_ERROR_DOMAIN_INPUT,
1108
205
     LIBCERROR_INPUT_ERROR_CHECKSUM_MISMATCH,
1109
205
     "%s: mismatch in checksum ( 0x%08" PRIx64 " != 0x%08" PRIx64 " ).\n",
1110
205
     function,
1111
205
     stored_checksum,
1112
205
     calculated_checksum );
1113
1114
205
    return( -1 );
1115
205
  }
1116
2.70k
  return( 1 );
1117
2.90k
}
1118
1119
/* Retrieves the volume identifier
1120
 * The identifier is an UUID stored in big-endian and is 16 bytes of size
1121
 * Returns 1 if successful or -1 on error
1122
 */
1123
int libfsapfs_volume_superblock_get_volume_identifier(
1124
     libfsapfs_volume_superblock_t *volume_superblock,
1125
     uint8_t *uuid_data,
1126
     size_t uuid_data_size,
1127
     libcerror_error_t **error )
1128
28
{
1129
28
  static char *function = "libfsapfs_volume_superblock_get_volume_identifier";
1130
1131
28
  if( volume_superblock == NULL )
1132
0
  {
1133
0
    libcerror_error_set(
1134
0
     error,
1135
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1136
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1137
0
     "%s: invalid volume superblock.",
1138
0
     function );
1139
1140
0
    return( -1 );
1141
0
  }
1142
28
  if( uuid_data == NULL )
1143
0
  {
1144
0
    libcerror_error_set(
1145
0
     error,
1146
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1147
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1148
0
     "%s: invalid UUID data.",
1149
0
     function );
1150
1151
0
    return( -1 );
1152
0
  }
1153
28
  if( ( uuid_data_size < 16 )
1154
28
   || ( uuid_data_size > (size_t) SSIZE_MAX ) )
1155
0
  {
1156
0
    libcerror_error_set(
1157
0
     error,
1158
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1159
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1160
0
     "%s: invalid UUID data size value out of bounds.",
1161
0
     function );
1162
1163
0
    return( -1 );
1164
0
  }
1165
28
  if( memory_copy(
1166
28
       uuid_data,
1167
28
       volume_superblock->volume_identifier,
1168
28
       16 ) == NULL )
1169
0
  {
1170
0
    libcerror_error_set(
1171
0
     error,
1172
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1173
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1174
0
     "%s: unable to copy volume identifier.",
1175
0
     function );
1176
1177
0
    return( -1 );
1178
0
  }
1179
28
  return( 1 );
1180
28
}
1181
1182
/* Retrieves the size of the UTF-8 encoded volume name
1183
 * The returned size includes the end of string character
1184
 * Returns 1 if successful or -1 on error
1185
 */
1186
int libfsapfs_volume_superblock_get_utf8_volume_name_size(
1187
     libfsapfs_volume_superblock_t *volume_superblock,
1188
     size_t *utf8_string_size,
1189
     libcerror_error_t **error )
1190
28
{
1191
28
  static char *function = "libfsapfs_volume_superblock_get_utf8_volume_name_size";
1192
1193
28
  if( volume_superblock == NULL )
1194
0
  {
1195
0
    libcerror_error_set(
1196
0
     error,
1197
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1198
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1199
0
     "%s: invalid volume superblock.",
1200
0
     function );
1201
1202
0
    return( -1 );
1203
0
  }
1204
28
  if( libuna_utf8_string_size_from_utf8_stream(
1205
28
       volume_superblock->volume_name,
1206
28
       256,
1207
28
       utf8_string_size,
1208
28
       error ) != 1 )
1209
4
  {
1210
4
    libcerror_error_set(
1211
4
     error,
1212
4
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1213
4
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1214
4
     "%s: unable to retrieve UTF-8 string size.",
1215
4
     function );
1216
1217
4
    return( -1 );
1218
4
  }
1219
24
  return( 1 );
1220
28
}
1221
1222
/* Retrieves the UTF-8 encoded volume name
1223
 * The size should include the end of string character
1224
 * Returns 1 if successful or -1 on error
1225
 */
1226
int libfsapfs_volume_superblock_get_utf8_volume_name(
1227
     libfsapfs_volume_superblock_t *volume_superblock,
1228
     uint8_t *utf8_string,
1229
     size_t utf8_string_size,
1230
     libcerror_error_t **error )
1231
28
{
1232
28
  static char *function = "libfsapfs_volume_superblock_get_utf8_volume_name";
1233
1234
28
  if( volume_superblock == NULL )
1235
0
  {
1236
0
    libcerror_error_set(
1237
0
     error,
1238
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1239
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1240
0
     "%s: invalid volume superblock.",
1241
0
     function );
1242
1243
0
    return( -1 );
1244
0
  }
1245
28
  if( libuna_utf8_string_copy_from_utf8_stream(
1246
28
       utf8_string,
1247
28
       utf8_string_size,
1248
28
       volume_superblock->volume_name,
1249
28
       256,
1250
28
       error ) != 1 )
1251
4
  {
1252
4
    libcerror_error_set(
1253
4
     error,
1254
4
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1255
4
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1256
4
     "%s: unable to retrieve UTF-8 string.",
1257
4
     function );
1258
1259
4
    return( -1 );
1260
4
  }
1261
24
  return( 1 );
1262
28
}
1263
1264
/* Retrieves the size of the UTF-16 encoded volume name
1265
 * The returned size includes the end of string character
1266
 * Returns 1 if successful or -1 on error
1267
 */
1268
int libfsapfs_volume_superblock_get_utf16_volume_name_size(
1269
     libfsapfs_volume_superblock_t *volume_superblock,
1270
     size_t *utf16_string_size,
1271
     libcerror_error_t **error )
1272
0
{
1273
0
  static char *function = "libfsapfs_volume_superblock_get_utf16_volume_name_size";
1274
1275
0
  if( volume_superblock == NULL )
1276
0
  {
1277
0
    libcerror_error_set(
1278
0
     error,
1279
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1280
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1281
0
     "%s: invalid volume superblock.",
1282
0
     function );
1283
1284
0
    return( -1 );
1285
0
  }
1286
0
  if( libuna_utf16_string_size_from_utf8_stream(
1287
0
       volume_superblock->volume_name,
1288
0
       256,
1289
0
       utf16_string_size,
1290
0
       error ) != 1 )
1291
0
  {
1292
0
    libcerror_error_set(
1293
0
     error,
1294
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1295
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1296
0
     "%s: unable to retrieve UTF-16 string size.",
1297
0
     function );
1298
1299
0
    return( -1 );
1300
0
  }
1301
0
  return( 1 );
1302
0
}
1303
1304
/* Retrieves the UTF-16 encoded volume name
1305
 * The size should include the end of string character
1306
 * Returns 1 if successful or -1 on error
1307
 */
1308
int libfsapfs_volume_superblock_get_utf16_volume_name(
1309
     libfsapfs_volume_superblock_t *volume_superblock,
1310
     uint16_t *utf16_string,
1311
     size_t utf16_string_size,
1312
     libcerror_error_t **error )
1313
0
{
1314
0
  static char *function = "libfsapfs_volume_superblock_get_utf16_volume_name";
1315
1316
0
  if( volume_superblock == NULL )
1317
0
  {
1318
0
    libcerror_error_set(
1319
0
     error,
1320
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1321
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1322
0
     "%s: invalid volume superblock.",
1323
0
     function );
1324
1325
0
    return( -1 );
1326
0
  }
1327
0
  if( libuna_utf16_string_copy_from_utf8_stream(
1328
0
       utf16_string,
1329
0
       utf16_string_size,
1330
0
       volume_superblock->volume_name,
1331
0
       256,
1332
0
       error ) != 1 )
1333
0
  {
1334
0
    libcerror_error_set(
1335
0
     error,
1336
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1337
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1338
0
     "%s: unable to retrieve UTF-16 string.",
1339
0
     function );
1340
1341
0
    return( -1 );
1342
0
  }
1343
0
  return( 1 );
1344
0
}
1345