Skip to content

Commit cc67487

Browse files
committed
Merge branch 'js/mingw-getcwd'
The way the Windows port figures out the current directory has been improved. * js/mingw-getcwd: mingw: fix getcwd when the parent directory cannot be queried mingw: ensure `getcwd()` reports the correct case
2 parents d1622fd + 4745fee commit cc67487

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed

compat/mingw.c

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,31 @@ static int ask_yes_no_if_possible(const char *format, ...)
203203
}
204204
}
205205

206+
/* Normalizes NT paths as returned by some low-level APIs. */
207+
static wchar_t *normalize_ntpath(wchar_t *wbuf)
208+
{
209+
int i;
210+
/* fix absolute path prefixes */
211+
if (wbuf[0] == '\\') {
212+
/* strip NT namespace prefixes */
213+
if (!wcsncmp(wbuf, L"\\??\\", 4) ||
214+
!wcsncmp(wbuf, L"\\\\?\\", 4))
215+
wbuf += 4;
216+
else if (!wcsnicmp(wbuf, L"\\DosDevices\\", 12))
217+
wbuf += 12;
218+
/* replace remaining '...UNC\' with '\\' */
219+
if (!wcsnicmp(wbuf, L"UNC\\", 4)) {
220+
wbuf += 2;
221+
*wbuf = '\\';
222+
}
223+
}
224+
/* convert backslashes to slashes */
225+
for (i = 0; wbuf[i]; i++)
226+
if (wbuf[i] == '\\')
227+
wbuf[i] = '/';
228+
return wbuf;
229+
}
230+
206231
int mingw_unlink(const char *pathname)
207232
{
208233
int ret, tries = 0;
@@ -918,8 +943,29 @@ struct tm *localtime_r(const time_t *timep, struct tm *result)
918943

919944
char *mingw_getcwd(char *pointer, int len)
920945
{
921-
wchar_t wpointer[MAX_PATH];
922-
if (!_wgetcwd(wpointer, ARRAY_SIZE(wpointer)))
946+
wchar_t cwd[MAX_PATH], wpointer[MAX_PATH];
947+
DWORD ret = GetCurrentDirectoryW(ARRAY_SIZE(cwd), cwd);
948+
949+
if (!ret || ret >= ARRAY_SIZE(cwd)) {
950+
errno = ret ? ENAMETOOLONG : err_win_to_posix(GetLastError());
951+
return NULL;
952+
}
953+
ret = GetLongPathNameW(cwd, wpointer, ARRAY_SIZE(wpointer));
954+
if (!ret && GetLastError() == ERROR_ACCESS_DENIED) {
955+
HANDLE hnd = CreateFileW(cwd, 0,
956+
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
957+
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
958+
if (hnd == INVALID_HANDLE_VALUE)
959+
return NULL;
960+
ret = GetFinalPathNameByHandleW(hnd, wpointer, ARRAY_SIZE(wpointer), 0);
961+
CloseHandle(hnd);
962+
if (!ret || ret >= ARRAY_SIZE(wpointer))
963+
return NULL;
964+
if (xwcstoutf(pointer, normalize_ntpath(wpointer), len) < 0)
965+
return NULL;
966+
return pointer;
967+
}
968+
if (!ret || ret >= ARRAY_SIZE(wpointer))
923969
return NULL;
924970
if (xwcstoutf(pointer, wpointer, len) < 0)
925971
return NULL;

0 commit comments

Comments
 (0)