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