+ disk_dentry->length = cpu_to_le64(p - orig_p);
+
+ /* Streams */
+
+ if (unlikely(inode->i_attributes & FILE_ATTRIBUTE_ENCRYPTED)) {
+ const struct wim_inode_stream *efs_strm;
+ const u8 *efs_hash;
+
+ efs_strm = inode_get_unnamed_stream(inode, STREAM_TYPE_EFSRPC_RAW_DATA);
+ efs_hash = efs_strm ? stream_hash(efs_strm) : zero_hash;
+ copy_hash(disk_dentry->default_hash, efs_hash);
+ disk_dentry->num_extra_streams = cpu_to_le16(0);
+ } else {
+ /*
+ * Extra stream entries:
+ *
+ * - Use one extra stream entry for each named data stream
+ * - Use one extra stream entry for the unnamed data stream when there is either:
+ * - a reparse point stream
+ * - at least one named data stream (for Windows PE bug workaround)
+ * - Use one extra stream entry for the reparse point stream if there is one
+ */
+ bool have_named_data_stream = false;
+ bool have_reparse_point_stream = false;
+ const u8 *unnamed_data_stream_hash = zero_hash;
+ const u8 *reparse_point_hash;
+ for (unsigned i = 0; i < inode->i_num_streams; i++) {
+ const struct wim_inode_stream *strm = &inode->i_streams[i];
+ if (strm->stream_type == STREAM_TYPE_DATA) {
+ if (stream_is_named(strm))
+ have_named_data_stream = true;
+ else
+ unnamed_data_stream_hash = stream_hash(strm);
+ } else if (strm->stream_type == STREAM_TYPE_REPARSE_POINT) {
+ have_reparse_point_stream = true;
+ reparse_point_hash = stream_hash(strm);
+ }
+ }
+
+ if (unlikely(have_reparse_point_stream || have_named_data_stream)) {
+
+ unsigned num_extra_streams = 0;
+
+ copy_hash(disk_dentry->default_hash, zero_hash);
+
+ if (have_reparse_point_stream) {
+ p = write_extra_stream_entry(p, NO_STREAM_NAME,
+ reparse_point_hash);
+ num_extra_streams++;
+ }
+
+ p = write_extra_stream_entry(p, NO_STREAM_NAME,
+ unnamed_data_stream_hash);
+ num_extra_streams++;
+
+ for (unsigned i = 0; i < inode->i_num_streams; i++) {
+ const struct wim_inode_stream *strm = &inode->i_streams[i];
+ if (stream_is_named_data_stream(strm)) {
+ p = write_extra_stream_entry(p, strm->stream_name,
+ stream_hash(strm));
+ num_extra_streams++;
+ }
+ }
+ wimlib_assert(num_extra_streams <= 0xFFFF);
+
+ disk_dentry->num_extra_streams = cpu_to_le16(num_extra_streams);
+ } else {
+ copy_hash(disk_dentry->default_hash, unnamed_data_stream_hash);
+ disk_dentry->num_extra_streams = cpu_to_le16(0);
+ }