/* Frees a segment table * Returns 1 if successful or -1 on error */ int libewf_segment_table_free( libewf_segment_table_t **segment_table, libcerror_error_t **error ) { static char *function = "libewf_segment_table_free"; int result = 1; 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_table != NULL ) { if( ( *segment_table )->basename != NULL ) { memory_free( ( *segment_table )->basename ); } if( libfdata_list_free( &( ( *segment_table )->segment_files_list ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free segment files list.", function ); result = -1; } if( libfcache_cache_free( &( ( *segment_table )->segment_files_cache ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free segment files cache.", function ); result = -1; } memory_free( *segment_table ); *segment_table = NULL; } return( result ); }
/* Opens a file for reading * Returns 1 if successful or -1 on error */ int libevtx_file_open_read( libevtx_internal_file_t *internal_file, libbfio_handle_t *file_io_handle, libcerror_error_t **error ) { libevtx_chunk_t *chunk = NULL; libevtx_record_values_t *record_values = NULL; libevtx_chunks_table_t *chunks_table = NULL; static char *function = "libevtx_file_open_read"; off64_t file_offset = 0; size64_t file_size = 0; uint16_t chunk_index = 0; uint16_t number_of_chunks = 0; uint16_t number_of_records = 0; uint16_t record_index = 0; int element_index = 0; int result = 0; int segment_index = 0; #if defined( HAVE_VERBOSE_OUTPUT ) uint64_t previous_record_identifier = 0; #endif #if defined( HAVE_DEBUG_OUTPUT ) uint8_t *trailing_data = NULL; size_t trailing_data_size = 0; ssize_t read_count = 0; #endif if( internal_file == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid 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 file - missing IO handle.", function ); return( -1 ); } if( internal_file->chunks_vector != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid file - chunks vector already set.", function ); return( -1 ); } if( internal_file->chunks_cache != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid file - chunks cache already set.", function ); return( -1 ); } if( internal_file->records_list != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid file - records list already set.", function ); return( -1 ); } if( internal_file->recovered_records_list != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid file - recovered records list already set.", function ); return( -1 ); } if( internal_file->records_cache != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid file - records cache already set.", function ); return( -1 ); } if( libbfio_handle_get_size( file_io_handle, &file_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve file size.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "Reading file header:\n" ); } #endif if( libevtx_io_handle_read_file_header( internal_file->io_handle, file_io_handle, 0, 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; } internal_file->io_handle->chunks_data_size = file_size - internal_file->io_handle->chunks_data_offset; /* TODO clone function ? */ if( libfdata_vector_initialize( &( internal_file->chunks_vector ), (size64_t) internal_file->io_handle->chunk_size, (intptr_t *) internal_file->io_handle, NULL, NULL, (int (*)(intptr_t *, intptr_t *, libfdata_vector_t *, libfcache_cache_t *, int, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libevtx_io_handle_read_chunk, NULL, LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create chunks vector.", function ); goto on_error; } if( libfdata_vector_append_segment( internal_file->chunks_vector, &segment_index, 0, internal_file->io_handle->chunks_data_offset, internal_file->io_handle->chunks_data_size, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append segment to chunks vector.", function ); goto on_error; } if( libfcache_cache_initialize( &( internal_file->chunks_cache ), LIBEVTX_MAXIMUM_CACHE_ENTRIES_CHUNKS, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create chunks cache.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "Reading chunks:\n" ); } #endif if( libevtx_chunks_table_initialize( &chunks_table, internal_file->io_handle, internal_file->chunks_vector, internal_file->chunks_cache, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create chunks table.", function ); goto on_error; } /* TODO clone function ? */ if( libfdata_list_initialize( &( internal_file->records_list ), (intptr_t *) chunks_table, (int (*)(intptr_t **, libcerror_error_t **)) &libevtx_chunks_table_free, NULL, (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfcache_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libevtx_chunks_table_read_record, NULL, LIBFDATA_DATA_HANDLE_FLAG_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create records list.", function ); goto on_error; } /* The chunks_table is managed by the list */ if( libfdata_list_initialize( &( internal_file->recovered_records_list ), (intptr_t *) chunks_table, NULL, NULL, (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfcache_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libevtx_chunks_table_read_record, NULL, LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create recovered records list.", function ); chunks_table = NULL; goto on_error; } chunks_table = NULL; if( libfcache_cache_initialize( &( internal_file->records_cache ), LIBEVTX_MAXIMUM_CACHE_ENTRIES_RECORDS, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create records cache.", function ); goto on_error; } file_offset = internal_file->io_handle->chunks_data_offset; while( ( file_offset + internal_file->io_handle->chunk_size ) <= (off64_t) file_size ) { if( libevtx_chunk_initialize( &chunk, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create chunk: %" PRIu16 ".", function, chunk_index ); goto on_error; } result = libevtx_chunk_read( chunk, internal_file->io_handle, file_io_handle, file_offset, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read chunk: %" PRIu16 ".", function, chunk_index ); goto on_error; } else if( result == 0 ) { if( chunk_index < internal_file->io_handle->number_of_chunks ) { #if defined( HAVE_VERBOSE_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: corruption detected in chunk: %" PRIu16 ".\n", function, chunk_index ); } #endif internal_file->io_handle->flags |= LIBEVTX_IO_HANDLE_FLAG_IS_CORRUPTED; } } else { if( ( chunk->flags & LIBEVTX_CHUNK_FLAG_IS_CORRUPTED ) != 0 ) { #if defined( HAVE_VERBOSE_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: corruption detected in chunk: %" PRIu16 ".\n", function, chunk_index ); } #endif if( chunk_index < internal_file->io_handle->number_of_chunks ) { internal_file->io_handle->flags |= LIBEVTX_IO_HANDLE_FLAG_IS_CORRUPTED; } } if( ( chunk_index < internal_file->io_handle->number_of_chunks ) || ( ( chunk->flags & LIBEVTX_CHUNK_FLAG_IS_CORRUPTED ) == 0 ) ) { number_of_chunks++; } if( libevtx_chunk_get_number_of_records( chunk, &number_of_records, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve chunk: %" PRIu16 " number of records.", function, chunk_index ); goto on_error; } for( record_index = 0; record_index < number_of_records; record_index++ ) { if( libevtx_chunk_get_record( chunk, record_index, &record_values, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve chunk: %" PRIu16 " record: %" PRIu16 ".", function, chunk_index, record_index ); goto on_error; } if( record_values == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing chunk: %" PRIu16 " record: %" PRIu16 ".", function, chunk_index, record_index ); goto on_error; } if( record_values->identifier < internal_file->io_handle->first_record_identifier ) { internal_file->io_handle->first_record_identifier = record_values->identifier; } if( record_values->identifier > internal_file->io_handle->last_record_identifier ) { internal_file->io_handle->last_record_identifier = record_values->identifier; } #if defined( HAVE_VERBOSE_OUTPUT ) if( ( chunk_index == 0 ) && ( record_index == 0 ) ) { previous_record_identifier = record_values->identifier; } else { previous_record_identifier++; if( record_values->identifier != previous_record_identifier ) { if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: detected gap in record identifier ( %" PRIu64 " != %" PRIu64 " ).\n", function, previous_record_identifier, record_values->identifier ); } previous_record_identifier = record_values->identifier; } } #endif /* The chunk index is stored in the element data size */ if( ( chunk_index < internal_file->io_handle->number_of_chunks ) || ( ( internal_file->io_handle->file_flags & LIBEVTX_FILE_FLAG_IS_DIRTY ) != 0 ) ) { if( libfdata_list_append_element( internal_file->records_list, &element_index, 0, file_offset + record_values->chunk_data_offset, (size64_t) chunk_index, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append element to records list.", function ); goto on_error; } } else { /* If the file is not dirty, records found in chunks outside the indicated * range are considered recovered */ if( libfdata_list_append_element( internal_file->recovered_records_list, &element_index, 0, file_offset + record_values->chunk_data_offset, (size64_t) chunk_index, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append element to recovered records list.", function ); goto on_error; } } /* TODO cache record values ? */ } if( libevtx_chunk_get_number_of_recovered_records( chunk, &number_of_records, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve chunk: %" PRIu16 " number of recovered records.", function, chunk_index ); goto on_error; } for( record_index = 0; record_index < number_of_records; record_index++ ) { if( libevtx_chunk_get_recovered_record( chunk, record_index, &record_values, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve chunk: %" PRIu16 " recovered record: %" PRIu16 ".", function, chunk_index, record_index ); goto on_error; } if( record_values == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing chunk: %" PRIu16 " recovered record: %" PRIu16 ".", function, chunk_index, record_index ); goto on_error; } /* TODO check for and remove duplicate identifiers ? */ /* The chunk index is stored in the element data size */ if( libfdata_list_append_element( internal_file->recovered_records_list, &element_index, 0, file_offset + record_values->chunk_data_offset, (size64_t) chunk_index, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append element to recovered records list.", function ); goto on_error; } } } file_offset += chunk->data_size; if( libevtx_chunk_free( &chunk, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free chunk: %" PRIu16 ".", function, chunk_index ); goto on_error; } chunk_index++; } internal_file->io_handle->chunks_data_size = file_offset - internal_file->io_handle->chunks_data_offset; if( number_of_chunks != internal_file->io_handle->number_of_chunks ) { #if defined( HAVE_VERBOSE_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: mismatch in number of chunks ( %" PRIu16 " != %" PRIu16 " ).\n", function, internal_file->io_handle->number_of_chunks, chunk_index ); } #endif internal_file->io_handle->flags |= LIBEVTX_IO_HANDLE_FLAG_IS_CORRUPTED; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( file_offset < (off64_t) file_size ) { trailing_data_size = (size_t) ( file_size - file_offset ); trailing_data = (uint8_t *) memory_allocate( sizeof( uint8_t ) * trailing_data_size ); if( trailing_data == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create trailing data.", function ); goto on_error; } read_count = libbfio_handle_read_buffer( file_io_handle, trailing_data, trailing_data_size, error ); if( read_count != (ssize_t) trailing_data_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read trailing data.", function ); memory_free( trailing_data ); goto on_error; } file_offset += read_count; libcnotify_printf( "%s: trailing data:\n", function ); libcnotify_print_data( trailing_data, trailing_data_size, LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); memory_free( trailing_data ); trailing_data = NULL; } } #endif return( 1 ); on_error: #if defined( HAVE_DEBUG_OUTPUT ) if( trailing_data != NULL ) { memory_free( trailing_data ); } #endif if( chunk != NULL ) { libevtx_chunk_free( &chunk, NULL ); } if( internal_file->records_cache != NULL ) { libfcache_cache_free( &( internal_file->records_cache ), NULL ); } if( internal_file->records_list != NULL ) { libfdata_list_free( &( internal_file->records_list ), NULL ); } if( chunks_table != NULL ) { libevtx_chunks_table_free( &chunks_table, NULL ); } if( internal_file->chunks_cache != NULL ) { libfcache_cache_free( &( internal_file->chunks_cache ), NULL ); } if( internal_file->chunks_vector != NULL ) { libfdata_vector_free( &( internal_file->chunks_vector ), NULL ); } return( -1 ); }
/* Closes a file * Returns 0 if successful or -1 on error */ int libevtx_file_close( libevtx_file_t *file, libcerror_error_t **error ) { libevtx_internal_file_t *internal_file = NULL; static char *function = "libevtx_file_close"; int result = 0; if( file == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid file.", function ); return( -1 ); } internal_file = (libevtx_internal_file_t *) file; if( internal_file->file_io_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid file - missing file IO handle.", function ); return( -1 ); } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( internal_file->file_io_handle_created_in_library != 0 ) { if( libevtx_debug_print_read_offsets( internal_file->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( internal_file->file_io_handle_opened_in_library != 0 ) { if( libbfio_handle_close( internal_file->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_file->file_io_handle_opened_in_library = 0; } if( internal_file->file_io_handle_created_in_library != 0 ) { if( libbfio_handle_free( &( internal_file->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_file->file_io_handle_created_in_library = 0; } internal_file->file_io_handle = NULL; if( libevtx_io_handle_clear( internal_file->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( libfdata_list_free( &( internal_file->recovered_records_list ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free recovered records list.", function ); result = -1; } if( libfdata_list_free( &( internal_file->records_list ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free records list.", function ); result = -1; } if( libfcache_cache_free( &( internal_file->records_cache ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free records cache.", function ); result = -1; } if( libfdata_vector_free( &( internal_file->chunks_vector ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free chunks vector.", function ); result = -1; } if( libfcache_cache_free( &( internal_file->chunks_cache ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free chunks cache.", function ); result = -1; } return( result ); }
/* Initializes the extents * Returns 1 if successful or -1 on error */ int libvmdk_extent_table_initialize_extents( libvmdk_extent_table_t *extent_table, int number_of_extents, int disk_type, libcerror_error_t **error ) { static char *function = "libvmdk_extent_table_initialize_extents"; 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 ); } if( ( disk_type != LIBVMDK_DISK_TYPE_2GB_EXTENT_FLAT ) && ( disk_type != LIBVMDK_DISK_TYPE_MONOLITHIC_FLAT ) && ( disk_type != LIBVMDK_DISK_TYPE_2GB_EXTENT_SPARSE ) && ( disk_type != LIBVMDK_DISK_TYPE_MONOLITHIC_SPARSE ) && ( disk_type != LIBVMDK_DISK_TYPE_STREAM_OPTIMIZED ) && ( disk_type != LIBVMDK_DISK_TYPE_VMFS_FLAT ) && ( disk_type != LIBVMDK_DISK_TYPE_VMFS_FLAT_PRE_ALLOCATED ) && ( disk_type != LIBVMDK_DISK_TYPE_VMFS_FLAT_ZEROED ) && ( disk_type != LIBVMDK_DISK_TYPE_VMFS_SPARSE ) && ( disk_type != LIBVMDK_DISK_TYPE_VMFS_SPARSE_THIN ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, "%s: unsupported disk type.", function ); return( -1 ); } if( ( disk_type == LIBVMDK_DISK_TYPE_2GB_EXTENT_FLAT ) || ( disk_type == LIBVMDK_DISK_TYPE_MONOLITHIC_FLAT ) || ( disk_type == LIBVMDK_DISK_TYPE_VMFS_FLAT ) || ( disk_type == LIBVMDK_DISK_TYPE_VMFS_FLAT_PRE_ALLOCATED ) || ( disk_type == LIBVMDK_DISK_TYPE_VMFS_FLAT_ZEROED ) ) { /* TODO add write support ? */ result = libfdata_stream_initialize( &( extent_table->extent_files_stream ), (intptr_t *) extent_table->io_handle, NULL, NULL, NULL, (ssize_t (*)(intptr_t *, intptr_t *, int, int, uint8_t *, size_t, uint32_t, uint8_t, libcerror_error_t **)) &libvmdk_extent_file_read_segment_data, NULL, (off64_t (*)(intptr_t *, intptr_t *, int, int, off64_t, libcerror_error_t **)) &libvmdk_extent_file_seek_segment_offset, LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED, error ); if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create extent files stream.", function ); goto on_error; } if( libfdata_stream_resize( extent_table->extent_files_stream, number_of_extents, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED, "%s: unable to resize extents file stream.", function ); goto on_error; } } else if( ( disk_type == LIBVMDK_DISK_TYPE_2GB_EXTENT_SPARSE ) || ( disk_type == LIBVMDK_DISK_TYPE_MONOLITHIC_SPARSE ) || ( disk_type == LIBVMDK_DISK_TYPE_STREAM_OPTIMIZED ) || ( disk_type == LIBVMDK_DISK_TYPE_VMFS_SPARSE ) || ( disk_type == LIBVMDK_DISK_TYPE_VMFS_SPARSE_THIN ) ) { /* TODO add write support ? */ result = libfdata_list_initialize( &( extent_table->extent_files_list ), (intptr_t *) extent_table->io_handle, NULL, NULL, (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfdata_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libvmdk_extent_file_read_element_data, NULL, LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED, error ); if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create extent files list.", function ); goto on_error; } if( libfdata_list_resize( extent_table->extent_files_list, number_of_extents, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED, "%s: unable to resize extent files list.", function ); goto on_error; } result = libfcache_cache_initialize( &( extent_table->extent_files_cache ), LIBVMDK_MAXIMUM_CACHE_ENTRIES_EXTENT_FILES, error ); if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create extent files cache.", function ); goto on_error; } } extent_table->disk_type = disk_type; extent_table->number_of_extents = number_of_extents; return( 1 ); on_error: if( extent_table->extent_files_list != NULL ) { libfdata_list_free( &( extent_table->extent_files_list ), NULL ); } return( -1 ); }
/* Clones the extent table * Returns 1 if successful or -1 on error */ int libvmdk_extent_table_clone( libvmdk_extent_table_t **destination_extent_table, libvmdk_extent_table_t *source_extent_table, libcerror_error_t **error ) { static char *function = "libvmdk_extent_table_clone"; if( destination_extent_table == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid destination extent table.", function ); return( -1 ); } if( *destination_extent_table != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid destination extent table value already set.", function ); return( -1 ); } if( source_extent_table == NULL ) { *destination_extent_table = NULL; return( 1 ); } *destination_extent_table = memory_allocate_structure( libvmdk_extent_table_t ); if( *destination_extent_table == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create destination extent table.", function ); goto on_error; } if( memory_set( *destination_extent_table, 0, sizeof( libvmdk_extent_table_t ) ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear source to destination extent table.", function ); memory_free( *destination_extent_table ); *destination_extent_table = NULL; return( -1 ); } if( source_extent_table->data_files_path != NULL ) { ( *destination_extent_table )->data_files_path = system_string_allocate( source_extent_table->data_files_path_size ); if( *destination_extent_table == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create destination extent table.", function ); goto on_error; } if( memory_copy( ( *destination_extent_table )->data_files_path, source_extent_table->data_files_path, sizeof( system_character_t ) * source_extent_table->data_files_path_size ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_COPY_FAILED, "%s: unable to copy source to destination data files path.", function ); goto on_error; } ( *destination_extent_table )->data_files_path_size = source_extent_table->data_files_path_size; } if( libfdata_list_clone( &( ( *destination_extent_table )->extent_files_list ), source_extent_table->extent_files_list, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create destination extent files list.", function ); goto on_error; } if( libfcache_cache_clone( &( ( *destination_extent_table )->extent_files_cache ), source_extent_table->extent_files_cache, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create destination extent files cache.", function ); goto on_error; } if( libfdata_stream_clone( &( ( *destination_extent_table )->extent_files_stream ), source_extent_table->extent_files_stream, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create destination extent files stream.", function ); goto on_error; } return( 1 ); on_error: if( *destination_extent_table != NULL ) { if( ( *destination_extent_table )->extent_files_cache != NULL ) { libfcache_cache_free( &( ( *destination_extent_table )->extent_files_cache ), NULL ); } if( ( *destination_extent_table )->extent_files_list != NULL ) { libfdata_list_free( &( ( *destination_extent_table )->extent_files_list ), NULL ); } if( ( *destination_extent_table )->data_files_path != NULL ) { memory_free( ( *destination_extent_table )->data_files_path ); } memory_free( *destination_extent_table ); *destination_extent_table = NULL; } return( -1 ); }
/* Clears the extent table * Returns 1 if successful or -1 on error */ int libvmdk_extent_table_clear( libvmdk_extent_table_t *extent_table, libcerror_error_t **error ) { static char *function = "libvmdk_extent_table_clear"; int result = 1; if( extent_table == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid extent table.", function ); return( -1 ); } if( extent_table->data_files_path != NULL ) { memory_free( extent_table->data_files_path ); extent_table->data_files_path = NULL; extent_table->data_files_path_size = 0; } if( extent_table->extent_files_list != NULL ) { if( libfdata_list_free( &( extent_table->extent_files_list ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free extent files list.", function ); result = -1; } } if( extent_table->extent_files_cache != NULL ) { if( libfcache_cache_free( &( extent_table->extent_files_cache ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free extent files cache.", function ); result = -1; } } if( extent_table->extent_files_stream != NULL ) { if( libfdata_stream_free( &( extent_table->extent_files_stream ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free extent files stream.", function ); result = -1; } } if( memory_set( extent_table, 0, sizeof( libvmdk_extent_table_t ) ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to extent table.", function ); result = -1; } return( result ); }
/* Reads the data list of a descriptor * Returns 1 if successful or -1 on error */ int libpff_io_handle_read_descriptor_data_list( libpff_io_handle_t *io_handle, libbfio_handle_t *file_io_handle, libpff_offsets_index_t *offsets_index, uint32_t descriptor_identifier, uint64_t data_identifier, uint8_t recovered, int recovered_value_index, libfdata_list_t **descriptor_data_list, libfcache_cache_t **descriptor_data_cache, libcerror_error_t **error ) { libpff_data_array_t *data_array = NULL; libpff_data_block_t *data_block = NULL; libpff_index_value_t *offset_index_value = NULL; static char *function = "libpff_io_handle_read_descriptor_data_list"; int element_index = 0; 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( descriptor_data_list == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid descriptor data list.", function ); return( -1 ); } if( *descriptor_data_list != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: descriptor data list already set.", function ); return( -1 ); } if( descriptor_data_cache == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid descriptor data cache.", function ); return( -1 ); } if( *descriptor_data_cache != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: descriptor data cache already set.", function ); return( -1 ); } if( libpff_offsets_index_get_index_value_by_identifier( offsets_index, file_io_handle, data_identifier, recovered, recovered_value_index, &offset_index_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to find offset index value identifier: %" PRIu64 ".", function, data_identifier ); goto on_error; } if( offset_index_value == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid offset index value.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: identifier: %" PRIu64 " (%s) at offset: %" PRIi64 " of size: %" PRIu32 "\n", function, offset_index_value->identifier, ( ( offset_index_value->identifier & LIBPFF_OFFSET_INDEX_IDENTIFIER_FLAG_INTERNAL ) ? "internal" : "external" ), offset_index_value->file_offset, offset_index_value->data_size ); } #endif if( offset_index_value->file_offset <= 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid offset index value - file offset value out of bounds.", function ); goto on_error; } if( offset_index_value->data_size == 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, "%s: invalid offset index value - data size value value out of bounds.", function ); goto on_error; } #if UINT32_MAX > SSIZE_MAX if( offset_index_value->data_size > (size32_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid offset index value - data size value exceeds maximum.", function ); goto on_error; } #endif #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: reading data block at offset: %" PRIi64 " (0x%08" PRIx64 ")\n", function, offset_index_value->file_offset, offset_index_value->file_offset ); } #endif if( libbfio_handle_seek_offset( file_io_handle, offset_index_value->file_offset, SEEK_SET, error ) == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_SEEK_FAILED, "%s: unable to seek data block offset: %" PRIi64 ".", function, offset_index_value->file_offset ); goto on_error; } if( libpff_data_block_initialize( &data_block, io_handle, descriptor_identifier, data_identifier, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create data block.", function ); goto on_error; } if( libpff_data_block_read( data_block, file_io_handle, offset_index_value->data_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read data block at offset: %" PRIi64 ".", function, offset_index_value->file_offset ); goto on_error; } /* Check if the data block contains a data array * The data array should have the internal flag set in the (data) offset index identifier * The data array starts with 0x01 followed by either 0x01 or 0x02 */ if( ( ( data_identifier & (uint64_t) LIBPFF_OFFSET_INDEX_IDENTIFIER_FLAG_INTERNAL ) != 0 ) && ( ( data_block->data[ 0 ] == 0x01 ) && ( ( data_block->data[ 1 ] == 0x01 ) || ( data_block->data[ 1 ] == 0x02 ) ) ) ) { if( libpff_data_array_initialize( &data_array, descriptor_identifier, data_identifier, io_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create data array.", function ); goto on_error; } if( libfdata_list_initialize( descriptor_data_list, (intptr_t *) data_array, (int (*)(intptr_t **, libcerror_error_t **)) &libpff_data_array_free, (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libpff_data_array_clone, (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfcache_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libpff_data_array_read_element_data, NULL, LIBFDATA_DATA_HANDLE_FLAG_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create descriptor data list.", function ); goto on_error; } /* The data_array is now managed by the list */ if( libpff_data_array_read( data_array, io_handle, file_io_handle, offsets_index, *descriptor_data_list, recovered, data_block->data, (size_t) offset_index_value->data_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read data array.", function ); data_array = NULL; goto on_error; } if( libpff_data_block_free( &data_block, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free data block.", function ); data_array = NULL; goto on_error; } if( libfcache_cache_initialize( descriptor_data_cache, LIBPFF_MAXIMUM_CACHE_ENTRIES_DATA_ARRAY, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create descriptor data cache.", function ); data_array = NULL; goto on_error; } } else { if( libpff_data_block_decrypt_data( data_block, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ENCRYPTION, LIBCERROR_ENCRYPTION_ERROR_DECRYPT_FAILED, "%s: unable to decrypt data block data.", function ); goto on_error; } /* TODO change data block not be a data handle ? pass a descriptor instead ? */ if( libfdata_list_initialize( descriptor_data_list, (intptr_t *) data_block, (int (*)(intptr_t **, libcerror_error_t **)) &libpff_data_block_free, (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libpff_data_block_clone, (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfcache_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libpff_data_block_read_element_data, NULL, LIBFDATA_DATA_HANDLE_FLAG_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create descriptor data list.", function ); goto on_error; } /* The data_block is now managed by the list */ if( libfdata_list_append_element_with_mapped_size( *descriptor_data_list, &element_index, 0, offset_index_value->file_offset, (size64_t) offset_index_value->data_size, 0, (size_t) data_block->uncompressed_data_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to append data list element.", function ); data_block = NULL; goto on_error; } if( libfcache_cache_initialize( descriptor_data_cache, LIBPFF_MAXIMUM_CACHE_ENTRIES_DATA_BLOCK, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create descriptor data cache.", function ); data_block = NULL; goto on_error; } /* The data block is managed by the list and should not be managed by the cache as well */ if( libfdata_list_set_element_value_by_index( *descriptor_data_list, (intptr_t *) file_io_handle, *descriptor_data_cache, 0, (intptr_t *) data_block, (int (*)(intptr_t **, libcerror_error_t **)) &libpff_data_block_free, LIBFDATA_LIST_ELEMENT_VALUE_FLAG_NON_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set data list element: 0.", function ); data_block = NULL; goto on_error; } } return( 1 ); on_error: if( *descriptor_data_cache != NULL ) { libfcache_cache_free( descriptor_data_cache, NULL ); } if( *descriptor_data_list != NULL ) { libfdata_list_free( descriptor_data_list, NULL ); } if( data_array != NULL ) { libpff_data_array_free( &data_array, NULL ); } if( data_block != NULL ) { libpff_data_block_free( &data_block, NULL ); } return( -1 ); }
/* Creates a segment table * Make sure the value segment_table is referencing, is set to NULL * Returns 1 if successful or -1 on error */ int libewf_segment_table_initialize( libewf_segment_table_t **segment_table, libewf_io_handle_t *io_handle, size64_t maximum_segment_size, uint8_t is_delta, libcerror_error_t **error ) { static char *function = "libewf_segment_table_initialize"; int result = 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_table != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid segment table value already set.", 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 ); } *segment_table = memory_allocate_structure( libewf_segment_table_t ); if( *segment_table == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create segment table.", function ); goto on_error; } if( memory_set( *segment_table, 0, sizeof( libewf_segment_table_t ) ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear segment table.", function ); memory_free( *segment_table ); *segment_table = NULL; return( -1 ); } if( is_delta == 0 ) { /* TODO add write support ? */ result = libfdata_list_initialize( &( ( *segment_table )->segment_files_list ), (intptr_t *) io_handle, NULL, NULL, (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfcache_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libewf_segment_file_read_element_data, NULL, LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED, error ); } else { /* TODO add write support ? */ result = libfdata_list_initialize( &( ( *segment_table )->segment_files_list ), (intptr_t *) io_handle, NULL, NULL, (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfcache_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libewf_delta_segment_file_read_element_data, NULL, LIBFDATA_DATA_HANDLE_FLAG_NON_MANAGED, error ); } if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create segment files list.", function ); goto on_error; } if( is_delta == 0 ) { result = libfcache_cache_initialize( &( ( *segment_table )->segment_files_cache ), LIBEWF_MAXIMUM_CACHE_ENTRIES_SEGMENT_FILES, error ); } else { result = libfcache_cache_initialize( &( ( *segment_table )->segment_files_cache ), LIBEWF_MAXIMUM_CACHE_ENTRIES_DELTA_SEGMENT_FILES, error ); } if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create segment files cache.", function ); goto on_error; } ( *segment_table )->maximum_segment_size = maximum_segment_size; return( 1 ); on_error: if( *segment_table != NULL ) { if( ( *segment_table )->segment_files_list != NULL ) { libfdata_list_free( &( ( *segment_table )->segment_files_list ), NULL ); } memory_free( *segment_table ); *segment_table = NULL; } return( -1 ); }
/* Creates a file * Make sure the value file is referencing, is set to NULL * Returns 1 if successful or -1 on error */ int libevt_file_initialize( libevt_file_t **file, libcerror_error_t **error ) { libevt_internal_file_t *internal_file = NULL; static char *function = "libevt_file_initialize"; if( file == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid file.", function ); return( -1 ); } if( *file != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid file value already set.", function ); return( -1 ); } internal_file = memory_allocate_structure( libevt_internal_file_t ); if( internal_file == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create file.", function ); goto on_error; } if( memory_set( internal_file, 0, sizeof( libevt_internal_file_t ) ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear file.", function ); memory_free( internal_file ); return( -1 ); } if( libevt_io_handle_initialize( &( internal_file->io_handle ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create IO handle.", function ); goto on_error; } if( libfdata_list_initialize( &( internal_file->records_list ), (intptr_t *) internal_file->io_handle, NULL, NULL, (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfcache_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libevt_record_values_read_element_data, NULL, LIBFDATA_FLAG_DATA_HANDLE_NON_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create records list.", function ); goto on_error; } if( libfdata_list_initialize( &( internal_file->recovered_records_list ), (intptr_t *) internal_file->io_handle, NULL, NULL, (int (*)(intptr_t *, intptr_t *, libfdata_list_element_t *, libfcache_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libevt_record_values_read_element_data, NULL, LIBFDATA_FLAG_DATA_HANDLE_NON_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create recovered records list.", function ); goto on_error; } if( libfcache_cache_initialize( &( internal_file->records_cache ), LIBEVT_MAXIMUM_CACHE_ENTRIES_RECORDS, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create records cache.", function ); goto on_error; } *file = (libevt_file_t *) internal_file; return( 1 ); on_error: if( internal_file != NULL ) { if( internal_file->recovered_records_list != NULL ) { libfdata_list_free( &( internal_file->recovered_records_list ), NULL ); } if( internal_file->records_list != NULL ) { libfdata_list_free( &( internal_file->records_list ), NULL ); } if( internal_file->io_handle != NULL ) { libevt_io_handle_free( &( internal_file->io_handle ), NULL ); } memory_free( internal_file ); } return( -1 ); }
/* Frees a file * Returns 1 if successful or -1 on error */ int libevt_file_free( libevt_file_t **file, libcerror_error_t **error ) { libevt_internal_file_t *internal_file = NULL; static char *function = "libevt_file_free"; int result = 1; if( file == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid file.", function ); return( -1 ); } if( *file != NULL ) { internal_file = (libevt_internal_file_t *) *file; if( internal_file->file_io_handle != NULL ) { if( libevt_file_close( *file, error ) != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_CLOSE_FAILED, "%s: unable to close file.", function ); result = -1; } } *file = NULL; if( libfcache_cache_free( &( internal_file->records_cache ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free records cache.", function ); result = -1; } if( libfdata_list_free( &( internal_file->recovered_records_list ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free recovered records list.", function ); result = -1; } if( libfdata_list_free( &( internal_file->records_list ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free records list.", function ); result = -1; } if( libevt_io_handle_free( &( internal_file->io_handle ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free IO handle.", function ); result = -1; } memory_free( internal_file ); } return( result ); }