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
|
||||
/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
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user