/* 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 ); }
/* 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 ); }
/* 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 ); }