/* Empties the area * Returns 1 if successful or -1 on error */ int libfdata_area_empty( libfdata_area_t *area, libcerror_error_t **error ) { libfdata_internal_area_t *internal_area = NULL; static char *function = "libfdata_area_empty"; if( area == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid area.", function ); return( -1 ); } internal_area = (libfdata_internal_area_t *) area; if( libcdata_array_empty( internal_area->segments_array, (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_range_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to empty segments array.", function ); return( -1 ); } if( libcdata_array_empty( internal_area->mapped_ranges_array, (int (*)(intptr_t **, libcerror_error_t **)) &libfdata_mapped_range_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to empty mapped ranges array.", function ); return( -1 ); } internal_area->size = 0; return( 1 ); }
/* Closes the mount handle * Returns the 0 if succesful or -1 on error */ int mount_handle_close_input( mount_handle_t *mount_handle, libcerror_error_t **error ) { static char *function = "mount_handle_close_input"; int result = 0; if( mount_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid mount handle.", function ); return( -1 ); } if( libcdata_array_empty( mount_handle->logical_volumes_array, (int (*)(intptr_t **, libcerror_error_t **)) &libvslvm_logical_volume_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to empty logical volumes array.", function ); result = -1; } if( libvslvm_volume_group_free( &( mount_handle->volume_group ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free volume group.", function ); result = -1; } if( libvslvm_handle_close( mount_handle->input_handle, error ) != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_CLOSE_FAILED, "%s: unable to close input handle.", function ); result = -1; } return( result ); }
/* Opens the input of the mount handle * Returns 1 if successful, 0 if the keys could not be read or -1 on error */ int mount_handle_open_input( mount_handle_t *mount_handle, const libcstring_system_character_t *filename, libcerror_error_t **error ) { libcstring_system_character_t *basename_end = NULL; libvhdi_file_t *input_file = NULL; static char *function = "mount_handle_open_input"; size_t basename_length = 0; size_t filename_length = 0; int entry_index = 0; if( mount_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid mount handle.", function ); return( -1 ); } if( filename == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid filename.", function ); return( -1 ); } filename_length = libcstring_system_string_length( filename ); basename_end = libcstring_system_string_search_character_reverse( filename, (libcstring_system_character_t) LIBCPATH_SEPARATOR, filename_length + 1 ); if( basename_end != NULL ) { basename_length = (size_t) ( basename_end - filename ) + 1; } if( basename_length > 0 ) { if( mount_handle_set_basename( mount_handle, filename, basename_length, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set basename.", function ); goto on_error; } } if( libvhdi_file_initialize( &input_file, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to initialize input file.", function ); goto on_error; } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) if( libvhdi_file_open_wide( input_file, filename, LIBVHDI_OPEN_READ, error ) != 1 ) #else if( libvhdi_file_open( input_file, filename, LIBVHDI_OPEN_READ, error ) != 1 ) #endif { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_OPEN_FAILED, "%s: unable to open input file.", function ); goto on_error; } if( mount_handle_open_input_parent_file( mount_handle, input_file, error ) == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_OPEN_FAILED, "%s: unable to open parent input file.", function ); goto on_error; } if( libcdata_array_append_entry( mount_handle->input_files_array, &entry_index, (intptr_t *) input_file, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append input file to array.", function ); goto on_error; } return( 1 ); on_error: if( input_file != NULL ) { libvhdi_file_free( &input_file, NULL ); } libcdata_array_empty( mount_handle->input_files_array, (int (*)(intptr_t **, libcerror_error_t **)) &libvhdi_file_free, NULL ); return( -1 ); }
/* Reads the metadata area * Returns 1 if successful or -1 on error */ int libvslvm_metadata_area_read( libvslvm_metadata_area_t *metadata_area, libbfio_handle_t *file_io_handle, off64_t file_offset, libcerror_error_t **error ) { vslvm_raw_location_descriptor_t raw_location_descriptor_data; vslvm_metadata_area_header_t metadata_area_header; libvslvm_raw_location_descriptor_t *raw_location_descriptor = NULL; static char *function = "libvslvm_metadata_area_read"; ssize_t read_count = 0; uint64_t offset = 0; uint64_t size = 0; uint32_t checksum = 0; uint32_t flags = 0; int entry_index = 0; int result = 0; #if defined( HAVE_DEBUG_OUTPUT ) uint64_t value_64bit = 0; uint32_t value_32bit = 0; #endif if( metadata_area == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid metadata area.", function ); return( -1 ); } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: reading metadata area at offset: %" PRIi64 "\n", function, file_offset ); } #endif if( libbfio_handle_seek_offset( file_io_handle, file_offset, SEEK_SET, error ) == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_SEEK_FAILED, "%s: unable to seek offset: %" PRIi64 " (0x%08" PRIx64 ").", function, file_offset, file_offset ); goto on_error; } read_count = libbfio_handle_read_buffer( file_io_handle, (uint8_t *) &metadata_area_header, sizeof( vslvm_metadata_area_header_t ), error ); if( read_count != (ssize_t) sizeof( vslvm_metadata_area_header_t ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read metadata area header.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: metadata area header data:\n", function ); libcnotify_print_data( (uint8_t *) &metadata_area_header, sizeof( vslvm_metadata_area_header_t ), 0 ); } #endif if( memory_compare( metadata_area_header.signature, vslvm_metadata_area_signature, 8 ) != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported metadata area signature.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { byte_stream_copy_to_uint32_little_endian( metadata_area_header.checksum, value_32bit ); libcnotify_printf( "%s: checksum\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); libcnotify_printf( "%s: signature\t\t\t\t\t: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", function, metadata_area_header.signature[ 0 ], metadata_area_header.signature[ 1 ], metadata_area_header.signature[ 2 ], metadata_area_header.signature[ 3 ], metadata_area_header.signature[ 4 ], metadata_area_header.signature[ 5 ], metadata_area_header.signature[ 6 ], metadata_area_header.signature[ 7 ], metadata_area_header.signature[ 8 ], metadata_area_header.signature[ 9 ], metadata_area_header.signature[ 10 ], metadata_area_header.signature[ 11 ], metadata_area_header.signature[ 12 ], metadata_area_header.signature[ 13 ], metadata_area_header.signature[ 14 ], metadata_area_header.signature[ 15 ] ); byte_stream_copy_to_uint32_little_endian( metadata_area_header.version, value_32bit ); libcnotify_printf( "%s: version\t\t\t\t\t: %" PRIu32 "\n", function, value_32bit ); byte_stream_copy_to_uint64_little_endian( metadata_area_header.data_offset, value_64bit ); libcnotify_printf( "%s: data offset\t\t\t\t: 0x%08" PRIx64 "\n", function, value_64bit ); byte_stream_copy_to_uint64_little_endian( metadata_area_header.data_size, value_64bit ); libcnotify_printf( "%s: data size\t\t\t\t\t: %" PRIu64 "\n", function, value_64bit ); libcnotify_printf( "\n" ); } #endif /* TODO calculate checksum */ do { read_count = libbfio_handle_read_buffer( file_io_handle, (uint8_t *) &raw_location_descriptor_data, sizeof( vslvm_raw_location_descriptor_t ), error ); if( read_count != (ssize_t) sizeof( vslvm_raw_location_descriptor_t ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read raw location descriptor.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: raw location descriptor data:\n", function ); libcnotify_print_data( (uint8_t *) &raw_location_descriptor_data, sizeof( vslvm_raw_location_descriptor_t ), 0 ); } #endif result = memory_compare( (uint8_t *) &raw_location_descriptor_data, vslvm_empty_raw_location_descriptor, sizeof( vslvm_raw_location_descriptor_t ) ); if( result != 0 ) { byte_stream_copy_to_uint64_little_endian( raw_location_descriptor_data.offset, offset ); byte_stream_copy_to_uint64_little_endian( raw_location_descriptor_data.size, size ); byte_stream_copy_to_uint32_little_endian( raw_location_descriptor_data.checksum, checksum ); byte_stream_copy_to_uint32_little_endian( raw_location_descriptor_data.flags, flags ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: offset\t\t\t\t\t: 0x%08" PRIx64 "\n", function, offset ); libcnotify_printf( "%s: size\t\t\t\t\t: %" PRIu64 "\n", function, size ); libcnotify_printf( "%s: checksum\t\t\t\t\t: 0x%08" PRIx32 "\n", function, checksum ); libcnotify_printf( "%s: flags\t\t\t\t\t: 0x%08" PRIx32 "\n", function, flags ); libcnotify_printf( "\n" ); } #endif if( ( flags & LIBVSLVM_RAW_LOCATION_DESCRIPTOR_FLAG_IGNORE ) == 0 ) { if( libvslvm_raw_location_descriptor_initialize( &raw_location_descriptor, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create raw location descriptor.", function ); goto on_error; } if( libvslvm_raw_location_descriptor_set( raw_location_descriptor, (off64_t) ( file_offset + offset ), (size64_t) size, checksum, flags, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set raw location descriptor.", function ); goto on_error; } if( libcdata_array_append_entry( metadata_area->raw_location_descriptors_array, &entry_index, (intptr_t *) raw_location_descriptor, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append entry to raw location descriptors array.", function ); goto on_error; } raw_location_descriptor = NULL; } } } while( result != 0 ); return( 1 ); on_error: if( raw_location_descriptor != NULL ) { libvslvm_raw_location_descriptor_free( &raw_location_descriptor, NULL ); } libcdata_array_empty( metadata_area->raw_location_descriptors_array, (int (*)(intptr_t **, libcerror_error_t **)) &libvslvm_raw_location_descriptor_free, NULL ); return( -1 ); }
/* Closes a handle * Returns 0 if successful or -1 on error */ int libvsmbr_handle_close( libvsmbr_handle_t *handle, libcerror_error_t **error ) { libvsmbr_internal_handle_t *internal_handle = NULL; static char *function = "libvsmbr_handle_close"; int result = 0; if( handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid handle.", function ); return( -1 ); } internal_handle = (libvsmbr_internal_handle_t *) handle; if( internal_handle->file_io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid handle - missing file IO handle.", function ); return( -1 ); } if( internal_handle->file_io_handle_created_in_library != 0 ) { #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( libvsmbr_debug_print_read_offsets( internal_handle->file_io_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_PRINT_FAILED, "%s: unable to print the read offsets.", function ); result = -1; } } #endif if( libbfio_handle_close( internal_handle->file_io_handle, error ) != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_CLOSE_FAILED, "%s: unable to close file IO handle.", function ); result = -1; } if( libbfio_handle_free( &( internal_handle->file_io_handle ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free file IO handle.", function ); result = -1; } } internal_handle->file_io_handle = NULL; internal_handle->file_io_handle_created_in_library = 0; if( libcdata_array_empty( internal_handle->partitions_array, (int (*)(intptr_t **, libcerror_error_t **)) &libvsmbr_partition_values_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED, "%s: unable to empty the partitions array.", function ); result = -1; } if( libcdata_array_empty( internal_handle->sections_array, (int (*)(intptr_t **, libcerror_error_t **)) &libvsmbr_section_values_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED, "%s: unable to empty the sections array.", function ); result = -1; } return( result ); }
/* Reads the items into the items array * Returns 1 if successful or -1 on error */ int libnk2_file_read_items( libnk2_internal_file_t *internal_file, libbfio_handle_t *file_io_handle, uint32_t number_of_items, libcerror_error_t **error ) { uint8_t number_of_record_entries_data[ 4 ]; libnk2_item_t *item = NULL; static char *function = "libnk2_file_read_items"; ssize_t read_count = 0; uint32_t item_index = 0; uint32_t number_of_record_entries = 0; int entry_index = 0; if( internal_file == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid internal file.", function ); return( -1 ); } if( libcdata_array_empty( internal_file->items_array, (int (*)(intptr_t **, libcerror_error_t **)) &libnk2_internal_item_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to empty items array.", function ); goto on_error; } for( item_index = 0; item_index < number_of_items; item_index++ ) { read_count = libbfio_handle_read_buffer( file_io_handle, number_of_record_entries_data, 4, error ); if( read_count != (ssize_t) 4 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read item: %" PRIu32 " number of record entries data.", function, item_index ); goto on_error; } byte_stream_copy_to_uint32_little_endian( number_of_record_entries_data, number_of_record_entries ); if( number_of_record_entries == 0 ) { break; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: item: %03" PRIu32 " number of record entries\t\t: %" PRIu32 "\n", function, item_index, number_of_record_entries ); libcnotify_printf( "\n" ); } #endif if( libnk2_item_initialize( &item, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create item.", function ); goto on_error; } if( libnk2_item_read_record_entries( (libnk2_internal_item_t *) item, internal_file->io_handle, file_io_handle, item_index, number_of_record_entries, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read record entries: %" PRIu32 ".", function, item_index ); goto on_error; } if( libcdata_array_append_entry( internal_file->items_array, &entry_index, (intptr_t *) item, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append record entries to items array.", function ); goto on_error; } item = NULL; } return( 1 ); on_error: if( item != NULL ) { libnk2_item_free( &item, NULL ); } libcdata_array_empty( internal_file->items_array, (int (*)(intptr_t **, libcerror_error_t **)) &libnk2_internal_item_free, NULL ); return( -1 ); }
/* Opens a file for reading * Returns 1 if successful or -1 on error */ int libnk2_file_open_read( libnk2_internal_file_t *internal_file, libbfio_handle_t *file_io_handle, libcerror_error_t **error ) { libnk2_file_footer_t *file_footer = NULL; libnk2_file_header_t *file_header = NULL; static char *function = "libnk2_file_open_read"; if( internal_file == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid internal file.", function ); return( -1 ); } if( internal_file->io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid internal file - missing IO handle.", function ); return( -1 ); } internal_file->io_handle->abort = 0; #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "Reading file header:\n" ); } #endif if( libnk2_file_header_initialize( &file_header, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create file header.", function ); goto on_error; } if( libnk2_file_header_read_file_io_handle( file_header, file_io_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read file header.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "Reading items:\n" ); } #endif if( libnk2_file_read_items( internal_file, file_io_handle, file_header->number_of_items, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read items.", function ); goto on_error; } if( libnk2_file_header_free( &file_header, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free file header.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "Reading file footer:\n" ); } #endif if( libnk2_file_footer_initialize( &file_footer, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create file footer.", function ); goto on_error; } if( libnk2_file_footer_read_file_io_handle( file_footer, file_io_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read file footer.", function ); goto on_error; } internal_file->modification_time = file_footer->modification_time; if( libnk2_file_footer_free( &file_footer, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free file footer.", function ); goto on_error; } internal_file->io_handle->abort = 0; return( 1 ); on_error: if( file_footer != NULL ) { libnk2_file_footer_free( &file_footer, NULL ); } if( file_header != NULL ) { libnk2_file_header_free( &file_header, NULL ); } libcdata_array_empty( internal_file->items_array, (int (*)(intptr_t **, libcerror_error_t **)) &libnk2_internal_item_free, NULL ); internal_file->io_handle->abort = 0; return( -1 ); }
/* Opens a volume for reading * Returns 1 if successful or -1 on error */ int libvshadow_volume_open_read( libvshadow_internal_volume_t *internal_volume, libbfio_handle_t *file_io_handle, libcerror_error_t **error ) { libvshadow_store_descriptor_t *last_store_descriptor = NULL; libvshadow_store_descriptor_t *store_descriptor = NULL; static char *function = "libvshadow_volume_open_read"; off64_t catalog_offset = 0; int number_of_store_descriptors = 0; int store_descriptor_index = 0; if( internal_volume == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid volume.", function ); return( -1 ); } if( internal_volume->io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid volume - missing IO handle.", function ); return( -1 ); } #if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT ) if( libcthreads_read_write_lock_grab_for_write( internal_volume->read_write_lock, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to grab read/write lock for writing.", function ); return( -1 ); } #endif #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "Reading NTFS volume header:\n" ); } #endif if( libvshadow_io_handle_read_ntfs_volume_header( internal_volume->io_handle, file_io_handle, &( internal_volume->size ), error ) == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read NTFS volume header.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "Reading VSS volume header:\n" ); } #endif if( libvshadow_io_handle_read_volume_header( internal_volume->io_handle, file_io_handle, (off64_t) 0x1e00, &catalog_offset, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read volume header.", function ); goto on_error; } if( catalog_offset > 0 ) { #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "Reading VSS catalog:\n" ); } #endif if( libvshadow_io_handle_read_catalog( internal_volume->io_handle, file_io_handle, catalog_offset, &( internal_volume->size ), internal_volume->store_descriptors_array, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read catalog.", function ); goto on_error; } if( libcdata_array_get_number_of_entries( internal_volume->store_descriptors_array, &number_of_store_descriptors, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve number of store descriptors from array.", function ); goto on_error; } for( store_descriptor_index = 0; store_descriptor_index < number_of_store_descriptors; store_descriptor_index++ ) { if( libcdata_array_get_entry_by_index( internal_volume->store_descriptors_array, store_descriptor_index, (intptr_t **) &store_descriptor, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve store descriptor: %d.", function, store_descriptor_index ); goto on_error; } store_descriptor->index = store_descriptor_index; #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "Reading VSS store: %02d:\n", store_descriptor->index ); } #endif if( libvshadow_store_descriptor_read_store_header( store_descriptor, file_io_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read store: %d header.", function, store_descriptor->index ); goto on_error; } store_descriptor->previous_store_descriptor = last_store_descriptor; if( last_store_descriptor != NULL ) { last_store_descriptor->next_store_descriptor = store_descriptor; } last_store_descriptor = store_descriptor; store_descriptor = NULL; } } #if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT ) if( libcthreads_read_write_lock_release_for_write( internal_volume->read_write_lock, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to release read/write lock for writing.", function ); return( -1 ); } #endif return( 1 ); on_error: internal_volume->size = 0; libcdata_array_empty( internal_volume->store_descriptors_array, (int (*)(intptr_t **, libcerror_error_t **)) &libvshadow_store_descriptor_free, NULL ); #if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT ) libcthreads_read_write_lock_release_for_write( internal_volume->read_write_lock, NULL ); #endif return( -1 ); }
/* Closes a volume * Returns 0 if successful or -1 on error */ int libvshadow_volume_close( libvshadow_volume_t *volume, libcerror_error_t **error ) { libvshadow_internal_volume_t *internal_volume = NULL; static char *function = "libvshadow_volume_close"; int result = 0; if( volume == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid volume.", function ); return( -1 ); } internal_volume = (libvshadow_internal_volume_t *) volume; if( internal_volume->io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid volume - missing IO handle.", function ); return( -1 ); } #if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT ) if( libcthreads_read_write_lock_grab_for_write( internal_volume->read_write_lock, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to grab read/write lock for writing.", function ); return( -1 ); } #endif #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( internal_volume->file_io_handle_created_in_library != 0 ) { if( libvshadow_debug_print_read_offsets( internal_volume->file_io_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_PRINT_FAILED, "%s: unable to print the read offsets.", function ); } } } #endif if( internal_volume->file_io_handle_opened_in_library != 0 ) { if( libbfio_handle_close( internal_volume->file_io_handle, error ) != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_CLOSE_FAILED, "%s: unable to close file IO handle.", function ); result = -1; } internal_volume->file_io_handle_opened_in_library = 0; } if( internal_volume->file_io_handle_created_in_library != 0 ) { if( libbfio_handle_free( &( internal_volume->file_io_handle ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free file IO handle.", function ); result = -1; } internal_volume->file_io_handle_created_in_library = 0; } internal_volume->file_io_handle = NULL; internal_volume->size = 0; if( libvshadow_io_handle_clear( internal_volume->io_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to clear IO handle.", function ); result = -1; } if( libcdata_array_empty( internal_volume->store_descriptors_array, (int (*)(intptr_t **, libcerror_error_t **)) &libvshadow_store_descriptor_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to empty store descriptors array.", function ); result = -1; } #if defined( HAVE_LIBVSHADOW_MULTI_THREAD_SUPPORT ) if( libcthreads_read_write_lock_release_for_write( internal_volume->read_write_lock, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to release read/write lock for writing.", function ); return( -1 ); } #endif return( result ); }
/* Retrieves the table of contents from the optical disk using IOCTL * Returns 1 if successful, 0 if not or -1 on error */ int libsmdev_optical_disc_get_table_of_contents_ioctl( libcfile_file_t *device_file, libsmdev_internal_handle_t *internal_handle, libcerror_error_t **error ) { struct cdrom_tochdr toc_header; struct cdrom_tocentry toc_entry; static char *function = "libsmdev_optical_disc_get_table_of_contents_ioctl"; ssize_t read_count = 0; uint32_t last_session_size = 0; uint32_t last_session_offset = 0; uint32_t last_track_size = 0; uint32_t last_track_offset = 0; uint32_t offset = 0; uint16_t entry_index = 0; uint8_t first_entry = 0; uint8_t last_entry = 0; uint8_t last_track_type = 0; uint8_t session_index = 0; uint8_t track_index = 0; uint8_t track_type = 0; int result = 0; read_count = libcfile_file_io_control_read( device_file, CDROMREADTOCHDR, NULL, 0, (uint8_t *) &toc_header, sizeof( struct cdrom_tochdr ), error ); if( read_count == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_IOCTL_FAILED, "%s: unable to query device for: CDROMREADTOCHDR.", function ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( ( error != NULL ) && ( *error != NULL ) ) { libcnotify_print_error_backtrace( *error ); } } #endif libcerror_error_free( error ); return( 0 ); } first_entry = toc_header.cdth_trk0; last_entry = toc_header.cdth_trk1; #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: number of entries\t: %" PRIu8 "\n", function, last_entry ); } #endif for( entry_index = (uint16_t) first_entry; entry_index <= (uint16_t) last_entry; entry_index++ ) { if( memory_set( &toc_entry, 0, sizeof( struct cdrom_tocentry ) ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear TOC entry.", function ); goto on_error; } toc_entry.cdte_track = (uint8_t) entry_index; toc_entry.cdte_format = CDROM_LBA; read_count = libcfile_file_io_control_read( device_file, CDROMREADTOCENTRY, NULL, 0, (uint8_t *) &toc_entry, sizeof( struct cdrom_tocentry ), error ); if( read_count == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_IOCTL_FAILED, "%s: unable to query device for: CDROMREADTOCENTRY.", function ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( ( error != NULL ) && ( *error != NULL ) ) { libcnotify_print_error_backtrace( *error ); } } #endif libcerror_error_free( error ); break; } if( toc_entry.cdte_format == CDROM_LBA ) { offset = (uint32_t) toc_entry.cdte_addr.lba; } else if( toc_entry.cdte_format == CDROM_MSF ) { libsmdev_optical_disc_copy_msf_to_lba( toc_entry.cdte_addr.msf.minute, toc_entry.cdte_addr.msf.second, toc_entry.cdte_addr.msf.frame, offset ); } else { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported CDTE format.", function ); goto on_error; } if( ( toc_entry.cdte_ctrl & CDROM_DATA_TRACK ) == 0 ) { track_type = LIBSMDEV_TRACK_TYPE_AUDIO; } else { track_type = LIBSMDEV_TRACK_TYPE_MODE1_2048; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: entry: %" PRIu16 "", function, entry_index ); if( ( toc_entry.cdte_ctrl & CDROM_DATA_TRACK ) == 0 ) { libcnotify_printf( " (audio)" ); } else { libcnotify_printf( " (data)" ); } if( toc_entry.cdte_format == CDROM_LBA ) { libcnotify_printf( " start\t: %" PRIu32 "", toc_entry.cdte_addr.lba ); } else if( toc_entry.cdte_format == CDROM_MSF ) { libcnotify_printf( " start\t: %02" PRIu8 ":%02" PRIu8 ".%02" PRIu8 "", toc_entry.cdte_addr.msf.minute, toc_entry.cdte_addr.msf.second, toc_entry.cdte_addr.msf.frame ); } libcnotify_printf( " (offset: %" PRIu32 ")\n", offset ); } #endif if( entry_index > first_entry ) { if( ( offset < last_track_offset ) || ( offset < last_session_offset ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid offset value out of bounds.", function ); goto on_error; } last_track_size = offset - last_track_offset; if( ( last_track_type == LIBSMDEV_TRACK_TYPE_MODE1_2048 ) || ( last_track_type != track_type ) ) { if( session_index == 0 ) { if( last_track_size < 11400 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid last track size value out of bounds.", function ); goto on_error; } last_track_size -= 11400; } else { if( last_track_size < 6900 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid last track size value out of bounds.", function ); goto on_error; } last_track_size -= 6900; } } if( libsmdev_handle_append_track( internal_handle, last_track_offset, last_track_size, last_track_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append track: %" PRIu8 ".", function, track_index ); goto on_error; } track_index++; if( ( last_track_type == LIBSMDEV_TRACK_TYPE_MODE1_2048 ) || ( last_track_type != track_type ) ) { last_session_size = offset - last_session_offset; if( libsmdev_handle_append_session( internal_handle, last_session_offset, last_session_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append session: %" PRIu8 ".", function, session_index ); goto on_error; } session_index++; last_session_offset = offset; } } last_track_offset = offset; last_track_type = track_type; } if( read_count != -1 ) { if( memory_set( &toc_entry, 0, sizeof( struct cdrom_tocentry ) ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear TOC entry.", function ); goto on_error; } toc_entry.cdte_track = CDROM_LEADOUT; toc_entry.cdte_format = CDROM_LBA; read_count = libcfile_file_io_control_read( device_file, CDROMREADTOCENTRY, NULL, 0, (uint8_t *) &toc_entry, sizeof( struct cdrom_tocentry ), error ); if( read_count == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_IOCTL_FAILED, "%s: unable to query device for: CDROMREADTOCENTRY.", function ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( ( error != NULL ) && ( *error != NULL ) ) { libcnotify_print_error_backtrace( *error ); } } #endif libcerror_error_free( error ); } else { if( toc_entry.cdte_format == CDROM_LBA ) { offset = (uint32_t) toc_entry.cdte_addr.lba; } else if( toc_entry.cdte_format == CDROM_MSF ) { libsmdev_optical_disc_copy_msf_to_lba( toc_entry.cdte_addr.msf.minute, toc_entry.cdte_addr.msf.second, toc_entry.cdte_addr.msf.frame, offset ); } else { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported CDTE format.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "\tLead out" ); if( ( toc_entry.cdte_ctrl & CDROM_DATA_TRACK ) == 0 ) { libcnotify_printf( " (audio)" ); } else { libcnotify_printf( " (data)" ); } if( toc_entry.cdte_format == CDROM_LBA ) { libcnotify_printf( " start:\t%" PRIu32 "", toc_entry.cdte_addr.lba ); } else if( toc_entry.cdte_format == CDROM_MSF ) { libcnotify_printf( " start:\t%02" PRIu8 ":%02" PRIu8 ".02%" PRIu8 "", toc_entry.cdte_addr.msf.minute, toc_entry.cdte_addr.msf.second, toc_entry.cdte_addr.msf.frame ); } libcnotify_printf( " (offset: %" PRIu32 ")\n\n", offset ); } #endif if( ( offset < last_track_offset ) || ( offset < last_session_offset ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid offset value out of bounds.", function ); goto on_error; } last_track_size = offset - last_track_offset; if( libsmdev_handle_append_track( internal_handle, last_track_offset, last_track_size, last_track_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append last track: %" PRIu8 ".", function, track_index ); goto on_error; } last_session_size = offset - last_session_offset; if( libsmdev_handle_append_session( internal_handle, last_session_offset, last_session_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append session: %" PRIu8 ".", function, session_index ); goto on_error; } result = 1; } } if( result == 0 ) { if( libcdata_array_empty( internal_handle->tracks_array, (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_track_value_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to empty tracks array.", function ); goto on_error; } if( libcdata_array_empty( internal_handle->sessions_array, (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_sector_range_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to empty sessions array.", function ); goto on_error; } } return( result ); on_error: libcdata_array_empty( internal_handle->tracks_array, (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_track_value_free, NULL ); libcdata_array_empty( internal_handle->sessions_array, (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_sector_range_free, NULL ); return( -1 ); }
/* Retrieves the table of contents from the optical disk using the SCSI READ TOC command * Returns 1 if successful, 0 if not or -1 on error */ int libsmdev_optical_disc_get_table_of_contents_scsi( libcfile_file_t *device_file, libsmdev_internal_handle_t *internal_handle, libcerror_error_t **error ) { uint8_t track_info_data[ 64 ]; uint8_t *toc_data = NULL; uint8_t *toc_entries = NULL; static char *function = "libsmdev_optical_disc_get_table_of_contents_scsi"; void *reallocation = NULL; size_t toc_data_offset = 0; size_t toc_data_size = 0; ssize_t read_count = 0; uint32_t lead_out_size = 0; uint32_t lead_out_offset = 0; uint32_t last_track_offset = 0; uint32_t track_offset = 0; uint32_t session_size = 0; uint32_t session_offset = 0; uint32_t next_session_offset = 0; uint16_t entry_index = 0; uint8_t first_track_number = 0; uint8_t last_track_number = 0; uint8_t lead_out_index = 0; uint8_t number_of_sessions = 0; uint8_t session_index = 0; uint8_t track_index = 0; uint8_t track_number = 0; uint8_t track_type = 0; int result = 0; toc_data_size = 1024; toc_data = (uint8_t *) memory_allocate( sizeof( uint8_t ) * toc_data_size ); if( toc_data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create TOC data.", function ); goto on_error; } if( memory_set( toc_data, 0, sizeof( uint8_t ) * toc_data_size ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear TOC data.", function ); goto on_error; } read_count = libsmdev_scsi_read_toc( device_file, LIBSMDEV_SCSI_TOC_CDB_FORMAT_RAW_TOC, toc_data, toc_data_size, error ); if( read_count == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve TOC.", function ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( ( error != NULL ) && ( *error != NULL ) ) { libcnotify_print_error_backtrace( *error ); } } #endif libcerror_error_free( error ); byte_stream_copy_to_uint16_big_endian( toc_data, toc_data_size ); if( toc_data_size > 1024 ) { reallocation = memory_reallocate( toc_data, sizeof( uint8_t ) * toc_data_size ); if( reallocation == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to resize TOC data.", function ); goto on_error; } toc_data = (uint8_t *) reallocation; read_count = libsmdev_scsi_read_toc( device_file, LIBSMDEV_SCSI_TOC_CDB_FORMAT_RAW_TOC, toc_data, toc_data_size, error ); if( read_count == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve TOC.", function ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( ( error != NULL ) && ( *error != NULL ) ) { libcnotify_print_error_backtrace( *error ); } } #endif libcerror_error_free( error ); } } } toc_data_size = (size_t) read_count; if( toc_data_size > 4 ) { #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: header:\n", function ); libcnotify_print_data( toc_data, 4, 0 ); } #endif number_of_sessions = (uint16_t) toc_data[ 3 ]; #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: number of sessions\t\t\t: %" PRIu8 "\n", function, number_of_sessions ); libcnotify_printf( "\n" ); } #endif toc_entries = &( toc_data[ 4 ] ); toc_data_offset = 4; while( toc_data_offset < (size_t) toc_data_size ) { #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: entry: %02" PRIu16 ":\n", function, entry_index ); libcnotify_print_data( toc_entries, 11, 0 ); } #endif if( toc_entries[ 3 ] <= 0x63 ) { libsmdev_optical_disc_copy_msf_to_lba( toc_entries[ 8 ], toc_entries[ 9 ], toc_entries[ 10 ], track_offset ); } else if( toc_entries[ 3 ] == 0xa0 ) { first_track_number = toc_entries[ 8 ]; } else if( toc_entries[ 3 ] == 0xa1 ) { last_track_number = toc_entries[ 8 ]; } else if( toc_entries[ 3 ] == 0xa2 ) { libsmdev_optical_disc_copy_msf_to_lba( toc_entries[ 8 ], toc_entries[ 9 ], toc_entries[ 10 ], lead_out_offset ); } else if( toc_entries[ 3 ] == 0xb0 ) { libsmdev_optical_disc_copy_absolute_msf_to_lba( toc_entries[ 4 ], toc_entries[ 5 ], toc_entries[ 6 ], next_session_offset ); } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( toc_entries[ 3 ] <= 0x63 ) { libcnotify_printf( "%s: session: %02" PRIu16 " track: %02" PRIu8 "\t\t\t: %02" PRIu8 ":%02" PRIu8 ".%02" PRIu8 " (offset: %" PRIu32 ")\n", function, toc_entries[ 0 ], toc_entries[ 3 ], toc_entries[ 4 ], toc_entries[ 5 ], toc_entries[ 6 ], track_offset ); } else if( toc_entries[ 3 ] == 0xa0 ) { libcnotify_printf( "%s: session: %02" PRIu8 " first track number\t: %" PRIu8 "\n", function, toc_entries[ 0 ], first_track_number ); } else if( toc_entries[ 3 ] == 0xa1 ) { libcnotify_printf( "%s: session: %02" PRIu8 " last track number\t\t: %" PRIu8 "\n", function, toc_entries[ 0 ], last_track_number ); } else if( toc_entries[ 3 ] == 0xa2 ) { libcnotify_printf( "%s: session: %02" PRIu8 " lead out\t\t\t: %02" PRIu8 ":%02" PRIu8 ".%02" PRIu8 " (offset: %" PRIu32 ")\n", function, toc_entries[ 0 ], toc_entries[ 8 ], toc_entries[ 9 ], toc_entries[ 10 ], lead_out_offset ); } else if( toc_entries[ 3 ] == 0xb0 ) { libcnotify_printf( "%s: session: %02" PRIu16 " end\t\t\t: %02" PRIu8 ":%02" PRIu8 ".%02" PRIu8 " (offset: %" PRIu32 ")\n", function, toc_entries[ 0 ], toc_entries[ 4 ], toc_entries[ 5 ], toc_entries[ 6 ], next_session_offset ); } libcnotify_printf( "\n" ); } #endif if( ( toc_entries[ 3 ] <= 0x63 ) || ( toc_entries[ 3 ] == 0xb0 ) ) { if( track_number >= first_track_number ) { if( toc_entries[ 3 ] == 0xb0 ) { track_offset = lead_out_offset; } if( track_offset < last_track_offset ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid track offset value out of bounds.", function ); goto on_error; } if( ( track_index + 1 ) != track_number ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid track number value out of bounds.", function ); goto on_error; } if( toc_entries[ 3 ] == 0xa2 ) { if( track_number != last_track_number ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid track number value out of bounds.", function ); goto on_error; } } if( memory_set( track_info_data, 0, 64 ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear track info data.", function ); goto on_error; } read_count = libsmdev_scsi_read_track_information( device_file, last_track_offset, track_info_data, 64, error ); if( read_count == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve track info data: %d.", function, track_index ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( ( error != NULL ) && ( *error != NULL ) ) { libcnotify_print_error_backtrace( *error ); } } #endif libcerror_error_free( error ); break; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: track information data: %d:\n", function, track_index ); libcnotify_print_data( track_info_data, (size_t) read_count, 0 ); } #endif if( track_info_data[ 2 ] != toc_entries[ 0 ] ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid track information data - session number value out of bounds.", function ); goto on_error; } if( track_info_data[ 3 ] != track_number ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid track information data - track number value out of bounds.", function ); goto on_error; } track_type = LIBSMDEV_TRACK_TYPE_UNKNOWN; if( ( track_info_data[ 5 ] & 0x04 ) != 0 ) { if( ( track_info_data[ 5 ] & 0x08 ) == 0 ) { if( ( track_info_data[ 6 ] & 0x0f ) == 1 ) { track_type = LIBSMDEV_TRACK_TYPE_MODE1_2048; } else if( ( track_info_data[ 6 ] & 0x0f ) == 2 ) { track_type = LIBSMDEV_TRACK_TYPE_MODE2_2048; } } } else { track_type = LIBSMDEV_TRACK_TYPE_AUDIO; } if( libsmdev_handle_append_track( internal_handle, last_track_offset, track_offset - last_track_offset, track_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append track: %d.", function, track_index ); goto on_error; } track_index++; } last_track_offset = track_offset; if( toc_entries[ 3 ] != 0xb0 ) { track_number = toc_entries[ 3 ]; } } if( toc_entries[ 3 ] == 0xb0 ) { if( session_offset >= next_session_offset ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid session offset value out of bounds.", function ); goto on_error; } if( ( session_index + 1 ) != toc_entries[ 0 ] ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid session number value out of bounds.", function ); goto on_error; } lead_out_size = 0; if( ( lead_out_offset >= session_offset ) && ( lead_out_offset < next_session_offset ) ) { lead_out_size = next_session_offset - lead_out_offset; if( libsmdev_handle_append_lead_out( internal_handle, lead_out_offset, lead_out_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append lead_out: %d.", function, lead_out_index ); goto on_error; } lead_out_index++; } session_size = next_session_offset - session_offset; if( ( session_index + 1 ) == number_of_sessions ) { session_size -= lead_out_size; } if( libsmdev_handle_append_session( internal_handle, session_offset, session_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append session: %d.", function, session_index ); goto on_error; } session_offset = next_session_offset; session_index++; } toc_entries += 11; toc_data_offset += 11; entry_index++; } if( ( track_index + 1 ) == track_number ) { if( track_offset < last_track_offset ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid track offset value out of bounds.", function ); goto on_error; } if( memory_set( track_info_data, 0, 64 ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear track info data.", function ); goto on_error; } read_count = libsmdev_scsi_read_track_information( device_file, last_track_offset, track_info_data, 64, error ); if( read_count == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve track info data: %d.", function, track_index ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( ( error != NULL ) && ( *error != NULL ) ) { libcnotify_print_error_backtrace( *error ); } } #endif libcerror_error_free( error ); } else { #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: track information data: %d:\n", function, track_index ); libcnotify_print_data( track_info_data, (size_t) read_count, 0 ); } #endif if( track_info_data[ 2 ] != toc_entries[ 0 ] ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid track information data - session number value out of bounds.", function ); goto on_error; } if( track_info_data[ 3 ] != toc_entries[ 3 ] ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid track information data - track number value out of bounds.", function ); goto on_error; } track_type = LIBSMDEV_TRACK_TYPE_UNKNOWN; if( ( track_info_data[ 5 ] & 0x04 ) != 0 ) { if( ( track_info_data[ 5 ] & 0x08 ) == 0 ) { if( ( track_info_data[ 6 ] & 0x0f ) == 1 ) { track_type = LIBSMDEV_TRACK_TYPE_MODE1_2048; } else if( ( track_info_data[ 6 ] & 0x0f ) == 2 ) { track_type = LIBSMDEV_TRACK_TYPE_MODE2_2048; } } } else { track_type = LIBSMDEV_TRACK_TYPE_AUDIO; } if( libsmdev_handle_append_track( internal_handle, last_track_offset, track_offset - last_track_offset, track_type, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append last track: %d.", function, track_index ); goto on_error; } } if( session_index != number_of_sessions ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid session index value out of bounds.", function ); goto on_error; } result = 1; } } if( result == 0 ) { if( libcdata_array_empty( internal_handle->tracks_array, (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_track_value_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to empty tracks array.", function ); goto on_error; } if( libcdata_array_empty( internal_handle->lead_outs_array, (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_sector_range_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to empty lead outs array.", function ); goto on_error; } if( libcdata_array_empty( internal_handle->sessions_array, (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_sector_range_free, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to empty sessions array.", function ); goto on_error; } } memory_free( toc_data ); toc_data = NULL; return( result ); on_error: if( toc_data != NULL ) { memory_free( toc_data ); } libcdata_array_empty( internal_handle->tracks_array, (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_track_value_free, NULL ); libcdata_array_empty( internal_handle->lead_outs_array, (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_sector_range_free, NULL ); libcdata_array_empty( internal_handle->sessions_array, (int (*)(intptr_t **, libcerror_error_t **)) &libsmdev_sector_range_free, NULL ); return( -1 ); }
/* Opens the mount handle * Returns 1 if successful or -1 on error */ int mount_handle_open_input( mount_handle_t *mount_handle, const libcstring_system_character_t *filename, libcerror_error_t **error ) { libbfio_handle_t *file_io_handle = NULL; libvslvm_logical_volume_t *logical_volume = NULL; static char *function = "mount_handle_open_input"; size_t filename_length = 0; int entry_index = 0; int logical_volume_index = 0; int number_of_logical_volumes = 0; int result = 0; if( mount_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid mount handle.", function ); return( -1 ); } if( libbfio_file_range_initialize( &file_io_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to initialize file IO handle.", function ); goto on_error; } filename_length = libcstring_system_string_length( filename ); #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) if( libbfio_file_range_set_name_wide( file_io_handle, filename, filename_length, error ) != 1 ) #else if( libbfio_file_range_set_name( file_io_handle, filename, filename_length, error ) != 1 ) #endif { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_OPEN_FAILED, "%s: unable to open set file name.", function ); goto on_error; } if( libbfio_file_range_set( file_io_handle, mount_handle->volume_offset, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_OPEN_FAILED, "%s: unable to open set volume offset.", function ); goto on_error; } if( libvslvm_handle_open_file_io_handle( mount_handle->input_handle, file_io_handle, LIBVSLVM_OPEN_READ, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_OPEN_FAILED, "%s: unable to open input handle.", function ); goto on_error; } if( libbfio_pool_append_handle( mount_handle->physical_volume_file_io_pool, &entry_index, file_io_handle, LIBBFIO_OPEN_READ, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_OPEN_FAILED, "%s: unable to open input handle.", function ); goto on_error; } /* The takes over management of the file IO handle */ file_io_handle = NULL; /* TODO determine if the first file is a metadata only file and change filenames accordingly */ if( libvslvm_handle_open_physical_volume_files_file_io_pool( mount_handle->input_handle, mount_handle->physical_volume_file_io_pool, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_OPEN_FAILED, "%s: unable to open physical volume files.", function ); goto on_error; } if( libvslvm_handle_get_volume_group( mount_handle->input_handle, &( mount_handle->volume_group ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve volume group.", function ); goto on_error; } if( libvslvm_volume_group_get_number_of_logical_volumes( mount_handle->volume_group, &number_of_logical_volumes, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve number of logical volumes.", function ); goto on_error; } for( logical_volume_index = 0; logical_volume_index < number_of_logical_volumes; logical_volume_index++ ) { if( libvslvm_volume_group_get_logical_volume( mount_handle->volume_group, logical_volume_index, &logical_volume, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve logical volume: %d.", function, logical_volume_index ); goto on_error; } if( libcdata_array_append_entry( mount_handle->logical_volumes_array, &entry_index, (intptr_t *) logical_volume, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append logical volume to array.", function ); goto on_error; } logical_volume = NULL; } return( 1 ); on_error: if( logical_volume != NULL ) { libvslvm_logical_volume_free( &logical_volume, NULL ); } if( mount_handle->volume_group != NULL ) { libvslvm_volume_group_free( &( mount_handle->volume_group ), NULL ); } if( mount_handle->input_handle != NULL ) { libvslvm_handle_free( &( mount_handle->input_handle ), NULL ); } if( file_io_handle != NULL ) { libbfio_handle_free( &file_io_handle, NULL ); } libcdata_array_empty( mount_handle->logical_volumes_array, (int (*)(intptr_t **, libcerror_error_t **)) &libvslvm_logical_volume_free, NULL ); return( -1 ); }
/* Reads a physical volume label * Returns 1 if successful, 0 if not found or -1 on error */ int libvslvm_physical_volume_read_label( libvslvm_physical_volume_t *physical_volume, libbfio_pool_t *file_io_pool, int file_io_pool_entry, off64_t file_offset, libcerror_error_t **error ) { vslvm_data_area_descriptor_t data_area_descriptor_data; vslvm_physical_volume_label_header_t physical_volume_label_header; vslvm_physical_volume_header_t physical_volume_header; libvslvm_data_area_descriptor_t *data_area_descriptor = NULL; libvslvm_internal_physical_volume_t *internal_physical_volume = NULL; static char *function = "libvslvm_physical_volume_read_label"; ssize_t read_count = 0; uint64_t offset = 0; uint64_t size = 0; int entry_index = 0; int result = 0; #if defined( HAVE_DEBUG_OUTPUT ) uint64_t value_64bit = 0; uint32_t value_32bit = 0; #endif if( physical_volume == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid physical volume.", function ); return( -1 ); } internal_physical_volume = (libvslvm_internal_physical_volume_t *) physical_volume; #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: reading physical volume label at offset: %" PRIi64 "\n", function, file_offset ); } #endif if( libbfio_pool_seek_offset( file_io_pool, file_io_pool_entry, file_offset, SEEK_SET, error ) == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_SEEK_FAILED, "%s: unable to seek offset: %" PRIi64 " (0x%08" PRIx64 ").", function, file_offset, file_offset ); goto on_error; } read_count = libbfio_pool_read_buffer( file_io_pool, file_io_pool_entry, (uint8_t *) &physical_volume_label_header, sizeof( vslvm_physical_volume_label_header_t ), error ); if( read_count != (ssize_t) sizeof( vslvm_physical_volume_label_header_t ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read physical volume label header.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: physical volume label header data:\n", function ); libcnotify_print_data( (uint8_t *) &physical_volume_label_header, sizeof( vslvm_physical_volume_label_header_t ), 0 ); } #endif if( memory_compare( physical_volume_label_header.signature, vslvm_physical_volume_label_signature, 8 ) != 0 ) { return( 0 ); } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: signature\t\t\t\t: %c%c%c%c%c%c%c%c\n", function, physical_volume_label_header.signature[ 0 ], physical_volume_label_header.signature[ 1 ], physical_volume_label_header.signature[ 2 ], physical_volume_label_header.signature[ 3 ], physical_volume_label_header.signature[ 4 ], physical_volume_label_header.signature[ 5 ], physical_volume_label_header.signature[ 6 ], physical_volume_label_header.signature[ 7 ] ); byte_stream_copy_to_uint64_little_endian( physical_volume_label_header.sector_number, value_64bit ); libcnotify_printf( "%s: sector number\t\t\t: %" PRIu64 "\n", function, value_64bit ); byte_stream_copy_to_uint32_little_endian( physical_volume_label_header.checksum, value_32bit ); libcnotify_printf( "%s: checksum\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); byte_stream_copy_to_uint32_little_endian( physical_volume_label_header.data_offset, value_32bit ); libcnotify_printf( "%s: data offset\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); libcnotify_printf( "%s: type indicator\t\t\t: %c%c%c%c%c%c%c%c\n", function, physical_volume_label_header.type_indicator[ 0 ], physical_volume_label_header.type_indicator[ 1 ], physical_volume_label_header.type_indicator[ 2 ], physical_volume_label_header.type_indicator[ 3 ], physical_volume_label_header.type_indicator[ 4 ], physical_volume_label_header.type_indicator[ 5 ], physical_volume_label_header.type_indicator[ 6 ], physical_volume_label_header.type_indicator[ 7 ] ); libcnotify_printf( "\n" ); } #endif /* TODO calculate checksum */ read_count = libbfio_pool_read_buffer( file_io_pool, file_io_pool_entry, (uint8_t *) &physical_volume_header, sizeof( vslvm_physical_volume_header_t ), error ); if( read_count != (ssize_t) sizeof( vslvm_physical_volume_header_t ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read physical volume header.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: physical volume header data:\n", function ); libcnotify_print_data( (uint8_t *) &physical_volume_header, sizeof( vslvm_physical_volume_header_t ), 0 ); } #endif #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: identifier\t\t\t\t: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", function, physical_volume_header.identifier[ 0 ], physical_volume_header.identifier[ 1 ], physical_volume_header.identifier[ 2 ], physical_volume_header.identifier[ 3 ], physical_volume_header.identifier[ 4 ], physical_volume_header.identifier[ 5 ], physical_volume_header.identifier[ 6 ], physical_volume_header.identifier[ 7 ], physical_volume_header.identifier[ 8 ], physical_volume_header.identifier[ 9 ], physical_volume_header.identifier[ 10 ], physical_volume_header.identifier[ 11 ], physical_volume_header.identifier[ 12 ], physical_volume_header.identifier[ 13 ], physical_volume_header.identifier[ 14 ], physical_volume_header.identifier[ 15 ], physical_volume_header.identifier[ 16 ], physical_volume_header.identifier[ 17 ], physical_volume_header.identifier[ 18 ], physical_volume_header.identifier[ 19 ], physical_volume_header.identifier[ 20 ], physical_volume_header.identifier[ 21 ], physical_volume_header.identifier[ 22 ], physical_volume_header.identifier[ 23 ], physical_volume_header.identifier[ 24 ], physical_volume_header.identifier[ 25 ], physical_volume_header.identifier[ 26 ], physical_volume_header.identifier[ 27 ], physical_volume_header.identifier[ 28 ], physical_volume_header.identifier[ 29 ], physical_volume_header.identifier[ 30 ], physical_volume_header.identifier[ 31 ] ); byte_stream_copy_to_uint64_little_endian( physical_volume_header.volume_size, value_64bit ); libcnotify_printf( "%s: volume size\t\t\t: %" PRIu64 "\n", function, value_64bit ); libcnotify_printf( "\n" ); } #endif do { read_count = libbfio_pool_read_buffer( file_io_pool, file_io_pool_entry, (uint8_t *) &data_area_descriptor_data, sizeof( vslvm_data_area_descriptor_t ), error ); if( read_count != (ssize_t) sizeof( vslvm_data_area_descriptor_t ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read data area descriptor.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: data area descriptor data:\n", function ); libcnotify_print_data( (uint8_t *) &data_area_descriptor_data, sizeof( vslvm_data_area_descriptor_t ), 0 ); } #endif result = memory_compare( (uint8_t *) &data_area_descriptor_data, vslvm_empty_data_area_descriptor, sizeof( vslvm_data_area_descriptor_t ) ); if( result != 0 ) { byte_stream_copy_to_uint64_little_endian( data_area_descriptor_data.offset, offset ); byte_stream_copy_to_uint64_little_endian( data_area_descriptor_data.size, size ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: data area offset\t\t\t: 0x%08" PRIx64 "\n", function, offset ); libcnotify_printf( "%s: data area size\t\t\t: %" PRIu64 "\n", function, size ); libcnotify_printf( "\n" ); } #endif if( libvslvm_data_area_descriptor_initialize( &data_area_descriptor, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create data area descriptor.", function ); goto on_error; } if( libvslvm_data_area_descriptor_set( data_area_descriptor, (off64_t) offset, (size64_t) size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set data area descriptor.", function ); goto on_error; } if( libcdata_array_append_entry( internal_physical_volume->data_area_descriptors_array, &entry_index, (intptr_t *) data_area_descriptor, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append entry to data area descriptors array.", function ); goto on_error; } data_area_descriptor = NULL; } } while( result != 0 ); do { read_count = libbfio_pool_read_buffer( file_io_pool, file_io_pool_entry, (uint8_t *) &data_area_descriptor_data, sizeof( vslvm_data_area_descriptor_t ), error ); if( read_count != (ssize_t) sizeof( vslvm_data_area_descriptor_t ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read metadata area descriptor.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: metadata area descriptor data:\n", function ); libcnotify_print_data( (uint8_t *) &data_area_descriptor_data, sizeof( vslvm_data_area_descriptor_t ), 0 ); } #endif result = memory_compare( (uint8_t *) &data_area_descriptor_data, vslvm_empty_data_area_descriptor, sizeof( vslvm_data_area_descriptor_t ) ); if( result != 0 ) { byte_stream_copy_to_uint64_little_endian( data_area_descriptor_data.offset, offset ); byte_stream_copy_to_uint64_little_endian( data_area_descriptor_data.size, size ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: metadata area offset\t\t: 0x%08" PRIx64 "\n", function, offset ); libcnotify_printf( "%s: metadata area size\t\t\t: %" PRIu64 "\n", function, size ); libcnotify_printf( "\n" ); } #endif if( libvslvm_data_area_descriptor_initialize( &data_area_descriptor, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create data area descriptor.", function ); goto on_error; } if( libvslvm_data_area_descriptor_set( data_area_descriptor, (off64_t) offset, (size64_t) size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set data area descriptor.", function ); goto on_error; } if( libcdata_array_append_entry( internal_physical_volume->metadata_area_descriptors_array, &entry_index, (intptr_t *) data_area_descriptor, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append entry to metadata area descriptors array.", function ); goto on_error; } data_area_descriptor = NULL; } } while( result != 0 ); return( 1 ); on_error: if( data_area_descriptor != NULL ) { libvslvm_data_area_descriptor_free( &data_area_descriptor, NULL ); } libcdata_array_empty( internal_physical_volume->metadata_area_descriptors_array, (int (*)(intptr_t **, libcerror_error_t **)) &libvslvm_data_area_descriptor_free, NULL ); libcdata_array_empty( internal_physical_volume->data_area_descriptors_array, (int (*)(intptr_t **, libcerror_error_t **)) &libvslvm_data_area_descriptor_free, NULL ); return( -1 ); }