/* Creates a cache * Make sure the value cache is referencing, is set to NULL * Returns 1 if successful or -1 on error */ int libfdata_cache_initialize( libfdata_cache_t **cache, int maximum_cache_entries, libcerror_error_t **error ) { return( libfcache_cache_initialize( (libfcache_cache_t **) cache, maximum_cache_entries, error ) ); }
/* 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 ); }
/* Creates an index * Make sure the value index is referencing, is set to NULL * Returns 1 if successful or -1 on error */ int libesedb_index_initialize( libesedb_index_t **index, libbfio_handle_t *file_io_handle, libesedb_io_handle_t *io_handle, libesedb_table_definition_t *table_definition, libesedb_table_definition_t *template_table_definition, libesedb_catalog_definition_t *index_catalog_definition, libfdata_vector_t *pages_vector, libfcache_cache_t *pages_cache, libfdata_vector_t *long_values_pages_vector, libfcache_cache_t *long_values_pages_cache, libfdata_btree_t *table_values_tree, libfcache_cache_t *table_values_cache, libfdata_btree_t *long_values_tree, libfcache_cache_t *long_values_cache, libcerror_error_t **error ) { libesedb_internal_index_t *internal_index = NULL; libesedb_page_tree_t *index_page_tree = NULL; static char *function = "libesedb_index_initialize"; off64_t node_data_offset = 0; if( index == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid index.", function ); return( -1 ); } if( *index != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid index value already set.", function ); return( -1 ); } if( table_definition == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid table definition.", function ); return( -1 ); } if( index_catalog_definition == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid index catalog definition.", function ); return( -1 ); } internal_index = memory_allocate_structure( libesedb_internal_index_t ); if( internal_index == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create index.", function ); goto on_error; } if( memory_set( internal_index, 0, sizeof( libesedb_internal_index_t ) ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear index.", function ); memory_free( internal_index ); return( -1 ); } /* TODO (template) table definition required ? */ if( libesedb_page_tree_initialize( &index_page_tree, io_handle, pages_vector, pages_cache, index_catalog_definition->identifier, NULL, NULL, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create index page tree.", function ); goto on_error; } /* TODO clone function */ if( libfdata_btree_initialize( &( internal_index->index_values_tree ), (intptr_t *) index_page_tree, (int (*)(intptr_t **, libcerror_error_t **)) &libesedb_page_tree_free, NULL, (int (*)(intptr_t *, intptr_t *, libfdata_btree_node_t *, int, off64_t, size64_t, uint32_t, intptr_t *, uint8_t, libcerror_error_t **)) &libesedb_page_tree_read_node, (int (*)(intptr_t *, intptr_t *, libfdata_btree_t *, libfcache_cache_t *, int, int, off64_t, size64_t, uint32_t, intptr_t *, uint8_t, libcerror_error_t **)) &libesedb_page_tree_read_leaf_value, LIBFDATA_DATA_HANDLE_FLAG_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create index values tree.", function ); libesedb_page_tree_free( &index_page_tree, NULL ); goto on_error; } if( libfcache_cache_initialize( &( internal_index->index_values_cache ), LIBESEDB_MAXIMUM_CACHE_ENTRIES_INDEX_VALUES, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create index values cache.", function ); goto on_error; } node_data_offset = index_catalog_definition->father_data_page_number - 1; node_data_offset *= io_handle->page_size; if( libfdata_btree_set_root_node( internal_index->index_values_tree, 0, node_data_offset, 0, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set root node in index values tree.", function ); goto on_error; } internal_index->io_handle = io_handle; internal_index->file_io_handle = file_io_handle; internal_index->table_definition = table_definition; internal_index->template_table_definition = template_table_definition; internal_index->index_catalog_definition = index_catalog_definition; internal_index->pages_vector = pages_vector; internal_index->pages_cache = pages_cache; internal_index->long_values_pages_vector = long_values_pages_vector; internal_index->long_values_pages_cache = long_values_pages_cache; internal_index->table_values_tree = table_values_tree; internal_index->table_values_cache = table_values_cache; internal_index->long_values_tree = long_values_tree; internal_index->long_values_cache = long_values_cache; *index = (libesedb_index_t *) internal_index; return( 1 ); on_error: if( internal_index != NULL ) { if( internal_index->index_values_cache != NULL ) { libfcache_cache_free( &( internal_index->index_values_cache ), NULL ); } if( internal_index->index_values_tree != NULL ) { libfdata_btree_free( &( internal_index->index_values_tree ), NULL ); } memory_free( internal_index ); } return( -1 ); }
/* 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 ); }
/* Creates a resource file * Make sure the value resource_file is referencing, is set to NULL * Returns 1 if successful or -1 on error */ int resource_file_initialize( resource_file_t **resource_file, uint32_t preferred_language_identifier, libcerror_error_t **error ) { static char *function = "resource_file_initialize"; if( resource_file == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid resource file.", function ); return( -1 ); } if( *resource_file != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid resource file value already set.", function ); return( -1 ); } *resource_file = memory_allocate_structure( resource_file_t ); if( *resource_file == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_INSUFFICIENT, "%s: unable to create resource file.", function ); goto on_error; } if( memory_set( *resource_file, 0, sizeof( resource_file_t ) ) == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_MEMORY, LIBCERROR_MEMORY_ERROR_SET_FAILED, "%s: unable to clear resource file.", function ); memory_free( *resource_file ); *resource_file = NULL; return( -1 ); } if( libexe_file_initialize( &( ( *resource_file )->exe_file ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create EXE file.", function ); goto on_error; } if( libwrc_stream_initialize( &( ( *resource_file )->resource_stream ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create resource stream.", function ); goto on_error; } if( libfcache_cache_initialize( &( ( *resource_file )->message_string_cache ), 16, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create message string cache.", function ); goto on_error; } ( *resource_file )->preferred_language_identifier = preferred_language_identifier; return( 1 ); on_error: if( *resource_file != NULL ) { if( ( *resource_file )->resource_stream != NULL ) { libwrc_stream_free( &( ( *resource_file )->resource_stream ), NULL ); } if( ( *resource_file )->exe_file != NULL ) { libexe_file_free( &( ( *resource_file )->exe_file ), NULL ); } memory_free( *resource_file ); *resource_file = NULL; } return( -1 ); }
/* Reads the database * Returns 1 if successful or -1 on error */ int libesedb_database_read( libesedb_database_t *database, libbfio_handle_t *file_io_handle, libesedb_io_handle_t *io_handle, libfdata_vector_t *pages_vector, libfcache_cache_t *pages_cache, libcerror_error_t **error ) { libesedb_data_definition_t *data_definition = NULL; libesedb_page_tree_t *database_page_tree = NULL; libfcache_cache_t *database_values_cache = NULL; libfdata_btree_t *database_values_tree = NULL; uint8_t *data = NULL; static char *function = "libesedb_database_read"; off64_t node_data_offset = 0; size_t data_size = 0; int leaf_value_index = 0; int number_of_leaf_values = 0; if( database == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid database.", function ); return( -1 ); } if( libesedb_page_tree_initialize( &database_page_tree, io_handle, pages_vector, pages_cache, LIBESEDB_FDP_OBJECT_IDENTIFIER_DATABASE, NULL, NULL, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create database page tree.", function ); goto on_error; } /* TODO clone function */ if( libfdata_btree_initialize( &database_values_tree, (intptr_t *) database_page_tree, (int (*)(intptr_t **, libcerror_error_t **)) &libesedb_page_tree_free, NULL, (int (*)(intptr_t *, intptr_t *, libfdata_btree_node_t *, int, off64_t, size64_t, uint32_t, intptr_t *, uint8_t, libcerror_error_t **)) &libesedb_page_tree_read_node, (int (*)(intptr_t *, intptr_t *, libfdata_btree_t *, libfcache_cache_t *, int, int, off64_t, size64_t, uint32_t, intptr_t *, uint8_t, libcerror_error_t **)) &libesedb_page_tree_read_leaf_value, LIBFDATA_DATA_HANDLE_FLAG_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create database values tree.", function ); goto on_error; } database_page_tree = NULL; if( libfcache_cache_initialize( &database_values_cache, LIBESEDB_MAXIMUM_CACHE_ENTRIES_TREE_VALUES, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create database values cache.", function ); goto on_error; } node_data_offset = LIBESEDB_PAGE_NUMBER_DATABASE - 1; node_data_offset *= io_handle->page_size; if( libfdata_btree_set_root_node( database_values_tree, 0, node_data_offset, 0, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set root node in database values tree.", function ); goto on_error; } if( libfdata_btree_get_number_of_leaf_values( database_values_tree, (intptr_t *) file_io_handle, database_values_cache, &number_of_leaf_values, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve number of leaf values from database values tree.", function ); goto on_error; } for( leaf_value_index = 0; leaf_value_index < number_of_leaf_values; leaf_value_index++ ) { if( libfdata_btree_get_leaf_value_by_index( database_values_tree, (intptr_t *) file_io_handle, database_values_cache, leaf_value_index, (intptr_t **) &data_definition, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve leaf value: %d from database values tree.", function, leaf_value_index ); goto on_error; } if( libesedb_data_definition_read_data( data_definition, file_io_handle, io_handle, pages_vector, pages_cache, &data, &data_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read data definition data.", function ); goto on_error; } /* TODO */ #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( data_size > 0 ) { libcnotify_printf( "%s: database value: %d data:\n", function, leaf_value_index ); libcnotify_print_data( data, data_size, 0 ); } } #endif } if( libfcache_cache_free( &database_values_cache, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free database values cache.", function ); goto on_error; } if( libfdata_btree_free( &database_values_tree, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free database values tree.", function ); goto on_error; } return( 1 ); on_error: if( database_values_cache != NULL ) { libfcache_cache_free( &database_values_cache, NULL ); } if( database_values_tree != NULL ) { libfdata_btree_free( &database_values_tree, NULL ); } if( database_page_tree != NULL ) { libesedb_page_tree_free( &database_page_tree, NULL ); } return( -1 ); }
/* 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 ); }
/* Reads the B-tree file * Returns 1 if successful or -1 on error */ int libfshfs_btree_file_read( libfshfs_btree_file_t *btree_file, libfshfs_io_handle_t *io_handle, libbfio_handle_t *file_io_handle, libfshfs_fork_descriptor_t *fork_descriptor, libcerror_error_t **error ) { libfcache_cache_t *btree_nodes_cache = NULL; libfdata_vector_t *btree_nodes_vector = NULL; libfshfs_allocation_block_t *allocation_block = NULL; fshfs_btree_node_descriptor_t *btree_node_descriptor = NULL; static char *function = "libfshfs_btree_file_read"; size_t btree_node_data_offset = 0; uint32_t next_node_number = 0; uint32_t previous_node_number = 0; uint16_t number_of_records = 0; uint16_t record_index = 0; uint16_t record_offset = 0; #if defined( HAVE_DEBUG_OUTPUT ) uint16_t value_16bit = 0; size_t btree_node_record_offsets_data_size = 0; #endif if( btree_file == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid B-tree file.", function ); return( -1 ); } if( libfshfs_allocation_block_vector_initialize( &btree_nodes_vector, io_handle, 512, fork_descriptor, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create B-tree nodes vector.", function ); goto on_error; } /* TODO add max number of cache definition */ if( libfcache_cache_initialize( &btree_nodes_cache, 4, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create B-tree nodes cache.", function ); goto on_error; } if( libfdata_vector_get_element_value_by_index( btree_nodes_vector, (intptr_t *) file_io_handle, btree_nodes_cache, 0, (intptr_t **) &allocation_block, 0, error ) == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve B-tree node: 0.", function ); goto on_error; } if( allocation_block == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid allocation block: 0.", function ); goto on_error; } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: B-tree node data:\n", function ); libcnotify_print_data( (uint8_t *) allocation_block->data, 512, LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); } #endif if( libfshfs_btree_file_read_node_descriptor( allocation_block->data, allocation_block->data_size, &number_of_records, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read B-tree node descriptor.", function ); goto on_error; } /* TODO add bounds checks */ #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { btree_node_record_offsets_data_size = ( number_of_records + 1 ) * 2; libcnotify_printf( "%s: B-tree node record offsets data:\n", function ); libcnotify_print_data( (uint8_t *) &( allocation_block->data[ 512 - btree_node_record_offsets_data_size ] ), btree_node_record_offsets_data_size, LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); } #endif btree_node_data_offset = 510; for( record_index = 0; record_index < number_of_records; record_index++ ) { byte_stream_copy_to_uint16_big_endian( &( ( allocation_block->data )[ btree_node_data_offset ] ), record_offset ); btree_node_data_offset -= 2; #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: record offset: %" PRIu16 "\t\t\t\t: 0x%04" PRIx16 "\n", function, record_index, record_offset ); } #endif } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { byte_stream_copy_to_uint16_big_endian( &( ( allocation_block->data )[ btree_node_data_offset ] ), value_16bit ); libcnotify_printf( "%s: free space offset\t\t\t\t: 0x%04" PRIx16 "\n", function, value_16bit ); } #endif if( libfdata_vector_free( &btree_nodes_vector, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free B-tree nodes vector.", function ); goto on_error; } if( libfcache_cache_free( &btree_nodes_cache, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free B-tree nodes cache.", function ); goto on_error; } return( 1 ); on_error: if( btree_nodes_cache != NULL ) { libfcache_cache_free( &btree_nodes_cache, NULL ); } if( btree_nodes_vector != NULL ) { libfdata_vector_free( &btree_nodes_vector, 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 ); }
/* Clones (duplicates) the cache, not the cache values * Returns 1 if successful or -1 on error */ int libfcache_cache_clone( libfcache_cache_t **destination_cache, libfcache_cache_t *source_cache, libcerror_error_t **error ) { libfcache_internal_cache_t *internal_source_cache = NULL; static char *function = "libfcache_cache_clone"; int number_of_cache_entries = 0; if( destination_cache == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid destination cache.", function ); return( -1 ); } if( *destination_cache != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: destination cache already set.", function ); return( -1 ); } if( source_cache == NULL ) { *destination_cache = NULL; return( 1 ); } internal_source_cache = (libfcache_internal_cache_t *) source_cache; if( libcdata_array_get_number_of_entries( internal_source_cache->entries, &number_of_cache_entries, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve number of cache entries from source entries array.", function ); return( -1 ); } if( libfcache_cache_initialize( destination_cache, number_of_cache_entries, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create destination cache.", function ); return( -1 ); } return( 1 ); }
/* Reads the catalog * Returns 1 if successful or -1 on error */ int libesedb_catalog_read( libesedb_catalog_t *catalog, libbfio_handle_t *file_io_handle, libesedb_io_handle_t *io_handle, uint32_t page_number, libfdata_vector_t *pages_vector, libfcache_cache_t *pages_cache, libcerror_error_t **error ) { libesedb_catalog_definition_t *catalog_definition = NULL; libesedb_data_definition_t *data_definition = NULL; libesedb_page_tree_t *catalog_page_tree = NULL; libesedb_table_definition_t *table_definition = NULL; libfcache_cache_t *catalog_values_cache = NULL; libfdata_btree_t *catalog_values_tree = NULL; uint8_t *catalog_definition_data = NULL; static char *function = "libesedb_catalog_read"; off64_t node_data_offset = 0; size_t catalog_definition_data_size = 0; int leaf_value_index = 0; int number_of_leaf_values = 0; if( catalog == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid catalog.", 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( page_number == 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_ZERO_OR_LESS, "%s: invalid page number value zero or less.", function ); return( -1 ); } if( libesedb_page_tree_initialize( &catalog_page_tree, io_handle, pages_vector, pages_cache, LIBESEDB_FDP_OBJECT_IDENTIFIER_CATALOG, NULL, NULL, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create catalog page tree.", function ); goto on_error; } /* TODO add clone function */ if( libfdata_btree_initialize( &catalog_values_tree, (intptr_t *) catalog_page_tree, (int (*)(intptr_t **, libcerror_error_t **)) &libesedb_page_tree_free, NULL, (int (*)(intptr_t *, intptr_t *, libfdata_btree_node_t *, int, off64_t, size64_t, uint32_t, intptr_t *, uint8_t, libcerror_error_t **)) &libesedb_page_tree_read_node, (int (*)(intptr_t *, intptr_t *, libfdata_btree_t *, libfcache_cache_t *, int, int, off64_t, size64_t, uint32_t, intptr_t *, uint8_t, libcerror_error_t **)) &libesedb_page_tree_read_leaf_value, LIBFDATA_DATA_HANDLE_FLAG_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create catalog values tree.", function ); goto on_error; } catalog_page_tree = NULL; if( libfcache_cache_initialize( &catalog_values_cache, LIBESEDB_MAXIMUM_CACHE_ENTRIES_TREE_VALUES, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create catalog values cache.", function ); goto on_error; } node_data_offset = ( (off64_t) page_number - 1 ) * io_handle->page_size; if( libfdata_btree_set_root_node( catalog_values_tree, 0, node_data_offset, 0, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set root node in catalog values tree.", function ); goto on_error; } if( libfdata_btree_get_number_of_leaf_values( catalog_values_tree, (intptr_t *) file_io_handle, catalog_values_cache, &number_of_leaf_values, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve number of leaf values from catalog values tree.", function ); goto on_error; } for( leaf_value_index = 0; leaf_value_index < number_of_leaf_values; leaf_value_index++ ) { if( libfdata_btree_get_leaf_value_by_index( catalog_values_tree, (intptr_t *) file_io_handle, catalog_values_cache, leaf_value_index, (intptr_t **) &data_definition, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve leaf value: %d from catalog values tree.", function, leaf_value_index ); goto on_error; } if( libesedb_data_definition_read_data( data_definition, file_io_handle, io_handle, pages_vector, pages_cache, &catalog_definition_data, &catalog_definition_data_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read data definition data.", function ); goto on_error; } if( libesedb_catalog_definition_initialize( &catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create catalog definition.", function ); goto on_error; } if( libesedb_catalog_definition_read( catalog_definition, catalog_definition_data, catalog_definition_data_size, io_handle->ascii_codepage, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read catalog definition.", function ); goto on_error; } if( ( catalog_definition->type != LIBESEDB_CATALOG_DEFINITION_TYPE_TABLE ) && ( table_definition == NULL ) ) { /* TODO add build-in table 1 support */ #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: missing table definition for catalog definition type: %" PRIu16 ".\n", function, catalog_definition->type ); } #endif if( libesedb_catalog_definition_free( &catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free catalog definition.", function ); goto on_error; } catalog_definition = NULL; } else switch( catalog_definition->type ) { case LIBESEDB_CATALOG_DEFINITION_TYPE_TABLE: table_definition = NULL; if( libesedb_table_definition_initialize( &table_definition, catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create table definition.", function ); libesedb_table_definition_free( &table_definition, NULL ); goto on_error; } catalog_definition = NULL; if( libcdata_list_append_value( catalog->table_definition_list, (intptr_t *) table_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append table definition to table definition list.", function ); libesedb_table_definition_free( &table_definition, NULL ); goto on_error; } break; case LIBESEDB_CATALOG_DEFINITION_TYPE_COLUMN: if( libesedb_table_definition_append_column_catalog_definition( table_definition, catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append column catalog definition to table definition.", function ); goto on_error; } catalog_definition = NULL; break; case LIBESEDB_CATALOG_DEFINITION_TYPE_INDEX: if( libesedb_table_definition_append_index_catalog_definition( table_definition, catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append index catalog definition to table definition.", function ); goto on_error; } catalog_definition = NULL; break; case LIBESEDB_CATALOG_DEFINITION_TYPE_LONG_VALUE: if( libesedb_table_definition_set_long_value_catalog_definition( table_definition, catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set long value catalog definition in table definition.", function ); goto on_error; } catalog_definition = NULL; break; case LIBESEDB_CATALOG_DEFINITION_TYPE_CALLBACK: if( libesedb_table_definition_set_callback_catalog_definition( table_definition, catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set callback catalog definition in table definition.", function ); goto on_error; } catalog_definition = NULL; break; default: #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: unsupported catalog definition type: %" PRIu16 ".\n", function, catalog_definition->type ); } #endif if( libesedb_catalog_definition_free( &catalog_definition, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free catalog definition.", function ); goto on_error; } catalog_definition = NULL; break; } } if( libfcache_cache_free( &catalog_values_cache, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free catalog values cache.", function ); goto on_error; } if( libfdata_btree_free( &catalog_values_tree, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free catalog values tree.", function ); goto on_error; } return( 1 ); on_error: if( catalog_definition != NULL ) { libesedb_catalog_definition_free( &catalog_definition, NULL ); } if( catalog_values_cache != NULL ) { libfcache_cache_free( &catalog_values_cache, NULL ); } if( catalog_values_tree != NULL ) { libfdata_btree_free( &catalog_values_tree, NULL ); } if( catalog_page_tree != NULL ) { libesedb_page_tree_free( &catalog_page_tree, NULL ); } return( -1 ); }
/* Opens a file for reading * Returns 1 if successful or -1 on error */ int libregf_file_open_read( libregf_internal_file_t *internal_file, libbfio_handle_t *file_io_handle, libcerror_error_t **error ) { static char *function = "libregf_file_open_read"; size64_t file_size = 0; uint32_t hive_bins_size = 0; uint32_t root_key_offset = 0; int result = 0; 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->hive_bins_list != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid file - hive bins list already set.", function ); return( -1 ); } if( internal_file->key_tree != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid file - key tree 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( libregf_io_handle_read_file_header( internal_file->io_handle, file_io_handle, &root_key_offset, &hive_bins_size, 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( ( internal_file->io_handle->file_type == LIBREGF_FILE_TYPE_REGISTRY ) && ( file_size > 4096 ) ) { /* TODO print data between header and hive bins list offset ? */ #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "Reading hive bins:\n" ); } #endif internal_file->io_handle->hive_bins_list_offset = 4096; if( libregf_hive_bins_list_initialize( &( internal_file->hive_bins_list ), internal_file->io_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create hive bins list.", function ); goto on_error; } result = libregf_hive_bins_list_read( internal_file->hive_bins_list, file_io_handle, internal_file->io_handle->hive_bins_list_offset, hive_bins_size, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, "%s: unable to read hive bins.", function ); goto on_error; } else if( result != 0 ) { /* TODO free & clone function */ if( libfdata_tree_initialize( &( internal_file->key_tree ), (intptr_t *) internal_file->hive_bins_list, NULL, NULL, (int (*)(intptr_t *, intptr_t *, libfdata_tree_node_t *, libfdata_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libregf_key_item_read_node_data, (int (*)(intptr_t *, intptr_t *, libfdata_tree_node_t *, libfdata_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libregf_key_item_read_sub_nodes, 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 key tree.", function ); goto on_error; } if( libfcache_cache_initialize( &( internal_file->key_cache ), LIBREGF_MAXIMUM_CACHE_ENTRIES_KEYS, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create key cache.", function ); goto on_error; } if( libfdata_tree_set_root_node( internal_file->key_tree, 0, (off64_t) root_key_offset, 0, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set key tree root node.", function ); goto on_error; } } } return( 1 ); on_error: if( internal_file->key_cache != NULL ) { libfcache_cache_free( &( internal_file->key_cache ), NULL ); } if( internal_file->key_tree != NULL ) { libfdata_tree_free( &( internal_file->key_tree ), NULL ); } if( internal_file->hive_bins_list != NULL ) { libregf_hive_bins_list_free( &( internal_file->hive_bins_list ), 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 ); }