示例#1
0
/* 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 );
}
示例#2
0
/* 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 );
}
示例#3
0
/* 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 );
}
示例#4
0
/* 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 );
}