Пример #1
0
/* 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 );
}
Пример #2
0
/* 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 );
}
Пример #3
0
/* 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 );
}
Пример #4
0
/* Closes a file
 * Returns 0 if successful or -1 on error
 */
int libregf_file_close(
     libregf_file_t *file,
     libcerror_error_t **error )
{
	libregf_internal_file_t *internal_file = NULL;
	static char *function                  = "libregf_file_close";
	int result                             = 0;

	if( file == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid file.",
		 function );

		return( -1 );
	}
	internal_file = (libregf_internal_file_t *) file;

	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 defined( HAVE_DEBUG_OUTPUT )
	if( libcnotify_verbose != 0 )
	{
		if( internal_file->file_io_handle_created_in_library != 0 )
		{
			if( libregf_debug_print_read_offsets(
			     internal_file->file_io_handle,
			     error ) != 1 )
			{
				libcerror_error_set(
				 error,
				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
				 LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
				 "%s: unable to print the read offsets.",
				 function );
			}
		}
	}
#endif
	if( internal_file->file_io_handle_opened_in_library != 0 )
	{
		if( libbfio_handle_close(
		     internal_file->file_io_handle,
		     error ) != 0 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_CLOSE_FAILED,
			 "%s: unable to close file IO handle.",
			 function );

			result = -1;
		}
		internal_file->file_io_handle_opened_in_library = 0;
	}
	if( internal_file->file_io_handle_created_in_library != 0 )
	{
		if( libbfio_handle_free(
		     &( internal_file->file_io_handle ),
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
			 "%s: unable to free file IO handle.",
			 function );

			result = -1;
		}
		internal_file->file_io_handle_created_in_library = 0;
	}
	internal_file->file_io_handle = NULL;

	if( libregf_io_handle_clear(
	     internal_file->io_handle,
	     error ) != 1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
		 "%s: unable to clear IO handle.",
		 function );

		result = -1;
	}
	if( internal_file->hive_bins_list != NULL )
	{
		if( libregf_hive_bins_list_free(
		     &( internal_file->hive_bins_list ),
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
			 "%s: unable to free hive bins list.",
			 function );

			result = -1;
		}
	}
	if( internal_file->key_tree != NULL )
	{
		if( libfdata_tree_free(
		     &( internal_file->key_tree ),
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
			 "%s: unable to free key tree.",
			 function );

			result = -1;
		}
	}
	if( internal_file->key_cache != NULL )
	{
		if( libfcache_cache_free(
		     &( internal_file->key_cache ),
		     error ) != 1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
			 "%s: unable to free key cache.",
			 function );

			result = -1;
		}
	}
	return( result );
}