/* Retrieves an extent file at a specific offset from the extent table * Returns 1 if successful, 0 if not or -1 on error */ int libvmdk_extent_table_get_extent_file_at_offset( libvmdk_extent_table_t *extent_table, off64_t offset, libbfio_pool_t *file_io_pool, int *extent_index, off64_t *extent_file_data_offset, libvmdk_extent_file_t **extent_file, libcerror_error_t **error ) { static char *function = "libvmdk_extent_table_get_extent_file_at_offset"; int result = 0; if( extent_table == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid extent table.", function ); return( -1 ); } result = libfdata_list_get_element_value_at_offset( extent_table->extent_files_list, (intptr_t *) file_io_pool, (libfdata_cache_t *) extent_table->extent_files_cache, offset, extent_index, extent_file_data_offset, (intptr_t **) extent_file, 0, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve element at offset: %" PRIi64 " from extent files list.", function, offset ); return( -1 ); } return( result ); }
/* Retrieves the grain data of a grain at a specific offset * Returns 1 if successful or -1 on error */ int libvmdk_grain_table_get_grain_data_at_offset( libvmdk_grain_table_t *grain_table, uint64_t grain_index, libbfio_pool_t *file_io_pool, libvmdk_extent_table_t *extent_table, libfcache_cache_t *grains_cache, off64_t offset, libvmdk_grain_data_t **grain_data, off64_t *grain_data_offset, libcerror_error_t **error ) { libvmdk_extent_file_t *extent_file = NULL; libfdata_list_t *grains_list = NULL; static char *function = "libvmdk_grain_table_get_grain_data_at_offset"; off64_t grain_group_data_offset = 0; off64_t extent_file_data_offset = 0; int extent_number = 0; int grain_groups_list_index = 0; int grains_list_index = 0; int result = 0; if( grain_table == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid grain table.", function ); return( -1 ); } result = libvmdk_extent_table_get_extent_file_at_offset( extent_table, offset, file_io_pool, &extent_number, &extent_file_data_offset, &extent_file, error ); if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve extent file at offset: %" PRIi64 " from extent table.", function, offset ); return( -1 ); } if( extent_file == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing extent file.", function ); return( -1 ); } result = libvmdk_extent_file_get_grain_group_at_offset( extent_file, file_io_pool, extent_file_data_offset, &grain_groups_list_index, &grain_group_data_offset, &grains_list, error ); if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve grain group from extent file: %d at offset: %" PRIi64 ".", function, extent_number, extent_file_data_offset ); return( -1 ); } result = libfdata_list_get_element_value_at_offset( grains_list, (intptr_t *) file_io_pool, grains_cache, grain_group_data_offset, &grains_list_index, grain_data_offset, (intptr_t **) grain_data, 0, error ); if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve grain: %" PRIu64 " data from grain group: %d in extent file: %d at offset: %" PRIi64 ".", function, grain_index, grain_groups_list_index, extent_number, extent_file_data_offset ); return( -1 ); } return( 1 ); }
/* Retrieves the chunk data of a chunk at a specific offset * Adds a checksum error if the data is corrupted * Returns 1 if successful or -1 on error */ int libewf_chunk_table_get_chunk_data_by_offset( libewf_chunk_table_t *chunk_table, uint64_t chunk_index, libewf_io_handle_t *io_handle, libbfio_pool_t *file_io_pool, libewf_media_values_t *media_values, libewf_segment_table_t *segment_table, libfdata_range_list_t *delta_chunks_range_list, libfcache_cache_t *chunk_groups_cache, libfcache_cache_t *chunks_cache, off64_t offset, libewf_chunk_data_t **chunk_data, off64_t *chunk_data_offset, libcerror_error_t **error ) { libewf_segment_file_t *segment_file = NULL; libfdata_list_t *chunks_list = NULL; static char *function = "libewf_chunk_table_get_chunk_data_by_offset"; off64_t chunk_offset = 0; off64_t chunk_group_data_offset = 0; off64_t segment_file_data_offset = 0; size_t chunk_data_size = 0; uint64_t start_sector = 0; uint64_t number_of_sectors = 0; uint32_t segment_number = 0; int chunk_groups_list_index = 0; int chunks_list_index = 0; int result = 0; if( chunk_table == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid chunk table.", function ); return( -1 ); } if( io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid IO handle.", function ); return( -1 ); } if( media_values == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid media values.", function ); return( -1 ); } if( chunk_data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid chunk data.", function ); return( -1 ); } if( chunk_data_offset == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid chunk data offset.", function ); return( -1 ); } if( delta_chunks_range_list != NULL ) { result = libfdata_range_list_get_element_value_at_offset( delta_chunks_range_list, (intptr_t *) file_io_pool, chunks_cache, offset, chunk_data_offset, (intptr_t **) chunk_data, 0, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve chunk: %" PRIu64 " from delta chunks range list.", function, chunk_index ); return( -1 ); } } if( result == 0 ) { result = libewf_chunk_table_get_segment_file_chunk_group_by_offset( chunk_table, file_io_pool, segment_table, chunk_groups_cache, offset, &segment_number, &segment_file_data_offset, &segment_file, &chunk_groups_list_index, &chunk_group_data_offset, &chunks_list, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve segment file chunk group at offset: %" PRIi64 ".", function, offset ); return( -1 ); } if( result != 0 ) { if( chunks_list == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing chunks list: %d.", function, chunk_groups_list_index ); return( -1 ); } result = libfdata_list_get_element_value_at_offset( chunks_list, (intptr_t *) file_io_pool, chunks_cache, chunk_group_data_offset, &chunks_list_index, chunk_data_offset, (intptr_t **) chunk_data, 0, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve chunk: %" PRIu64 " data from chunk group: %d in segment file: %" PRIu32 " at offset: %" PRIi64 ".", function, chunk_index, chunk_groups_list_index, segment_number, segment_file_data_offset ); return( -1 ); } } } if( result != 0 ) { if( *chunk_data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing chunk: %" PRIu64 " data.", function, chunk_index ); return( -1 ); } if( libewf_chunk_data_unpack( *chunk_data, media_values->chunk_size, io_handle->compression_method, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GENERIC, "%s: unable to unpack chunk: %" PRIu64 " data.", function, chunk_index ); return( -1 ); } if( ( ( *chunk_data )->range_flags & LIBEWF_RANGE_FLAG_IS_CORRUPTED ) != 0 ) { if( io_handle->zero_on_error != 0 ) { if( memory_set( ( *chunk_data )->data, 0, ( *chunk_data )->data_size ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to zero chunk: %" PRIu64 " data.", function, chunk_index ); return( -1 ); } } chunk_offset = offset - *chunk_data_offset; } } else { chunk_offset = (off64_t) chunk_index * media_values->chunk_size; chunk_data_size = media_values->chunk_size; if( (size64_t) ( chunk_offset + chunk_data_size ) > media_values->media_size ) { chunk_data_size = (size_t) ( media_values->media_size - chunk_offset ); } if( libewf_chunk_data_initialize_clear_data( chunk_data, chunk_data_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create chunk: %" PRIu64 " data.", function, chunk_index ); return( -1 ); } if( *chunk_data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing chunk data: %" PRIu64 ".", function, chunk_index ); return( -1 ); } ( *chunk_data )->data_size = chunk_data_size; ( *chunk_data )->range_flags |= LIBEWF_RANGE_FLAG_IS_CORRUPTED; } if( ( ( *chunk_data )->range_flags & LIBEWF_RANGE_FLAG_IS_CORRUPTED ) != 0 ) { /* Add checksum error */ start_sector = chunk_offset / media_values->bytes_per_sector; number_of_sectors = media_values->sectors_per_chunk; if( ( start_sector + number_of_sectors ) > (uint64_t) media_values->number_of_sectors ) { number_of_sectors = (uint64_t) media_values->number_of_sectors - start_sector; } if( libcdata_range_list_insert_range( chunk_table->checksum_errors, start_sector, number_of_sectors, NULL, NULL, NULL, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to insert checksum error in range list.", function ); return( -1 ); } } return( 1 ); }
/* Retrieves a segment file at a specific offset from the segment table * Returns 1 if successful, 0 if not or -1 on error */ int libewf_segment_table_get_segment_file_at_offset( libewf_segment_table_t *segment_table, off64_t offset, libbfio_pool_t *file_io_pool, uint32_t *segment_number, off64_t *segment_file_data_offset, libewf_segment_file_t **segment_file, libcerror_error_t **error ) { static char *function = "libewf_segment_table_get_segment_file_at_offset"; int result = 0; int segment_files_list_index = 0; if( segment_table == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid segment table.", function ); return( -1 ); } if( segment_number == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid segment number.", function ); return( -1 ); } result = libfdata_list_get_element_value_at_offset( segment_table->segment_files_list, (intptr_t *) file_io_pool, segment_table->segment_files_cache, offset, &segment_files_list_index, segment_file_data_offset, (intptr_t **) segment_file, 0, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve element at offset: %" PRIi64 " from segment files list.", function, offset ); return( -1 ); } else if( result != 0 ) { #if SIZEOF_INT <= 4 if( segment_files_list_index < 0 ) #else if( ( segment_files_list_index < 0 ) || ( segment_files_list_index > (int) UINT32_MAX ) ) #endif { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid segment files list index value out of bounds.", function ); return( -1 ); } *segment_number = (uint32_t) segment_files_list_index; } return( result ); }