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