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>
This commit is contained in:
parent
9614a29f17
commit
e70dbe774a
|
@ -73,3 +73,7 @@ Bug Fixes
|
||||||
- Fix a potential crash reading invalid passwd and group entries from
|
- Fix a potential crash reading invalid passwd and group entries from
|
||||||
/etc/passwd and /etc/group.
|
/etc/passwd and /etc/group.
|
||||||
Addresses: https://cygwin.com/ml/cygwin/2015-12/msg00170.html
|
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
|
||||||
|
|
|
@ -20,6 +20,7 @@ details. */
|
||||||
#include <sys/cygwin.h>
|
#include <sys/cygwin.h>
|
||||||
#include <cygwin/version.h>
|
#include <cygwin/version.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <wctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#define _WIN32_WINNT 0x0602
|
#define _WIN32_WINNT 0x0602
|
||||||
|
@ -579,20 +580,7 @@ do_sysfolders (char option)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'S':
|
case 'S':
|
||||||
{
|
GetSystemDirectoryW (wbuf, MAX_PATH);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'W':
|
case 'W':
|
||||||
|
@ -607,9 +595,43 @@ do_sysfolders (char option)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s: failed to retrieve special folder path\n",
|
fprintf (stderr, "%s: failed to retrieve special folder path\n",
|
||||||
prog_name);
|
prog_name);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if (!windows_flag)
|
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,
|
if (cygwin_conv_path (CCP_WIN_W_TO_POSIX | cygdrive_flag,
|
||||||
wbuf, buf, PATH_MAX))
|
wbuf, buf, PATH_MAX))
|
||||||
fprintf (stderr, "%s: error converting \"%ls\" - %s\n",
|
fprintf (stderr, "%s: error converting \"%ls\" - %s\n",
|
||||||
|
|
Loading…
Reference in New Issue