From 099817c3dba479a8b494fe72f576c8fd1420c2b1 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 18 Jun 2012 20:17:15 +0000 Subject: [PATCH] * cygheap.cc (init_cygheap::init_installation_root): Rearrange code creating valid native NT installation_root path. Only strip last backslash from path if the result is a valid NT path. Explain why. --- winsup/cygwin/ChangeLog | 6 ++++++ winsup/cygwin/cygheap.cc | 28 ++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index ef885e083..5a451abef 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,9 @@ +2012-06-18 Corinna Vinschen + + * cygheap.cc (init_cygheap::init_installation_root): Rearrange code + creating valid native NT installation_root path. Only strip last + backslash from path if the result is a valid NT path. Explain why. + 2012-06-17 Christopher Faylor Add '#include "cygwait.h"' throughout, where appropriate. diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index bc96a5533..c7f1f6ab4 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -170,18 +170,28 @@ init_cygheap::init_installation_root () "GetModuleFileNameW(%p, %p, %u), %E", cygwin_hmodule, installation_root, PATH_MAX); PWCHAR p = installation_root; - if (wcsncmp (p, L"\\\\?\\", 4)) /* No long path prefix. */ + if (wcsncasecmp (p, L"\\\\", 2)) /* Normal drive letter path */ { - if (!wcsncasecmp (p, L"\\\\", 2)) /* UNC */ + p = wcpcpy (p, L"\\??\\"); + GetModuleFileNameW (cygwin_hmodule, p, PATH_MAX - 4); + } + else + { + bool unc = false; + if (wcsncmp (p + 2, L"?\\", 2)) /* No long path prefix, so UNC path. */ { p = wcpcpy (p, L"\\??\\UN"); GetModuleFileNameW (cygwin_hmodule, p, PATH_MAX - 6); *p = L'C'; + unc = true; } - else + else if (!wcsncmp (p + 4, L"UNC\\", 4)) /* Native NT UNC path. */ + unc = true; + if (unc) { - p = wcpcpy (p, L"\\??\\"); - GetModuleFileNameW (cygwin_hmodule, p, PATH_MAX - 4); + p = wcschr (p + 2, L'\\'); /* Skip server name */ + if (p) + p = wcschr (p + 1, L'\\'); /* Skip share name */ } } installation_root[1] = L'?'; @@ -200,7 +210,13 @@ init_cygheap::init_installation_root () if (!w) api_fatal ("Can't initialize Cygwin installation root dir.\n" "Invalid DLL path"); - *w = L'\0'; + /* If w < p, the Cygwin DLL resides in the root dir of a drive or network + path. In that case, if we strip off yet another backslash, the path + becomes invalid. We avoid that here so that the DLL also works in this + scenario. The /usr/bin and /usr/lib default mounts will probably point + to something non-existing, but that's life. */ + if (w > p) + *w = L'\0'; for (int i = 1; i >= 0; --i) {