win32_apply.c: detect case-sensitive filename support
authorEric Biggers <ebiggers3@gmail.com>
Tue, 16 Aug 2016 06:55:50 +0000 (23:55 -0700)
committerEric Biggers <ebiggers3@gmail.com>
Tue, 16 Aug 2016 06:55:50 +0000 (23:55 -0700)
NEWS
doc/man1/wimlib-imagex-apply.1
doc/man1/wimlib-imagex-capture.1
include/wimlib/win32_common.h
src/win32_apply.c

diff --git a/NEWS b/NEWS
index 2d21c49..88522aa 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -26,6 +26,10 @@ Version 1.10.0-BETA:
        been removed.  Users are advised to upgrade to a later version of
        libntfs-3g.
 
+       On Windows, wimlib now supports case-sensitive filename extraction when
+       supported by the underlying operating system and filesystem (operating
+       system support requires a registry setting).
+
 Version 1.9.2:
        On UNIX, wimlib can now overwrite readonly files when extracting.
 
index a046ef7..688d74f 100644 (file)
@@ -337,15 +337,20 @@ byte except '\\0' and \'/', so on a POSIX-compliant system this option will only
 have an effect in the unlikely case that the WIM image for some reason has a
 filename containing one of these characters.
 .IP ""
-On Windows, filenames are case-insensitive, cannot include the characters '/',
-\'\\0', '\\', ':', '*', '?', '"', '<', '>', or '|', and cannot end with a space
-or period.  Ordinarily, files in WIM images should meet these conditions as
-well. However, it is not guaranteed, and in particular a WIM image captured with
-\fBwimlib-imagex\fR on a POSIX-compliant system could contain such files.  By
-default, invalid names will be ignored, and if there are multiple names
+On Windows, filenames are case-insensitive(*), cannot include the characters
+'/', \'\\0', '\\', ':', '*', '?', '"', '<', '>', or '|', and cannot end with a
+space or period.  Ordinarily, files in WIM images should meet these conditions
+as well. However, it is not guaranteed, and in particular a WIM image captured
+with \fBwimlib-imagex\fR on a POSIX-compliant system could contain such files.
+By default, invalid names will be ignored, and if there are multiple names
 differing only in case, one will be chosen to extract arbitrarily; however, with
 \fB--include-invalid-names\fR, all names will be sanitized and extracted in some
 form.
+.IP ""
+(*) Unless the ObCaseInsensitive setting has been set to 0 in the Windows
+registry, in which case certain software, including the Windows version of
+\fBwimlib-imagex\fR, will honor case-sensitive filenames on NTFS and other
+compatible filesystems.
 .TP
 \fB--wimboot\fR
 Windows only: Instead of extracting the files themselves, extract "pointer
index 226441c..3b0db0a 100644 (file)
@@ -174,8 +174,9 @@ information, at least to the extent supported by the destination filesystem.
 Pedantic note: since Windows is not fully compatible with its own filesystem
 (NTFS), on Windows wimlib cannot archive certain files that may exist on a valid
 NTFS filesystem but are inaccessible to the Windows API, for example two files
-with names differing only in case in the same directory, or a file whose name
-contains certain characters considered invalid by Windows.  If you run into
+with names differing only in case in the same directory (unless
+ObCaseInsensitive has been set to 0 in the Windows registry), or a file whose
+name contains certain characters considered invalid by Windows.  If you run into
 problems archiving such files consider using the \fBNTFS VOLUME CAPTURE
 (UNIX)\fR mode from Linux.
 .SH OPTIONS
index df8b0cb..cbdacd3 100644 (file)
@@ -95,6 +95,13 @@ NtSetSecurityObject(IN HANDLE Handle,
                     IN SECURITY_INFORMATION SecurityInformation,
                     IN PSECURITY_DESCRIPTOR SecurityDescriptor);
 
+NTSTATUS
+NTAPI
+NtOpenSymbolicLinkObject(PHANDLE LinkHandle,
+                        ACCESS_MASK DesiredAccess,
+                        POBJECT_ATTRIBUTES ObjectAttributes);
+
+
 /* Dynamically loaded ntdll functions */
 
 extern NTSTATUS (WINAPI *func_RtlDosPathNameToNtPathName_U_WithStatus)
index 33c1a5d..a4f8175 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;
 }