/* 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 ); }
/* Create the directory tree from the directory entry list * Returns 1 if succesful, 0 if no directory entries or -1 on error */ int libolecf_directory_tree_create( libcdata_tree_node_t **directory_tree_root_node, uint32_t *short_sector_stream_start_sector_identifier, libolecf_directory_entry_t **document_summary_information_directory_entry, libolecf_directory_entry_t **summary_information_directory_entry, libcdata_list_t *directory_entry_list, uint8_t byte_order, libcerror_error_t **error ) { libcdata_list_element_t *list_element = NULL; libolecf_directory_entry_t *directory_entry = NULL; static char *function = "libolecf_directory_tree_create"; int element_index = 0; int number_of_elements = 0; if( directory_tree_root_node == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid directory tree root node.", function ); return( -1 ); } if( *directory_tree_root_node != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: directory tree root node already set.", function ); return( -1 ); } if( short_sector_stream_start_sector_identifier == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid short sector stream start sector identifier.", function ); return( -1 ); } if( libcdata_list_get_first_element( directory_entry_list, &list_element, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve first element of directory entry list.", function ); goto on_error; } if( libcdata_list_get_number_of_elements( directory_entry_list, &number_of_elements, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve number of elements in directory entry list.", function ); goto on_error; } if( number_of_elements == 0 ) { return( 0 ); } for( element_index = 0; element_index < number_of_elements; element_index++ ) { if( libcdata_list_element_get_value( list_element, (intptr_t **) &directory_entry, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value from element: %d.", function, element_index ); goto on_error; } if( directory_entry == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing directory entry: %d.", function, element_index ); goto on_error; } if( directory_entry->type == LIBOLECF_ITEM_TYPE_ROOT_STORAGE ) { break; } if( libcdata_list_element_get_next_element( list_element, &list_element, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve next element of element: %d.", function, element_index ); goto on_error; } } if( list_element == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: unable to find root storage directory entry.", function ); goto on_error; } #if defined( HAVE_VERBOSE_OUTPUT ) || defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { if( element_index != 0 ) { libcnotify_printf( "%s: root storage is not first directory entry.\n", function ); } if( directory_entry->previous_directory_identifier != LIBOLECF_SECTOR_IDENTIFIER_UNUSED ) { libcnotify_printf( "%s: previous directory identifier in root storage is not unused.\n", function ); } if( directory_entry->next_directory_identifier != LIBOLECF_SECTOR_IDENTIFIER_UNUSED ) { libcnotify_printf( "%s: next directory identifier in root storage is not unused.\n", function ); } } #endif if( directory_entry->sub_directory_identifier == LIBOLECF_SECTOR_IDENTIFIER_UNUSED ) { return( 0 ); } if( libcdata_tree_node_initialize( directory_tree_root_node, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create directory root node.", function ); goto on_error; } if( libcdata_tree_node_set_value( *directory_tree_root_node, (intptr_t *) directory_entry, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set directory root node value.", function ); goto on_error; } *short_sector_stream_start_sector_identifier = directory_entry->sector_identifier; if( libolecf_directory_tree_create_process_entry( *directory_tree_root_node, directory_entry, document_summary_information_directory_entry, summary_information_directory_entry, directory_entry_list, directory_entry, byte_order, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to process sub directory entry.", function ); goto on_error; } return( 1 ); on_error: if( *directory_tree_root_node != NULL ) { /* The directory entry is managed by the list */ libcdata_tree_node_free( directory_tree_root_node, NULL, NULL ); } return( -1 ); }
/* Creates an item tree from the descriptors index * Returns 1 if successful, 0 if the item tree could not be created or -1 on error */ int libpff_item_tree_create( libcdata_tree_node_t **item_tree_root_node, libbfio_handle_t *file_io_handle, libpff_descriptors_index_t *descriptors_index, libcdata_list_t *orphan_node_list, libcdata_tree_node_t **root_folder_item_tree_node, libcerror_error_t **error ) { libfdata_tree_node_t *descriptor_index_tree_root_node = NULL; libpff_item_descriptor_t *item_descriptor = NULL; static char *function = "libpff_item_tree_create"; int result = 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( *item_tree_root_node != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: item tree root node already set.", function ); return( -1 ); } if( libfdata_tree_get_root_node( descriptors_index->index_tree, &descriptor_index_tree_root_node, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to retrieve descriptor index tree root node.", function ); goto on_error; } if( libpff_item_descriptor_initialize( &item_descriptor, 0, 0, 0, 0, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create item descriptor.", function ); goto on_error; } if( libcdata_tree_node_initialize( item_tree_root_node, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create item tree root node.", function ); goto on_error; } if( libcdata_tree_node_set_value( *item_tree_root_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 ); goto on_error; } /* The item descriptor is now managed by the item tree root node */ item_descriptor = NULL; result = libpff_item_tree_create_node( *item_tree_root_node, file_io_handle, descriptors_index->index_tree, descriptor_index_tree_root_node, descriptors_index->index_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 item tree.", function ); goto on_error; } return( result ); on_error: if( *item_tree_root_node != NULL ) { libcdata_tree_node_free( item_tree_root_node, (int (*)(intptr_t **, libcerror_error_t **)) &libpff_item_descriptor_free, NULL ); } if( item_descriptor != NULL ) { libpff_item_descriptor_free( &item_descriptor, NULL ); } return( -1 ); }
/* Process the directory entry and adds it to the directory tree node * Returns 1 if succesful or -1 on error */ int libolecf_directory_tree_create_process_entry( libcdata_tree_node_t *directory_tree_node, const libolecf_directory_entry_t *root_directory_entry, libolecf_directory_entry_t **document_summary_information_directory_entry, libolecf_directory_entry_t **summary_information_directory_entry, libcdata_list_t *directory_entry_list, libolecf_directory_entry_t *directory_entry, uint8_t byte_order, libcerror_error_t **error ) { libcdata_tree_node_t *parent_node = NULL; libolecf_directory_entry_t *directory_entry_value = NULL; libcdata_tree_node_t *tree_node = NULL; static char *function = "libolecf_directory_tree_create_process_entry"; int result = 0; if( directory_tree_node == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid directory tree node.", function ); return( -1 ); } if( root_directory_entry == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid root directory entry.", function ); return( -1 ); } if( document_summary_information_directory_entry == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid document summary information directory entry.", function ); return( -1 ); } if( summary_information_directory_entry == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid summary information directory entry.", function ); return( -1 ); } if( directory_entry->name_size == 28 ) { result = libuna_utf8_string_compare_with_utf16_stream( (uint8_t *) "\005DocumentSummaryInformation", 28, directory_entry->name, directory_entry->name_size, byte_order, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GENERIC, "%s: unable to compare directory entry name.", function ); goto on_error; } else if( result == 1 ) { *document_summary_information_directory_entry = directory_entry; } } else if( directory_entry->name_size == 20 ) { result = libuna_utf8_string_compare_with_utf16_stream( (uint8_t *) "\005SummaryInformation", 20, directory_entry->name, directory_entry->name_size, byte_order, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GENERIC, "%s: unable to compare directory entry name.", function ); goto on_error; } else if( result == 1 ) { *summary_information_directory_entry = directory_entry; } } /* Process sub directory identifier */ if( ( directory_entry->sub_directory_identifier != LIBOLECF_SECTOR_IDENTIFIER_UNUSED ) && ( directory_entry->sub_directory_identifier != 0 ) && ( root_directory_entry->directory_identifier == 0 ) ) { result = libolecf_directory_list_get_element_by_identifier( directory_entry_list, directory_entry->sub_directory_identifier, &directory_entry_value, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve sub directory entry list element: %" PRIu32 ".", function, directory_entry->sub_directory_identifier ); goto on_error; } else if( result != 0 ) { if( directory_entry_value == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing sub directory entry: %" PRIu32 ".", function, directory_entry->sub_directory_identifier ); goto on_error; } if( directory_entry_value->set_in_tree != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: directory entry tree node already set.", function ); goto on_error; } if( libcdata_tree_node_initialize( &tree_node, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create directory tree node.", function ); goto on_error; } if( libcdata_tree_node_set_value( tree_node, (intptr_t *) directory_entry_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set directory tree node value.", function ); goto on_error; } if( libcdata_tree_node_insert_node( directory_tree_node, tree_node, (int (*)(intptr_t *, intptr_t *, libcerror_error_t **)) &libolecf_directory_entry_compare, LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to insert sub directory tree node.", function ); goto on_error; } directory_entry_value->set_in_tree = 1; if( libolecf_directory_tree_create_process_entry( tree_node, root_directory_entry, document_summary_information_directory_entry, summary_information_directory_entry, directory_entry_list, directory_entry_value, byte_order, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to process sub directory entry.", function ); tree_node = NULL; goto on_error; } tree_node = NULL; } } /* Process previous directory identifier */ if( directory_entry->previous_directory_identifier != LIBOLECF_SECTOR_IDENTIFIER_UNUSED ) { result = libolecf_directory_list_get_element_by_identifier( directory_entry_list, (int) directory_entry->previous_directory_identifier, &directory_entry_value, error ); if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve previous directory entry: 0x%08" PRIx32 ".", function, directory_entry->previous_directory_identifier ); goto on_error; } else if( result != 0 ) { if( directory_entry_value == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing previous directory entry: %" PRIu32 ".", function, directory_entry->previous_directory_identifier ); goto on_error; } if( directory_entry_value->set_in_tree != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: directory entry tree node already set.", function ); goto on_error; } if( libcdata_tree_node_initialize( &tree_node, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create directory tree node.", function ); goto on_error; } if( libcdata_tree_node_set_value( tree_node, (intptr_t *) directory_entry_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set directory tree node value.", function ); goto on_error; } if( libcdata_tree_node_get_parent_node( directory_tree_node, &parent_node, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve parent node.", function ); goto on_error; } if( libcdata_tree_node_insert_node( parent_node, tree_node, (int (*)(intptr_t *, intptr_t *, libcerror_error_t **)) &libolecf_directory_entry_compare, LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to insert previous directory tree node.", function ); goto on_error; } directory_entry_value->set_in_tree = 1; if( libolecf_directory_tree_create_process_entry( tree_node, root_directory_entry, document_summary_information_directory_entry, summary_information_directory_entry, directory_entry_list, directory_entry_value, byte_order, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to process previous directory entry.", function ); tree_node = NULL; goto on_error; } tree_node = NULL; } } /* Process next directory identifier */ if( directory_entry->next_directory_identifier != LIBOLECF_SECTOR_IDENTIFIER_UNUSED ) { result = libolecf_directory_list_get_element_by_identifier( directory_entry_list, (int) directory_entry->next_directory_identifier, &directory_entry_value, error ); if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve next directory entry: 0x%08" PRIx32 ".", function, directory_entry->next_directory_identifier ); goto on_error; } else if( result != 0 ) { if( directory_entry_value == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing next directory entry: %" PRIu32 ".", function, directory_entry->sub_directory_identifier ); goto on_error; } if( directory_entry_value->set_in_tree != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, "%s: directory entry tree node already set.", function ); goto on_error; } if( libcdata_tree_node_initialize( &tree_node, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, "%s: unable to create directory tree node.", function ); goto on_error; } if( libcdata_tree_node_set_value( tree_node, (intptr_t *) directory_entry_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set directory tree node value.", function ); goto on_error; } if( libcdata_tree_node_get_parent_node( directory_tree_node, &parent_node, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve parent node.", function ); goto on_error; } if( libcdata_tree_node_insert_node( parent_node, tree_node, (int (*)(intptr_t *, intptr_t *, libcerror_error_t **)) &libolecf_directory_entry_compare, LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, "%s: unable to insert next directory tree node.", function ); goto on_error; } directory_entry_value->set_in_tree = 1; if( libolecf_directory_tree_create_process_entry( tree_node, root_directory_entry, document_summary_information_directory_entry, summary_information_directory_entry, directory_entry_list, directory_entry_value, byte_order, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to process next directory entry.", function ); tree_node = NULL; goto on_error; } tree_node = NULL; } } return( 1 ); on_error: if( tree_node != NULL ) { libcdata_tree_node_free( &tree_node, NULL, NULL ); } return( -1 ); }