?? libewf_read.c
字號:
/* * libewf file reading * * Copyright (c) 2006-2007, Joachim Metz <forensics@hoffmannbv.nl>, * Hoffmann Investigations. All rights reserved. * * Refer to AUTHORS for acknowledgements. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the creator, related organisations, nor the names of * its contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * - All advertising materials mentioning features or use of this software * must acknowledge the contribution by people stated in the acknowledgements. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER, COMPANY AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */#include "libewf_includes.h"#include <libewf/libewf_definitions.h>#include "libewf_common.h"#include "libewf_endian.h"#include "libewf_notify.h"#include "libewf_file.h"#include "libewf_read.h"#include "libewf_section.h"#include "libewf_segment_table.h"#include "ewf_crc.h"#include "ewf_file_header.h"/* Builds the index (section list and offset table) from the input files * Returns 1 if successful, or -1 on error */int8_t libewf_read_build_index( LIBEWF_INTERNAL_HANDLE *internal_handle ){ EWF_SECTION *last_section = NULL; uint16_t segment_number = 0; if( internal_handle == NULL ) { LIBEWF_WARNING_PRINT( "libewf_read_build_index: invalid handle.\n" ); return( -1 ); } if( internal_handle->index_build != 0 ) { LIBEWF_WARNING_PRINT( "libewf_read_build_index: index has already been build.\n" ); return( -1 ); } if( libewf_internal_handle_read_initialize( internal_handle ) != 1 ) { LIBEWF_WARNING_PRINT( "libewf_read_build_index: unable to initialize read values in handle.\n" ); return( -1 ); } for( segment_number = 1; segment_number < internal_handle->segment_table->amount; segment_number++ ) { if( last_section != NULL ) { libewf_common_free( last_section ); } LIBEWF_VERBOSE_PRINT( "libewf_read_build_index: building index for segment number: %" PRIu32 ".\n", segment_number ); last_section = libewf_read_sections_from_segment( internal_handle, segment_number ); } /* Check to see if the done section has been found */ if( last_section == NULL ) { LIBEWF_WARNING_PRINT( "libewf_read_build_index: invalid last section.\n" ); return( -1 ); } else if( ewf_section_is_type_done( last_section ) == 0 ) { LIBEWF_WARNING_PRINT( "libewf_read_build_index: unable to find the last segment file (done section).\n" ); libewf_common_free( last_section ); return( -1 ); } libewf_common_free( last_section ); /* Determine the EWF file format */ if( libewf_internal_handle_determine_format( internal_handle ) != 1 ) { LIBEWF_WARNING_PRINT( "libewf_read_build_index: unable to determine file format.\n" ); } LIBEWF_VERBOSE_PRINT( "libewf_read_build_index: index successful build.\n" ); /* Calculate the media size */ internal_handle->media->media_size = (uint64_t) internal_handle->media->amount_of_sectors * (uint64_t) internal_handle->media->bytes_per_sector; /* Flag that the index was build */ internal_handle->index_build = 1; return( 1 );}/* Reads and processes sections of a segment file * Returns the last section read, or NULL on error */EWF_SECTION *libewf_read_sections_from_segment( LIBEWF_INTERNAL_HANDLE *internal_handle, uint16_t segment_number ){ EWF_SECTION *section = NULL; int file_descriptor = 0; /* The first offset is directly after the file header (13 byte) */ off_t previous_offset = (off_t) EWF_FILE_HEADER_SIZE; if( internal_handle == NULL ) { LIBEWF_WARNING_PRINT( "libewf_sections_read_segment: invalid handle.\n" ); return( NULL ); } if( libewf_segment_table_values_is_set( internal_handle->segment_table, segment_number ) == 0 ) { LIBEWF_WARNING_PRINT( "libewf_sections_read_segment: missing a segment file for segment %" PRIu32 ".\n", segment_number ); return( NULL ); } file_descriptor = libewf_segment_table_get_file_descriptor( internal_handle->segment_table, segment_number ); if( file_descriptor <= -1 ) { LIBEWF_WARNING_PRINT( "libewf_sections_read_segment: invalid file descriptor.\n" ); return( NULL ); } do { if( section != NULL ) { libewf_common_free( section ); } section = libewf_section_read( internal_handle, file_descriptor, internal_handle->segment_table->section_list[ segment_number ], segment_number, &previous_offset ); if( section == NULL ) { LIBEWF_WARNING_PRINT( "libewf_sections_read_segment: unable to read section.\n" ); return( NULL ); } /* The done and next sections point back at themselves */ if( ( ewf_section_is_type_next( section ) == 1 ) || ( ewf_section_is_type_done( section ) == 1 ) ) { break; } } while( section != NULL ); return( section );}/* Reads a certain chunk of data from the segment file(s) * Will read until the requested size is filled or the entire chunk is read * This function swaps byte pairs if specified * Returns the amount of bytes read, 0 if no bytes can be read, or -1 on error */ssize_t libewf_read_chunk( LIBEWF_INTERNAL_HANDLE *internal_handle, uint32_t chunk, uint32_t chunk_offset, void *buffer, size_t size ){ EWF_CHUNK *chunk_data = NULL; EWF_CHUNK *chunk_read = NULL; EWF_CRC calculated_crc = 0; EWF_CRC stored_crc = 0;#if defined( HAVE_WIDE_CHARACTER_TYPE ) && defined( HAVE_WIDE_CHARACTER_SUPPORT_FUNCTIONS ) wchar_t *filename = NULL;#else char *filename = NULL;#endif ssize_t chunk_read_count = 0; ssize_t crc_read_count = 0; size_t chunk_data_size = 0; size_t bytes_available = 0; size_t md5_hash_size = 0; uint16_t segment_number = 0; int8_t chunk_cache_used = 0; int8_t result = 0; uint8_t percentage = 0; int file_descriptor = 0; if( internal_handle == NULL ) { LIBEWF_WARNING_PRINT( "libewf_read_chunk: invalid handle.\n" ); return( -1 ); } if( internal_handle->media == NULL ) { LIBEWF_WARNING_PRINT( "libewf_read_chunk: invalid handle - missing subhandle media.\n" ); return( -1 ); } if( internal_handle->read == NULL ) { LIBEWF_WARNING_PRINT( "libewf_read_chunk: invalid handle - missing subhandle read.\n" ); return( -1 ); } if( internal_handle->offset_table == NULL ) { LIBEWF_WARNING_PRINT( "libewf_read_chunk: invalid handle - missing offset table.\n" ); return( -1 ); } if( internal_handle->segment_table == NULL ) { LIBEWF_WARNING_PRINT( "libewf_read_chunk: invalid handle - missing segment table.\n" ); return( -1 ); } if( internal_handle->chunk_cache == NULL ) { LIBEWF_WARNING_PRINT( "libewf_read_chunk: invalid chunk cache.\n" ); return( -1 ); } if( internal_handle->index_build == 0 ) { LIBEWF_WARNING_PRINT( "libewf_read_chunk: index was not build.\n" ); return( -1 ); } if( buffer == NULL ) { LIBEWF_WARNING_PRINT( "libewf_read_chunk: invalid buffer.\n" ); return( -1 ); } if( buffer == internal_handle->chunk_cache->compressed ) { LIBEWF_WARNING_PRINT( "libewf_read_chunk: invalid buffer - same as chunk cache compressed.\n" ); return( -1 ); } /* Check if the chunk is available */ if( chunk >= internal_handle->offset_table->amount ) { return( 0 ); } /* Check if the chunk is cached */ if( ( internal_handle->chunk_cache->chunk != chunk ) || ( internal_handle->chunk_cache->cached == 0 ) ) { file_descriptor = internal_handle->offset_table->file_descriptor[ chunk ]; segment_number = internal_handle->offset_table->segment_number[ chunk ]; /* Check if chunk cache passthrough is used * if the chunk cache is used as the chunk data buffer */ chunk_cache_used = (int8_t) ( buffer == internal_handle->chunk_cache->data ); /* Determine the size of the chunk including the CRC */ chunk_data_size = internal_handle->offset_table->size[ chunk ]; /* Make sure the chunk cache is large enough */ if( chunk_data_size > internal_handle->chunk_cache->allocated_size ) { LIBEWF_VERBOSE_PRINT( "libewf_read_chunk: reallocating chunk data size: %zu.\n", chunk_data_size ); if( libewf_internal_handle_chunk_cache_realloc( internal_handle, chunk_data_size ) == NULL ) { LIBEWF_WARNING_PRINT( "libewf_read_chunk: unable to reallocate chunk cache.\n"); return( -1 ); } /* Adjust chunk data buffer if necessary */ if( ( chunk_cache_used == 1 ) && ( buffer != internal_handle->chunk_cache->data ) ) { buffer = internal_handle->chunk_cache->data; } } chunk_data = internal_handle->chunk_cache->data;#ifdef HAVE_BUFFER_PASSTHROUGH /* Determine if the chunk data should be put directly in the buffer */ if( ( buffer != internal_handle->chunk_cache->data ) && ( chunk_offset == 0 ) && ( size >= (uint64_t) internal_handle->media->chunk_size ) ) { chunk_data = (EWF_CHUNK *) buffer; }#endif /* Determine if the chunk data should be directly read into chunk data buffer * or to use the intermediate storage for a compressed chunk */ if( internal_handle->offset_table->compressed[ chunk ] == 1 ) { chunk_read = internal_handle->chunk_cache->compressed; } else { chunk_read = chunk_data; } /* If buffer passthrough is used the CRC is read seperately */ if( ( chunk_read != internal_handle->chunk_cache->compressed ) && ( chunk_read != internal_handle->chunk_cache->data ) ) { chunk_data_size -= EWF_CRC_SIZE; } /* Make sure the file offset is in the right place */ if( libewf_seek_chunk( internal_handle, chunk ) <= -1 ) { LIBEWF_WARNING_PRINT( "libewf_read_chunk: unable to seek chunk.\n"); return( -1 ); } /* Read the chunk data */ chunk_read_count = ewf_chunk_read( chunk_read, file_descriptor, chunk_data_size ); if( chunk_read_count <= -1 ) { LIBEWF_WARNING_PRINT( "libewf_read_chunk: unable to read chunk.\n"); return( -1 ); } internal_handle->segment_table->file_offset[ segment_number ] += (off_t) chunk_read_count; if( ( internal_handle->offset_table->last > 0 ) && ( chunk > 0 ) ) { percentage = (uint8_t) ( (uint32_t) ( chunk * 100 ) / internal_handle->offset_table->last ); } /* Determine if the chunk is not compressed */ if( internal_handle->offset_table->compressed[ chunk ] == 0 ) { LIBEWF_VERBOSE_PRINT( "libewf_read_chunk: chunk %" PRIu32 " of %" PRIu32 " (%" PRIu8 "%%) is UNCOMPRESSED.\n", ( chunk + 1 ), internal_handle->offset_table->amount, percentage ); /* If buffer passthrough is used the CRC needs to be read seperately */ if( ( chunk_read != internal_handle->chunk_cache->compressed ) && ( chunk_read != internal_handle->chunk_cache->data ) ) { crc_read_count = ewf_crc_read( &stored_crc, file_descriptor );
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -