/* Creates an item tree node from the descriptor index * * If a descriptor index value has no existing parent it is added to the orphan node list * and the function will return 0 * * Returns 1 if successful, 0 if the item tree node could not be created or -1 on error */ int libpff_item_tree_create_node( libcdata_tree_node_t *item_tree_root_node, libbfio_handle_t *file_io_handle, libfdata_tree_t *descriptor_index_tree, libfdata_tree_node_t *descriptor_index_tree_node, libfcache_cache_t *index_tree_cache, libcdata_list_t *orphan_node_list, libcdata_tree_node_t **root_folder_item_tree_node, libcerror_error_t **error ) { libcdata_tree_node_t *item_tree_node = NULL; libcdata_tree_node_t *parent_node = NULL; libfdata_tree_node_t *descriptor_index_tree_parent_node = NULL; libfdata_tree_node_t *descriptor_index_tree_sub_node = NULL; libpff_index_value_t *descriptor_index_value = NULL; libpff_item_descriptor_t *item_descriptor = NULL; static char *function = "libpff_item_tree_create_node"; int leaf_node_index = 0; int number_of_sub_nodes = 0; int result = 0; int sub_node_index = 0; if( item_tree_root_node == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid item tree root node.", function ); return( -1 ); } if( orphan_node_list == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid orphan node list.", function ); return( -1 ); } if( root_folder_item_tree_node == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid root folder item tree node.", function ); return( -1 ); } /* Check if the index node can be read */ if( libfdata_tree_node_get_number_of_sub_nodes( descriptor_index_tree_node, (intptr_t *) file_io_handle, index_tree_cache, &number_of_sub_nodes, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve number of sub nodes from descriptor index tree node.", function ); #if defined( HAVE_DEBUG_OUTPUT ) if( ( libcnotify_verbose != 0 ) && ( error != NULL ) && ( *error != NULL ) ) { libcnotify_print_error_backtrace( *error ); } #endif libcerror_error_free( error ); /* TODO flag corrupt item tree */ return( 0 ); } result = libfdata_tree_node_is_deleted( descriptor_index_tree_node, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if descriptor index tree sub node: %d is deleted.", function, sub_node_index ); return( -1 ); } else if( result != 0 ) { return( 0 ); } result = libfdata_tree_node_is_leaf( descriptor_index_tree_node, (intptr_t *) file_io_handle, index_tree_cache, 0, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if descriptor index tree sub node: %d is a leaf node.", function, sub_node_index ); return( -1 ); } else if( result == 0 ) { for( sub_node_index = 0; sub_node_index < number_of_sub_nodes; sub_node_index++ ) { if( libfdata_tree_node_get_sub_node_by_index( descriptor_index_tree_node, (intptr_t *) file_io_handle, index_tree_cache, sub_node_index, &descriptor_index_tree_sub_node, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve sub node: %d from descriptor index tree node.", function, sub_node_index ); return( -1 ); } result = libpff_item_tree_create_node( item_tree_root_node, file_io_handle, descriptor_index_tree, descriptor_index_tree_sub_node, index_tree_cache, orphan_node_list, root_folder_item_tree_node, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create index tree from descriptor index tree sub node: %d.", function, sub_node_index ); return( -1 ); } } } else { if( libfdata_tree_node_get_node_value( descriptor_index_tree_node, (intptr_t *) file_io_handle, index_tree_cache, (intptr_t **) &descriptor_index_value, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve descriptor index tree sub node value.", function ); return( -1 ); } if( descriptor_index_value == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing descriptor index tree sub node value.", function ); return( -1 ); } if( descriptor_index_value->identifier > (uint64_t) UINT32_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: descriptor index identifier value exceeds maximum.", function ); return( -1 ); } /* Create a new item descriptor */ if( libpff_item_descriptor_initialize( &item_descriptor, (uint32_t) descriptor_index_value->identifier, descriptor_index_value->data_identifier, descriptor_index_value->local_descriptors_identifier, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create item descriptor.", function ); return( -1 ); } if( item_descriptor == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing item descriptor.", function ); return( -1 ); } /* The root folder index descriptor points to itself as its parent */ if( descriptor_index_value->identifier == descriptor_index_value->parent_identifier ) { if( *root_folder_item_tree_node != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: root folder item tree node already set.", function ); libpff_item_descriptor_free( &item_descriptor, NULL ); return( -1 ); } if( libcdata_tree_node_initialize( root_folder_item_tree_node, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create root folder item tree node.", function ); libpff_item_descriptor_free( &item_descriptor, NULL ); return( -1 ); } if( libcdata_tree_node_set_value( *root_folder_item_tree_node, (intptr_t *) item_descriptor, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set item descriptor in root folder item tree node.", function ); libcdata_tree_node_free( root_folder_item_tree_node, NULL, NULL ); libpff_item_descriptor_free( &item_descriptor, NULL ); return( -1 ); } result = libcdata_tree_node_insert_node( item_tree_root_node, *root_folder_item_tree_node, (int (*)(intptr_t *, intptr_t *, libcerror_error_t **)) &libpff_item_descriptor_compare, LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES, NULL ); /* Free the node if it could not be inserted */ if( result != 1 ) { libcdata_tree_node_free( root_folder_item_tree_node, (int (*)(intptr_t **, libcerror_error_t **)) &libpff_item_descriptor_free, NULL ); } if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to insert item descriptor in item tree node.", function ); return( -1 ); } } else { result = libpff_item_tree_get_tree_node_by_identifier( item_tree_root_node, descriptor_index_value->parent_identifier, &parent_node, error ); if( result == 0 ) { #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: reading ahead for descriptor: %" PRIu64 " parent %" PRIu32 ".\n", function, descriptor_index_value->identifier, descriptor_index_value->parent_identifier ); } #endif result = libpff_index_tree_get_leaf_node_by_identifier( descriptor_index_tree, file_io_handle, index_tree_cache, descriptor_index_value->parent_identifier, &leaf_node_index, &descriptor_index_tree_parent_node, error ); if( result == 1 ) { if( descriptor_index_tree_parent_node == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid descriptor index tree parent node.", function ); libpff_item_descriptor_free( &item_descriptor, NULL ); return( -1 ); } result = libpff_item_tree_create_node( item_tree_root_node, file_io_handle, descriptor_index_tree, descriptor_index_tree_parent_node, index_tree_cache, orphan_node_list, root_folder_item_tree_node, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create index tree from descriptor index tree parent node: %" PRIu32 ".", function, descriptor_index_value->parent_identifier ); libpff_item_descriptor_free( &item_descriptor, NULL ); return( -1 ); } parent_node = NULL; result = libpff_item_tree_get_tree_node_by_identifier( item_tree_root_node, descriptor_index_value->parent_identifier, &parent_node, error ); } } if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to find parent node: %" PRIu32 ".", function, descriptor_index_value->parent_identifier ); libpff_item_descriptor_free( &item_descriptor, NULL ); return( -1 ); } else if( result == 0 ) { #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: parent node: %" PRIu32 " missing - found orphan node: %" PRIu64 ".\n", function, descriptor_index_value->parent_identifier, descriptor_index_value->identifier ); } #endif if( libcdata_tree_node_initialize( &item_tree_node, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create item tree node.", function ); libpff_item_descriptor_free( &item_descriptor, NULL ); return( -1 ); } if( libcdata_tree_node_set_value( item_tree_node, (intptr_t *) item_descriptor, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set item descriptor in item tree root node.", function ); libcdata_tree_node_free( &item_tree_node, NULL, NULL ); libpff_item_descriptor_free( &item_descriptor, NULL ); return( -1 ); } item_descriptor = NULL; if( libcdata_list_append_value( orphan_node_list, (intptr_t *) item_tree_node, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to append orphan node in orphan node list.", function ); libcdata_tree_node_free( &item_tree_node, (int (*)(intptr_t **, libcerror_error_t **)) &libpff_item_descriptor_free, NULL ); return( -1 ); } return( 0 ); } if( parent_node == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: invalid parent node.", function ); libpff_item_descriptor_free( &item_descriptor, NULL ); return( -1 ); } result = libcdata_tree_node_insert_value( parent_node, (intptr_t *) item_descriptor, (int (*)(intptr_t *, intptr_t *, libcerror_error_t **)) &libpff_item_descriptor_compare, LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES, error ); /* Free the node if it could not be inserted */ if( result != 1 ) { libpff_item_descriptor_free( &item_descriptor, NULL ); } if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to insert item descriptor in item tree node.", function ); return( -1 ); } } } 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 ); }
/* Retrieves the key for the specific UTF-16 encoded path * The path separator is the \ character * Returns 1 if successful, 0 if no such key or -1 on error */ int libregf_file_get_key_by_utf16_path( libregf_file_t *file, const uint16_t *utf16_string, size_t utf16_string_length, libregf_key_t **key, libcerror_error_t **error ) { libfdata_tree_node_t *key_tree_node = NULL; libfdata_tree_node_t *key_tree_sub_node = NULL; libregf_internal_file_t *internal_file = NULL; libregf_key_item_t *key_item = NULL; libregf_key_item_t *sub_key_item = NULL; uint16_t *utf16_string_segment = NULL; static char *function = "libregf_file_get_key_by_utf16_path"; libuna_unicode_character_t unicode_character = 0; size_t utf16_string_index = 0; size_t utf16_string_segment_length = 0; uint32_t name_hash = 0; 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( utf16_string == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid UTF-16 string.", function ); return( -1 ); } if( utf16_string_length > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid UTF-16 string length value exceeds maximum.", function ); return( -1 ); } if( key == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid key.", function ); return( -1 ); } if( *key != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: key already set.", function ); return( -1 ); } if( utf16_string_length > 0 ) { /* Ignore a leading separator */ if( utf16_string[ utf16_string_index ] == (uint16_t) LIBREGF_SEPARATOR ) { utf16_string_index++; } } if( libfdata_tree_get_root_node( internal_file->key_tree, &key_tree_node, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve key tree root node.", function ); return( -1 ); } if( libfdata_tree_node_get_node_value( key_tree_node, (intptr_t *) internal_file->file_io_handle, (libfdata_cache_t *) internal_file->key_cache, (intptr_t **) &key_item, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve root key item.", function ); return( -1 ); } if( key_item == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing root key item.", function ); return( -1 ); } if( utf16_string_length == utf16_string_index ) { result = 1; } else while( utf16_string_index < utf16_string_length ) { utf16_string_segment = (uint16_t *) &( utf16_string[ utf16_string_index ] ); utf16_string_segment_length = utf16_string_index; name_hash = 0; while( utf16_string_index < utf16_string_length ) { if( libuna_unicode_character_copy_from_utf16( &unicode_character, utf16_string, utf16_string_length, &utf16_string_index, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_COPY_FAILED, "%s: unable to copy UTF-16 string to Unicode character.", function ); return( -1 ); } if( ( unicode_character == (libuna_unicode_character_t) LIBREGF_SEPARATOR ) || ( unicode_character == 0 ) ) { utf16_string_segment_length += 1; break; } name_hash *= 37; name_hash += (uint32_t) towupper( (wint_t) unicode_character ); } utf16_string_segment_length = utf16_string_index - utf16_string_segment_length; if( utf16_string_segment_length == 0 ) { result = 0; } else { result = libregf_key_tree_get_sub_key_values_by_utf16_name( key_tree_node, internal_file->file_io_handle, internal_file->key_cache, name_hash, utf16_string_segment, utf16_string_segment_length, internal_file->io_handle->ascii_codepage, &key_tree_sub_node, &sub_key_item, error ); } if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve sub key values by name.", function ); return( -1 ); } else if( result == 0 ) { break; } key_tree_node = key_tree_sub_node; } if( result != 0 ) { if( libregf_key_initialize( key, internal_file->io_handle, internal_file->file_io_handle, key_tree_node, internal_file->key_cache, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create key.", function ); return( -1 ); } } return( result ); }
/* Retrieves the sub key values (key tree node and key item) for the specific UTF-8 formatted name * Returns 1 if successful, 0 if no such sub key item or -1 on error */ int libregf_key_tree_get_sub_key_values_by_utf8_name( libfdata_tree_node_t *key_tree_node, libbfio_handle_t *file_io_handle, libfcache_cache_t *key_cache, uint32_t name_hash, const uint8_t *utf8_string, size_t utf8_string_length, int ascii_codepage, libfdata_tree_node_t **key_tree_sub_node, libregf_key_item_t **sub_key_item, libcerror_error_t **error ) { static char *function = "libregf_key_tree_get_sub_key_values_by_utf8_name"; int number_of_sub_keys = 0; int result = 0; int sub_key_index = 0; if( key_tree_sub_node == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid key tree sub node.", function ); return( -1 ); } if( sub_key_item == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid sub key item.", function ); return( -1 ); } if( libfdata_tree_node_get_number_of_sub_nodes( key_tree_node, (intptr_t *) file_io_handle, (libfdata_cache_t *) key_cache, &number_of_sub_keys, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve number of sub keys.", function ); return( -1 ); } for( sub_key_index = 0; sub_key_index < number_of_sub_keys; sub_key_index++ ) { if( libfdata_tree_node_get_sub_node_by_index( key_tree_node, (intptr_t *) file_io_handle, (libfdata_cache_t *) key_cache, sub_key_index, key_tree_sub_node, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve key tree sub node: %d.", function, sub_key_index ); return( -1 ); } if( libfdata_tree_node_get_node_value( *key_tree_sub_node, (intptr_t *) file_io_handle, (libfdata_cache_t *) key_cache, (intptr_t **) sub_key_item, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve sub key item.", function ); return( -1 ); } result = libregf_key_item_compare_name_with_utf8_string( *sub_key_item, name_hash, utf8_string, utf8_string_length, ascii_codepage, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GENERIC, "%s: unable to compare sub key name with UTF-8 string.", function ); return( -1 ); } else if( result != 0 ) { break; } } if( sub_key_index >= number_of_sub_keys ) { return( 0 ); } return( 1 ); }
/* Retrieves the local descriptor value for the specific identifier * Returns 1 if successful, 0 if no value was found or -1 on error */ int libpff_local_descriptors_tree_get_value_by_identifier( libfdata_tree_t *local_descriptors_tree, libbfio_handle_t *file_io_handle, libfcache_cache_t *cache, uint64_t identifier, libpff_local_descriptor_value_t **local_descriptor_value, libcerror_error_t **error ) { libfdata_tree_node_t *leaf_local_descriptors_tree_node = NULL; static char *function = "libpff_local_descriptors_tree_get_value_by_identifier"; int result = 0; result = libpff_local_descriptors_tree_get_leaf_node_by_identifier( local_descriptors_tree, file_io_handle, cache, identifier, &leaf_local_descriptors_tree_node, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve leaf node by identifier in root node.", function ); return( -1 ); } else if( result != 0 ) { if( leaf_local_descriptors_tree_node == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing leaf local descriptors tree node.", function ); return( -1 ); } if( libfdata_tree_node_get_node_value( leaf_local_descriptors_tree_node, (intptr_t *) file_io_handle, cache, (intptr_t **) local_descriptor_value, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve leaf local descriptors tree node value.", function ); return( -1 ); } } return( result ); }
/* Retrieves the leaf node for the specific identifier * Returns 1 if successful, 0 if no leaf node was found or -1 on error */ int libpff_local_descriptors_tree_node_get_leaf_node_by_identifier( libfdata_tree_node_t *local_descriptors_tree_node, libbfio_handle_t *file_io_handle, libfcache_cache_t *cache, uint64_t identifier, libfdata_tree_node_t **leaf_local_descriptors_tree_node, libcerror_error_t **error ) { libfdata_tree_node_t *local_descriptors_tree_sub_node = NULL; libpff_local_descriptor_value_t *local_descriptors_tree_sub_node_value = NULL; static char *function = "libpff_local_descriptors_tree_node_get_leaf_node_by_identifier"; int16_t compare = 0; int number_of_sub_nodes = 0; int result = 0; int sub_node_index = 0; if( local_descriptors_tree_node == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid local descriptors tree node.", function ); return( -1 ); } if( libfdata_tree_node_get_number_of_sub_nodes( local_descriptors_tree_node, (intptr_t *) file_io_handle, cache, &number_of_sub_nodes, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve number of sub nodes from local descriptors tree node.", function ); return( -1 ); } for( sub_node_index = 0; sub_node_index < number_of_sub_nodes; sub_node_index++ ) { if( libfdata_tree_node_get_sub_node_by_index( local_descriptors_tree_node, (intptr_t *) file_io_handle, cache, sub_node_index, &local_descriptors_tree_sub_node, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve sub node: %d from local descriptors tree node.", function, sub_node_index ); return( -1 ); } if( libfdata_tree_node_get_node_value( local_descriptors_tree_sub_node, (intptr_t *) file_io_handle, cache, (intptr_t **) &local_descriptors_tree_sub_node_value, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve local descriptors tree sub node value: %d.", function, sub_node_index ); return( -1 ); } if( local_descriptors_tree_sub_node_value == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing local descriptors tree sub node value: %d.", function, sub_node_index ); return( -1 ); } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( "%s: local descriptors tree sub node value: %d identifier\t: 0x%08" PRIx64 " (%" PRIu64 ").\n", function, sub_node_index, local_descriptors_tree_sub_node_value->identifier, local_descriptors_tree_sub_node_value->identifier ); } #endif if( identifier > local_descriptors_tree_sub_node_value->identifier ) { compare = 1; } else if( identifier < local_descriptors_tree_sub_node_value->identifier ) { compare = -1; } else { compare = 0; } result = libfdata_tree_node_is_leaf( local_descriptors_tree_sub_node, (intptr_t *) file_io_handle, cache, 0, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if local descriptors tree sub node: %d is a leaf node.", function, sub_node_index ); return( -1 ); } else if( result != 0 ) { result = libfdata_tree_node_is_deleted( local_descriptors_tree_sub_node, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to determine if local descriptors tree sub node: %d is a deleted node.", function, sub_node_index ); return( -1 ); } else if( result == 0 ) { if( compare == 0 ) { if( leaf_local_descriptors_tree_node == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid leaf local descriptors tree node.", function ); return( -1 ); } if( *leaf_local_descriptors_tree_node != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: leaf local descriptors tree node value already set.", function ); return( -1 ); } *leaf_local_descriptors_tree_node = local_descriptors_tree_sub_node; result = 1; break; } } result = 0; } else { /* A branch node contains the identifier of its first sub node */ if( ( compare == 0 ) || ( ( compare > 0 ) && ( sub_node_index == ( number_of_sub_nodes - 1 ) ) ) ) { result = libpff_local_descriptors_tree_node_get_leaf_node_by_identifier( local_descriptors_tree_sub_node, file_io_handle, cache, identifier, leaf_local_descriptors_tree_node, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve leaf local descriptors tree node by identifier in sub node: %d.", function, sub_node_index ); return( -1 ); } break; } else if( ( compare < 0 ) && ( sub_node_index >= 1 ) ) { if( libfdata_tree_node_get_sub_node_by_index( local_descriptors_tree_node, (intptr_t *) file_io_handle, cache, sub_node_index - 1, &local_descriptors_tree_sub_node, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve sub node: %d from local descriptors tree node.", function, sub_node_index - 1 ); return( -1 ); } result = libpff_local_descriptors_tree_node_get_leaf_node_by_identifier( local_descriptors_tree_sub_node, file_io_handle, cache, identifier, leaf_local_descriptors_tree_node, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve leaf local descriptors tree node by identifier in sub node: %d.", function, sub_node_index - 1 ); return( -1 ); } break; } } } return( result ); }