aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/dcrt0.cc6
-rw-r--r--winsup/cygwin/globals.cc2
-rw-r--r--winsup/cygwin/path.cc30
3 files changed, 36 insertions, 2 deletions
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index f153c73..3bbee4d 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -730,6 +730,12 @@ init_windows_system_directory ()
system_wow64_directory[system_wow64_directory_length++] = L'\\';
system_wow64_directory[system_wow64_directory_length] = L'\0';
}
+ /* We need the Windows dir in path.cc. */
+ wcscpy (windows_directory, windows_system_directory);
+ windows_directory_length = windows_system_directory_length - 1;
+ windows_directory[windows_directory_length] = L'\0';
+ while (windows_directory[windows_directory_length - 1] != L'\\')
+ windows_directory[--windows_directory_length] = L'\0';
#endif /* __i386__ */
}
}
diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc
index 942bd1c..0b9559e 100644
--- a/winsup/cygwin/globals.cc
+++ b/winsup/cygwin/globals.cc
@@ -26,6 +26,8 @@ UINT windows_system_directory_length;
#ifdef __i386__
WCHAR system_wow64_directory[MAX_PATH];
UINT system_wow64_directory_length;
+WCHAR windows_directory[MAX_PATH];
+UINT windows_directory_length;
#endif /* __i386__ */
WCHAR global_progname[NT_MAX_PATH];
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 2248b56..93068a4 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -3187,9 +3187,31 @@ restart:
forces path_conv::check to backtrack inner path components. */
if (!fs.is_remote_drive ())
{
- PFILE_NAME_INFORMATION pfni = (PFILE_NAME_INFORMATION)
- tp.c_get ();
+#ifdef __i386__
+ /* On WOW64, ignore any potential problems if the path is inside
+ the Windows dir to avoid false positives for stuff under
+ File System Redirector control. */
+ if (wincap.is_wow64 ())
+ {
+ static UNICODE_STRING wpath;
+ UNICODE_STRING udpath;
+
+ /* Create UNICODE_STRING for Windows dir. */
+ RtlInitCountedUnicodeString (&wpath, windows_directory,
+ windows_directory_length * sizeof (WCHAR));
+ /* Create a UNICODE_STRING from incoming path, splitting
+ off the leading "\\??\\" */
+ RtlInitCountedUnicodeString (&udpath, upath.Buffer + 4,
+ upath.Length - 4 * sizeof (WCHAR));
+ /* Are we below Windows dir? Skip the check for inner
+ symlinks. */
+ if (RtlEqualUnicodePathPrefix (&udpath, &wpath, TRUE))
+ goto skip_inner_syml_check;
+ }
+#endif /* __i386__ */
+ PFILE_NAME_INFORMATION pfni;
+ pfni = (PFILE_NAME_INFORMATION) tp.c_get ();
if (NT_SUCCESS (NtQueryInformationFile (h, &io, pfni, NT_MAX_PATH,
FileNameInformation)))
{
@@ -3204,6 +3226,10 @@ restart:
break;
}
}
+#ifdef __i386__
+ skip_inner_syml_check:
+ ;
+#endif /* __i386__ */
}
}
if (!NT_SUCCESS (status))