win32_apply.c: try to clear attributes on existing directories
authorEric Biggers <ebiggers3@gmail.com>
Sun, 15 Mar 2015 01:25:53 +0000 (20:25 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Sun, 15 Mar 2015 01:41:29 +0000 (20:41 -0500)
include/wimlib/win32_common.h
src/win32_apply.c

index 3242851..9b87355 100644 (file)
@@ -25,6 +25,10 @@ extern NTSTATUS (WINAPI *func_NtCreateFile)(PHANDLE FileHandle,
                                            PVOID EaBuffer,
                                            ULONG EaLength);
 
+#ifndef FILE_OPENED
+#  define FILE_OPENED 0x00000001
+#endif
+
 extern NTSTATUS (WINAPI *func_NtOpenFile) (PHANDLE FileHandle,
                                           ACCESS_MASK DesiredAccess,
                                           POBJECT_ATTRIBUTES ObjectAttributes,
index b66717e..26814f6 100644 (file)
@@ -1370,6 +1370,20 @@ create_directory(const struct wim_dentry *dentry, struct win32_apply_ctx *ctx)
                return WIMLIB_ERR_MKDIR;
        }
 
+       if (ctx->iosb.Information == FILE_OPENED) {
+               /* If we opened an existing directory, try to clear its file
+                * attributes.  As far as I know, this only actually makes a
+                * difference in the case where a FILE_ATTRIBUTE_READONLY
+                * directory has a named data stream which needs to be
+                * extracted.  You cannot create a named data stream of such a
+                * directory, even though this contradicts Microsoft's
+                * documentation for FILE_ATTRIBUTE_READONLY which states it is
+                * not honored for directories!  */
+               FILE_BASIC_INFORMATION basic_info = { .FileAttributes = FILE_ATTRIBUTE_NORMAL };
+               (*func_NtSetInformationFile)(h, &ctx->iosb, &basic_info,
+                                            sizeof(basic_info), FileBasicInformation);
+       }
+
        if (!dentry_is_root(dentry)) {
                ret = set_short_name(h, dentry, ctx);
                if (ret)