Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2016-01-07 23:07:56 +0300
committerCorinna Vinschen <corinna@vinschen.de>2016-01-07 23:07:56 +0300
commite70dbe774a0c5fe2f8112e06df1e231b1f114560 (patch)
treef959d72c30c99441733b9cba8d6920c4e491c9cf
parent9614a29f17952f52bbce6f55be54523eaeea8580 (diff)
cygpath: Try to return system directories with correct case
* cygpath.cc (do_sysfolders): Drop lame workaround to fix case of directory returned by GetSystemDirectoryW. Try to fix case of any path returned by this function in case it has to return a POSIX path to support case-sensitivity. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r--winsup/cygwin/release/2.4.04
-rw-r--r--winsup/utils/cygpath.cc50
2 files changed, 40 insertions, 14 deletions
diff --git a/winsup/cygwin/release/2.4.0 b/winsup/cygwin/release/2.4.0
index 4feff5b80..5953d61ea 100644
--- a/winsup/cygwin/release/2.4.0
+++ b/winsup/cygwin/release/2.4.0
@@ -73,3 +73,7 @@ Bug Fixes
- Fix a potential crash reading invalid passwd and group entries from
/etc/passwd and /etc/group.
Addresses: https://cygwin.com/ml/cygwin/2015-12/msg00170.html
+
+- Cygpath(1) now tries to correct the case of system directories when
+ returned as POSIX paths.
+ Addresses: https://cygwin.com/ml/cygwin/2016-01/msg00002.html
diff --git a/winsup/utils/cygpath.cc b/winsup/utils/cygpath.cc
index 0fbb2e90e..c0a527631 100644
--- a/winsup/utils/cygpath.cc
+++ b/winsup/utils/cygpath.cc
@@ -20,6 +20,7 @@ details. */
#include <sys/cygwin.h>
#include <cygwin/version.h>
#include <ctype.h>
+#include <wctype.h>
#include <errno.h>
#define _WIN32_WINNT 0x0602
@@ -579,20 +580,7 @@ do_sysfolders (char option)
break;
case 'S':
- {
- HANDLE fh;
- WIN32_FIND_DATAW w32_fd;
-
- GetSystemDirectoryW (wbuf, MAX_PATH);
- /* The path returned by GetSystemDirectoryW is not case preserving.
- The below code is a trick to get the correct case of the system
- directory from Windows. */
- if ((fh = FindFirstFileW (wbuf, &w32_fd)) != INVALID_HANDLE_VALUE)
- {
- FindClose (fh);
- wcscpy (wcsrchr (wbuf, L'\\') + 1, w32_fd.cFileName);
- }
- }
+ GetSystemDirectoryW (wbuf, MAX_PATH);
break;
case 'W':
@@ -607,9 +595,43 @@ do_sysfolders (char option)
{
fprintf (stderr, "%s: failed to retrieve special folder path\n",
prog_name);
+ return;
}
else if (!windows_flag)
{
+ /* The system folders are not necessarily case-correct. To allow
+ case-sensitivity, try to correct the case. Note that this only
+ works for local filesystems. */
+ if (iswalpha (wbuf[0]) && wbuf[1] == L':' && wbuf[2] == L'\\')
+ {
+ OBJECT_ATTRIBUTES attr;
+ NTSTATUS status;
+ HANDLE h;
+ IO_STATUS_BLOCK io;
+ UNICODE_STRING upath;
+ const ULONG size = sizeof (FILE_NAME_INFORMATION)
+ + PATH_MAX * sizeof (WCHAR);
+ PFILE_NAME_INFORMATION pfni = (PFILE_NAME_INFORMATION) alloca (size);
+
+ /* Avoid another buffer, reuse pfni. */
+ wcpcpy (wcpcpy (pfni->FileName, L"\\??\\"), wbuf);
+ RtlInitUnicodeString (&upath, pfni->FileName);
+ InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE,
+ NULL, NULL);
+ status = NtOpenFile (&h, READ_CONTROL, &attr, &io,
+ FILE_SHARE_VALID_FLAGS, FILE_OPEN_REPARSE_POINT);
+ if (NT_SUCCESS (status))
+ {
+ status = NtQueryInformationFile (h, &io, pfni, size,
+ FileNameInformation);
+ if (NT_SUCCESS (status))
+ {
+ pfni->FileName[pfni->FileNameLength / sizeof (WCHAR)] = L'\0';
+ wcscpy (wbuf + 2, pfni->FileName);
+ }
+ NtClose (h);
+ }
+ }
if (cygwin_conv_path (CCP_WIN_W_TO_POSIX | cygdrive_flag,
wbuf, buf, PATH_MAX))
fprintf (stderr, "%s: error converting \"%ls\" - %s\n",