+/*
+ * Set the type of each stream for an unencrypted file.
+ *
+ * There will be an unnamed data stream, a reparse point stream, or both an
+ * unnamed data stream and a reparse point stream. In addition, there may be
+ * named data streams.
+ *
+ * NOTE: if the file has a reparse point stream or at least one named data
+ * stream, then WIMGAPI puts *all* streams in the extra stream entries and
+ * leaves the default stream hash zeroed. wimlib now does the same. However,
+ * for input we still support the default hash field being used, since wimlib
+ * used to use it and MS software is somewhat accepting of it as well.
+ */
+static void
+assign_stream_types_unencrypted(struct wim_inode *inode)
+{
+ bool found_reparse_point_stream = false;
+ bool found_unnamed_data_stream = false;
+ struct wim_inode_stream *unnamed_stream_with_zero_hash = NULL;
+
+ for (unsigned i = 0; i < inode->i_num_streams; i++) {
+ struct wim_inode_stream *strm = &inode->i_streams[i];
+
+ if (stream_is_named(strm)) {
+ /* Named data stream */
+ strm->stream_type = STREAM_TYPE_DATA;
+ } else if (i != 0 || !is_zero_hash(strm->_stream_hash)) {
+ /* Unnamed stream in the extra stream entries, OR the
+ * default stream in the dentry provided that it has a
+ * nonzero hash. */
+ if ((inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
+ !found_reparse_point_stream) {
+ found_reparse_point_stream = true;
+ strm->stream_type = STREAM_TYPE_REPARSE_POINT;
+ } else if (!found_unnamed_data_stream) {
+ found_unnamed_data_stream = true;
+ strm->stream_type = STREAM_TYPE_DATA;
+ }
+ } else if (!unnamed_stream_with_zero_hash) {
+ unnamed_stream_with_zero_hash = strm;
+ }
+ }
+
+ if (unnamed_stream_with_zero_hash) {
+ int type = STREAM_TYPE_UNKNOWN;
+ if ((inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
+ !found_reparse_point_stream) {
+ type = STREAM_TYPE_REPARSE_POINT;
+ } else if (!found_unnamed_data_stream) {
+ type = STREAM_TYPE_DATA;
+ }
+ unnamed_stream_with_zero_hash->stream_type = type;
+ }
+}
+
+/*
+ * Read and interpret the collection of streams for the specified inode.
+ */
+static int
+setup_inode_streams(const u8 *p, const u8 *end, struct wim_inode *inode,
+ unsigned num_extra_streams, const u8 *default_hash,
+ u64 *offset_p)
+{
+ const u8 *orig_p = p;
+
+ inode->i_num_streams = 1 + num_extra_streams;