win32_apply.c: test for EFS data before reparse data
authorEric Biggers <ebiggers3@gmail.com>
Wed, 28 Jan 2015 04:31:41 +0000 (22:31 -0600)
committerEric Biggers <ebiggers3@gmail.com>
Thu, 29 Jan 2015 02:30:38 +0000 (20:30 -0600)
src/win32_apply.c

index 54c247c..fb62984 100644 (file)
@@ -1737,22 +1737,6 @@ begin_extract_stream_instance(const struct wim_lookup_table_entry *stream,
                build_extraction_path(dentry, ctx);
        }
 
-       /* Reparse point?  */
-       if (unlikely(inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT)
-           && (stream_name_nchars == 0))
-       {
-               if (!ctx->common.supported_features.reparse_points)
-                       return 0;
-
-               /* We can't write the reparse stream directly; we must set it
-                * with FSCTL_SET_REPARSE_POINT, which requires that all the
-                * data be available.  So, stage the data in a buffer.  */
-
-               if (!prepare_data_buffer(ctx, stream->size))
-                       return WIMLIB_ERR_NOMEM;
-               list_add_tail(&dentry->tmp_list, &ctx->reparse_dentries);
-               return 0;
-       }
 
        /* Encrypted file?  */
        if (unlikely(inode->i_attributes & FILE_ATTRIBUTE_ENCRYPTED)
@@ -1778,6 +1762,28 @@ begin_extract_stream_instance(const struct wim_lookup_table_entry *stream,
                return 0;
        }
 
+       /* Reparse point?
+        *
+        * Note: FILE_ATTRIBUTE_REPARSE_POINT is tested *after*
+        * FILE_ATTRIBUTE_ENCRYPTED since the WIM format does not store both EFS
+        * data and reparse data for the same file, and the EFS data takes
+        * precedence.  */
+       if (unlikely(inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT)
+           && (stream_name_nchars == 0))
+       {
+               if (!ctx->common.supported_features.reparse_points)
+                       return 0;
+
+               /* We can't write the reparse stream directly; we must set it
+                * with FSCTL_SET_REPARSE_POINT, which requires that all the
+                * data be available.  So, stage the data in a buffer.  */
+
+               if (!prepare_data_buffer(ctx, stream->size))
+                       return WIMLIB_ERR_NOMEM;
+               list_add_tail(&dentry->tmp_list, &ctx->reparse_dentries);
+               return 0;
+       }
+
        if (ctx->num_open_handles == MAX_OPEN_STREAMS) {
                /* XXX: Fix this.  But because of the checks in
                 * extract_stream_list(), this can now only happen on a