+ for_lookup_table_entry(w->lookup_table,
+ do_print_lookup_table_entry,
+ NULL);
+}
+
+/*
+ * Looks up an entry in the lookup table.
+ */
+struct lookup_table_entry *
+__lookup_resource(const struct lookup_table *table, const u8 hash[])
+{
+ size_t i;
+ struct lookup_table_entry *lte;
+ struct hlist_node *pos;
+
+ wimlib_assert(table != NULL);
+ wimlib_assert(hash != NULL);
+
+ i = *(size_t*)hash % table->capacity;
+ hlist_for_each_entry(lte, pos, &table->array[i], hash_list)
+ if (hashes_equal(hash, lte->hash))
+ return lte;
+ return NULL;
+}
+
+#ifdef WITH_FUSE
+/*
+ * Finds the dentry, lookup table entry, and stream index for a WIM file stream,
+ * given a path name.
+ *
+ * This is only for pre-resolved inodes.
+ */
+int lookup_resource(WIMStruct *w, const char *path,
+ int lookup_flags,
+ struct dentry **dentry_ret,
+ struct lookup_table_entry **lte_ret,
+ u16 *stream_idx_ret)
+{
+ struct dentry *dentry;
+ struct lookup_table_entry *lte;
+ u16 stream_idx;
+ const char *stream_name = NULL;
+ struct inode *inode;
+ char *p = NULL;
+
+ if (lookup_flags & LOOKUP_FLAG_ADS_OK) {
+ stream_name = path_stream_name(path);
+ if (stream_name) {
+ p = (char*)stream_name - 1;
+ *p = '\0';
+ }
+ }
+
+ dentry = get_dentry(w, path);
+ if (p)
+ *p = ':';
+ if (!dentry)
+ return -ENOENT;
+
+ inode = dentry->d_inode;
+
+ wimlib_assert(inode->resolved);
+
+ if (!(lookup_flags & LOOKUP_FLAG_DIRECTORY_OK)
+ && inode_is_directory(inode))
+ return -EISDIR;
+
+ if (stream_name) {
+ struct ads_entry *ads_entry;
+ u16 ads_idx;
+ ads_entry = inode_get_ads_entry(inode, stream_name,
+ &ads_idx);
+ if (ads_entry) {
+ stream_idx = ads_idx + 1;
+ lte = ads_entry->lte;
+ goto out;
+ } else {
+ return -ENOENT;
+ }
+ } else {
+ lte = inode->lte;
+ stream_idx = 0;
+ }
+out:
+ if (dentry_ret)
+ *dentry_ret = dentry;
+ if (lte_ret)
+ *lte_ret = lte;
+ if (stream_idx_ret)
+ *stream_idx_ret = stream_idx;
+ return 0;
+}
+#endif
+
+static void inode_resolve_ltes(struct inode *inode, struct lookup_table *table)
+{
+ struct lookup_table_entry *lte;
+
+ wimlib_assert(!inode->resolved);
+
+ /* Resolve the default file stream */
+ lte = __lookup_resource(table, inode->hash);
+ inode->lte = lte;
+ inode->resolved = true;
+
+ /* Resolve the alternate data streams */
+ for (u16 i = 0; i < inode->num_ads; i++) {
+ struct ads_entry *cur_entry = &inode->ads_entries[i];
+ lte = __lookup_resource(table, cur_entry->hash);
+ cur_entry->lte = lte;
+ }
+}
+
+static void inode_unresolve_ltes(struct inode *inode)
+{
+ wimlib_assert(inode->resolved);
+ if (inode->lte)
+ copy_hash(inode->hash, inode->lte->hash);
+ else
+ zero_out_hash(inode->hash);
+
+ for (u16 i = 0; i < inode->num_ads; i++) {
+ if (inode->ads_entries[i].lte)
+ copy_hash(inode->ads_entries[i].hash,
+ inode->ads_entries[i].lte->hash);
+ else
+ zero_out_hash(inode->ads_entries[i].hash);
+ }
+ inode->resolved = false;