diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index d4118aba6..b677e67d4 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,11 @@ +2012-02-21 Corinna Vinschen + + Based on an idea from Nick Lowe : + * shared.cc (shared_info::init_obcaseinsensitive): Check actual state + of case sensitivity on post-Windows 2000 systems. + * wincap.h (wincaps::kernel_is_always_casesensitive): New element. + * wincap.cc: Implement above element throughout. + 2012-02-20 Corinna Vinschen * flock.cc (inode_t::del_my_locks): Drop useless counter lc. Close diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc index 86f93c269..7a0b2510b 100644 --- a/winsup/cygwin/shared.cc +++ b/winsup/cygwin/shared.cc @@ -286,23 +286,44 @@ shared_destroy () UnmapViewOfFile (user_shared); } -/* Initialize obcaseinsensitive. Default to case insensitive on pre-XP. */ +/* Initialize obcaseinsensitive.*/ void shared_info::init_obcaseinsensitive () { - NTSTATUS status; - DWORD def_obcaseinsensitive = 1; + if (wincap.kernel_is_always_casesensitive ()) + { + /* Only Windows 2000. Default to case insensitive unless the user + sets the obcaseinsensitive registry value explicitely to 0. */ + DWORD def_obcaseinsensitive = 1; - obcaseinsensitive = def_obcaseinsensitive; - RTL_QUERY_REGISTRY_TABLE tab[2] = { - { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOSTRING, - L"obcaseinsensitive", &obcaseinsensitive, REG_DWORD, - &def_obcaseinsensitive, sizeof (DWORD) }, - { NULL, 0, NULL, NULL, 0, NULL, 0 } - }; - status = RtlQueryRegistryValues (RTL_REGISTRY_CONTROL, - L"Session Manager\\kernel", - tab, NULL, NULL); + obcaseinsensitive = def_obcaseinsensitive; + RTL_QUERY_REGISTRY_TABLE tab[2] = { + { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOSTRING, + L"obcaseinsensitive", &obcaseinsensitive, REG_DWORD, + &def_obcaseinsensitive, sizeof (DWORD) }, + { NULL, 0, NULL, NULL, 0, NULL, 0 } + }; + RtlQueryRegistryValues (RTL_REGISTRY_CONTROL, + L"Session Manager\\kernel", + tab, NULL, NULL); + } + else + { + /* Instead of reading the obcaseinsensitive registry value, test the + actual state of case sensitivity handling in the kernel. */ + UNICODE_STRING sysroot; + OBJECT_ATTRIBUTES attr; + HANDLE h; + + RtlInitUnicodeString (&sysroot, L"\\SYSTEMROOT"); + InitializeObjectAttributes (&attr, &sysroot, 0, NULL, NULL); + /* NtOpenSymbolicLinkObject returns STATUS_ACCESS_DENIED when called + with a 0 access mask. However, if the kernel is case sensitive, + it returns STATUS_OBJECT_NAME_NOT_FOUND because we used the incorrect + case for the filename (It's actually "\\SystemRoot"). */ + obcaseinsensitive = NtOpenSymbolicLinkObject (&h, 0, &attr) + != STATUS_OBJECT_NAME_NOT_FOUND; + } } void inline diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index 91af3c624..6fe172f77 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -54,6 +54,7 @@ wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = { has_console_logon_sid:false, wow64_has_secondary_stack:false, has_program_compatibility_assitant:false, + kernel_is_always_casesensitive:true, }; wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) = { @@ -87,6 +88,7 @@ wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) = has_console_logon_sid:false, wow64_has_secondary_stack:false, has_program_compatibility_assitant:false, + kernel_is_always_casesensitive:true, }; wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = { @@ -120,6 +122,7 @@ wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = { has_console_logon_sid:false, wow64_has_secondary_stack:false, has_program_compatibility_assitant:false, + kernel_is_always_casesensitive:false, }; wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = { @@ -153,6 +156,7 @@ wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = { has_console_logon_sid:false, wow64_has_secondary_stack:false, has_program_compatibility_assitant:false, + kernel_is_always_casesensitive:false, }; wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = { @@ -186,6 +190,7 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = { has_console_logon_sid:false, wow64_has_secondary_stack:false, has_program_compatibility_assitant:false, + kernel_is_always_casesensitive:false, }; wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = { @@ -219,6 +224,7 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = { has_console_logon_sid:false, wow64_has_secondary_stack:true, has_program_compatibility_assitant:false, + kernel_is_always_casesensitive:false, }; wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = { @@ -252,6 +258,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = { has_console_logon_sid:false, wow64_has_secondary_stack:false, has_program_compatibility_assitant:true, + kernel_is_always_casesensitive:false, }; wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = { @@ -285,6 +292,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = { has_console_logon_sid:true, wow64_has_secondary_stack:false, has_program_compatibility_assitant:true, + kernel_is_always_casesensitive:false, }; wincapc wincap __attribute__((section (".cygwin_dll_common"), shared)); diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index 87620286d..3ca5d87ea 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -44,6 +44,7 @@ struct wincaps unsigned has_console_logon_sid : 1; unsigned wow64_has_secondary_stack : 1; unsigned has_program_compatibility_assitant : 1; + unsigned kernel_is_always_casesensitive : 1; }; class wincapc @@ -96,6 +97,7 @@ public: bool IMPLEMENT (has_console_logon_sid) bool IMPLEMENT (wow64_has_secondary_stack) bool IMPLEMENT (has_program_compatibility_assitant) + bool IMPLEMENT (kernel_is_always_casesensitive) #undef IMPLEMENT };