+}
+
+/*
+ * Returns the lookup table entry for stream @stream_idx of the inode, where
+ * stream_idx = 0 means the default un-named file stream, and stream_idx >= 1
+ * corresponds to an alternate data stream.
+ *
+ * This works for both resolved and un-resolved inodes.
+ */
+struct wim_lookup_table_entry *
+inode_stream_lte(const struct wim_inode *inode, unsigned stream_idx,
+ const struct wim_lookup_table *table)
+{
+ if (inode->i_resolved)
+ return inode_stream_lte_resolved(inode, stream_idx);
+ else
+ return inode_stream_lte_unresolved(inode, stream_idx, table);
+}
+
+struct wim_lookup_table_entry *
+inode_unnamed_lte_resolved(const struct wim_inode *inode)
+{
+ wimlib_assert(inode->i_resolved);
+ for (unsigned i = 0; i <= inode->i_num_ads; i++) {
+ if (inode_stream_name_nbytes(inode, i) == 0 &&
+ !is_zero_hash(inode_stream_hash_resolved(inode, i)))
+ {
+ return inode_stream_lte_resolved(inode, i);
+ }
+ }
+ return NULL;
+}
+
+struct wim_lookup_table_entry *
+inode_unnamed_lte_unresolved(const struct wim_inode *inode,
+ const struct wim_lookup_table *table)
+{
+ wimlib_assert(!inode->i_resolved);
+ for (unsigned i = 0; i <= inode->i_num_ads; i++) {
+ if (inode_stream_name_nbytes(inode, i) == 0 &&
+ !is_zero_hash(inode_stream_hash_unresolved(inode, i)))
+ {
+ return inode_stream_lte_unresolved(inode, i, table);
+ }
+ }
+ return NULL;
+}
+
+/* Return the lookup table entry for the unnamed data stream of an inode, or
+ * NULL if there is none.
+ *
+ * You'd think this would be easier than it actually is, since the unnamed data
+ * stream should be the one referenced from the inode itself. Alas, if there
+ * are named data streams, Microsoft's "imagex.exe" program will put the unnamed
+ * data stream in one of the alternate data streams instead of inside the WIM
+ * dentry itself. So we need to check the alternate data streams too.
+ *
+ * Also, note that a dentry may appear to have more than one unnamed stream, but
+ * if the SHA1 message digest is all 0's then the corresponding stream does not
+ * really "count" (this is the case for the inode's own file stream when the
+ * file stream that should be there is actually in one of the alternate stream
+ * entries.). This is despite the fact that we may need to extract such a
+ * missing entry as an empty file or empty named data stream.
+ */
+struct wim_lookup_table_entry *
+inode_unnamed_lte(const struct wim_inode *inode,
+ const struct wim_lookup_table *table)
+{
+ if (inode->i_resolved)
+ return inode_unnamed_lte_resolved(inode);
+ else
+ return inode_unnamed_lte_unresolved(inode, table);
+}
+
+static int
+lte_add_stream_size(struct wim_lookup_table_entry *lte, void *total_bytes_p)
+{
+ *(u64*)total_bytes_p += lte->resource_entry.size;