/* Clones (duplicates) the tree * Returns 1 if successful or -1 on error */ int libfdata_tree_clone( libfdata_tree_t **destination_tree, libfdata_tree_t *source_tree, libcerror_error_t **error ) { libfdata_internal_tree_t *internal_source_tree = NULL; libfdata_tree_node_t *source_tree_root_node = NULL; intptr_t *destination_data_handle = NULL; static char *function = "libfdata_tree_clone"; off64_t node_offset = 0; size64_t node_size = 0; uint32_t node_flags = 0; int node_file_index = -1; if( destination_tree == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid destination tree.", function ); return( -1 ); } if( *destination_tree != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: invalid destination tree value already set.", function ); return( -1 ); } if( source_tree == NULL ) { *destination_tree = NULL; return( 1 ); } internal_source_tree = (libfdata_internal_tree_t *) source_tree; if( internal_source_tree->data_handle != NULL ) { if( internal_source_tree->free_data_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid source tree - missing free data handle function.", function ); goto on_error; } if( internal_source_tree->clone_data_handle == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid source tree - missing clone data handle function.", function ); goto on_error; } if( internal_source_tree->clone_data_handle( &destination_data_handle, internal_source_tree->data_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to clone data handle.", function ); goto on_error; } } if( libfdata_tree_initialize( destination_tree, destination_data_handle, internal_source_tree->free_data_handle, internal_source_tree->clone_data_handle, internal_source_tree->read_node, internal_source_tree->read_sub_nodes, LIBFDATA_DATA_HANDLE_FLAG_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create destination tree.", function ); goto on_error; } destination_data_handle = NULL; if( libfdata_tree_get_root_node( source_tree, &source_tree_root_node, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve source tree root node.", function ); goto on_error; } if( libfdata_tree_node_get_data_range( source_tree_root_node, &node_file_index, &node_offset, &node_size, &node_flags, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve source tree root node data range.", function ); goto on_error; } if( libfdata_tree_set_root_node( *destination_tree, node_file_index, node_offset, node_size, node_flags, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set destination tree root node.", function ); goto on_error; } /* TODO or clone all the tree nodes ? */ return( 1 ); on_error: if( *destination_tree != NULL ) { libfdata_tree_free( destination_tree, NULL ); } if( destination_data_handle != NULL ) { internal_source_tree->free_data_handle( &destination_data_handle, 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 ); }
/* 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, liberror_error_t **error ) { libesedb_page_tree_t *database_page_tree = NULL; libesedb_values_tree_value_t *values_tree_value = NULL; libfcache_cache_t *database_values_cache = NULL; libfdata_tree_t *database_values_tree = NULL; libfdata_tree_node_t *database_values_tree_node = NULL; uint8_t *data = NULL; static char *function = "libesedb_database_read"; off64_t node_data_offset = 0; size_t data_size = 0; int number_of_leaf_nodes = 0; int leaf_node_index = 0; if( database == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_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 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create database page tree.", function ); goto on_error; } /* TODO clone function */ if( libfdata_tree_initialize( &database_values_tree, (intptr_t *) database_page_tree, (int (*)(intptr_t **, liberror_error_t **)) &libesedb_page_tree_free, NULL, &libesedb_page_tree_read_node_value, &libesedb_page_tree_read_sub_nodes, LIBFDATA_FLAG_IO_HANDLE_MANAGED, error ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_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 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_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_tree_set_root_node( database_values_tree, node_data_offset, 0, error ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set root node in database values tree.", function ); goto on_error; } if( libfdata_tree_get_number_of_leaf_nodes( database_values_tree, file_io_handle, database_values_cache, &number_of_leaf_nodes, 0, error ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve number of leaf nodes from database values tree.", function ); goto on_error; } for( leaf_node_index = 0; leaf_node_index < number_of_leaf_nodes; leaf_node_index++ ) { if( libfdata_tree_get_leaf_node_by_index( database_values_tree, file_io_handle, database_values_cache, leaf_node_index, &database_values_tree_node, 0, error ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve leaf node: %d from database values tree.", function, leaf_node_index ); goto on_error; } if( libfdata_tree_node_get_node_value( database_values_tree_node, file_io_handle, database_values_cache, (intptr_t **) &values_tree_value, 0, error ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve node value from values tree node.", function ); goto on_error; } if( libesedb_values_tree_value_read_data( values_tree_value, file_io_handle, io_handle, pages_vector, pages_cache, &data, &data_size, error ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_IO, LIBERROR_IO_ERROR_READ_FAILED, "%s: unable to read values tree value data.", function ); goto on_error; } /* TODO */ #if defined( HAVE_DEBUG_OUTPUT ) if( libnotify_verbose != 0 ) { if( data_size > 0 ) { libnotify_printf( "%s: database value: %d data:\n", function, leaf_node_index ); libnotify_print_data( data, data_size ); } } #endif } if( libfcache_cache_free( &database_values_cache, error ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to free database values cache.", function ); goto on_error; } if( libfdata_tree_free( &database_values_tree, error ) != 1 ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_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_tree_free( &database_values_tree, NULL ); } if( database_page_tree != NULL ) { libesedb_page_tree_free( &database_page_tree, NULL ); } return( -1 ); }
/* Reads a specifi local descriptors tree * Returns 1 if successful or -1 on error */ int libpff_local_descriptors_tree_read( libfdata_tree_t **local_descriptors_tree, 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, libcerror_error_t **error ) { libpff_index_value_t *offset_index_value = NULL; libpff_local_descriptors_t *local_descriptors = NULL; static char *function = "libpff_local_descriptors_tree_read"; if( local_descriptors_tree == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid local descriptors tree.", function ); return( -1 ); } if( *local_descriptors_tree != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: local descriptors tree 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 ); } 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 retrieve 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: missing offset index value: %" PRIu64 ".", function, data_identifier ); 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 /* Create the local descriptors tree */ if( libpff_local_descriptors_initialize( &local_descriptors, io_handle, offsets_index, descriptor_identifier, offset_index_value->file_offset, recovered, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create local descriptors.", function ); goto on_error; } if( libfdata_tree_initialize( local_descriptors_tree, (intptr_t *) local_descriptors, (int (*)(intptr_t **, libcerror_error_t **)) &libpff_local_descriptors_free, (int (*)(intptr_t **, intptr_t *, libcerror_error_t **)) &libpff_local_descriptors_clone, (int (*)(intptr_t *, intptr_t *, libfdata_tree_node_t *, libfcache_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libpff_local_descriptors_read_node, (int (*)(intptr_t *, intptr_t *, libfdata_tree_node_t *, libfcache_cache_t *, int, off64_t, size64_t, uint32_t, uint8_t, libcerror_error_t **)) &libpff_local_descriptors_read_sub_nodes, LIBFDATA_DATA_HANDLE_FLAG_MANAGED, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create local descriptors tree", function ); goto on_error; } if( libfdata_tree_set_root_node( *local_descriptors_tree, 0, offset_index_value->file_offset, (size64_t) data_identifier, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set local descriptors tree root node.", function ); goto on_error; } return( 1 ); on_error: if( local_descriptors != NULL ) { libpff_local_descriptors_free( &local_descriptors, NULL ); } return( -1 ); }