]> wimlib.net Git - wimlib/blobdiff - src/win32_apply.c
win32_apply.c: detect case-sensitive filename support
[wimlib] / src / win32_apply.c
index d9bf63c2fd305b93cf932b1bbff9d0dc996f8c83..a4f817513ea12d7c9a5b54b25ba0528c017861fa 100644 (file)
@@ -308,8 +308,28 @@ win32_get_supported_features(const wchar_t *target,
 
        supported_features->timestamps = 1;
 
-       /* Note: Windows does not support case sensitive filenames!  At least
-        * not without changing the registry and rebooting...  */
+       if (vol_flags & FILE_CASE_SENSITIVE_SEARCH) {
+               /*
+                * The filesystem supports case-sensitive filenames.  But does
+                * the operating system as well?  This normally requires the
+                * registry setting ObCaseInsensitive=0.  We can test it
+                * indirectly by attempting to open the "\SystemRoot" symbolic
+                * link using a name with the wrong case.  If we get
+                * STATUS_OBJECT_NAME_NOT_FOUND instead of STATUS_ACCESS_DENIED,
+                * then case-sensitive names must be enabled.
+                */
+               UNICODE_STRING path;
+               OBJECT_ATTRIBUTES attr;
+               HANDLE h;
+               NTSTATUS status;
+
+               RtlInitUnicodeString(&path, L"\\systemroot");
+               InitializeObjectAttributes(&attr, &path, 0, NULL, NULL);
+
+               status = NtOpenSymbolicLinkObject(&h, 0, &attr);
+               if (status == STATUS_OBJECT_NAME_NOT_FOUND)
+                       supported_features->case_sensitive_filenames = 1;
+       }
 
        return 0;
 }
@@ -1631,28 +1651,16 @@ create_directory(const struct wim_dentry *dentry, struct win32_apply_ctx *ctx)
        int ret;
 
        /* DELETE is needed for set_short_name(); GENERIC_READ and GENERIC_WRITE
-        * are needed for adjust_compression_attribute(); WRITE_DAC is needed to
-        * remove the directory's DACL if the directory already existed  */
-       perms = GENERIC_READ | GENERIC_WRITE | WRITE_DAC;
+        * are needed for adjust_compression_attribute().  */
+       perms = GENERIC_READ | GENERIC_WRITE;
        if (!dentry_is_root(dentry))
                perms |= DELETE;
 
        /* FILE_ATTRIBUTE_SYSTEM is needed to ensure that
         * FILE_ATTRIBUTE_ENCRYPTED doesn't get set before we want it to be.  */
-retry:
        status = create_file(&h, perms, NULL, FILE_ATTRIBUTE_SYSTEM,
                             FILE_OPEN_IF, FILE_DIRECTORY_FILE, dentry, ctx);
        if (unlikely(!NT_SUCCESS(status))) {
-               if (status == STATUS_ACCESS_DENIED) {
-                       if (perms & WRITE_DAC) {
-                               perms &= ~WRITE_DAC;
-                               goto retry;
-                       }
-                       if (perms & DELETE) {
-                               perms &= ~DELETE;
-                               goto retry;
-                       }
-               }
                const wchar_t *path = current_path(ctx);
                winnt_error(status, L"Can't create directory \"%ls\"", path);