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