From d684b16258d4be88a6b78f17e48637c1127b0ed7 Mon Sep 17 00:00:00 2001 From: Jan Dubois Date: Mon, 18 Dec 2006 13:37:25 -0800 Subject: [PATCH] Update cwd() to return the "short" pathname if the long one doesn't fit the codepage Message-ID: <3rteo219or8hqr511e4vg1fnsgvgemb4sh@4ax.com> p4raw-id: //depot/perl@29598 --- win32/perlhost.h | 54 ++++++++++++++++++++++++++++------ win32/vdir.h | 88 +++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 106 insertions(+), 36 deletions(-) diff --git a/win32/perlhost.h b/win32/perlhost.h index fe026dd..d6e1e0f 100644 --- a/win32/perlhost.h +++ b/win32/perlhost.h @@ -21,6 +21,10 @@ #include "vmem.h" #include "vdir.h" +#ifndef WC_NO_BEST_FIT_CHARS +# define WC_NO_BEST_FIT_CHARS 0x00000400 +#endif + START_EXTERN_C extern char * g_win32_get_privlib(const char *pl); extern char * g_win32_get_sitelib(const char *pl); @@ -2236,20 +2240,52 @@ CPerlHost::FreeLocalEnvironmentStrings(LPSTR lpStr) Safefree(lpStr); } +static char * +get_valid_filename(pTHX_ WCHAR *widename) +{ + char *name; + BOOL use_default = FALSE; + size_t widelen = wcslen(widename)+1; + int len = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, widename, widelen, + NULL, 0, NULL, NULL); + Newx(name, len, char); + WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, widename, widelen, + name, len, NULL, &use_default); + if (use_default) { + WCHAR *shortname; + DWORD shortlen = GetShortPathNameW(widename, NULL, 0); + Newx(shortname, shortlen, WCHAR); + shortlen = GetShortPathNameW(widename, shortname, shortlen)+1; + len = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, shortname, shortlen, + NULL, 0, NULL, NULL); + Renew(name, len, char); + WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, shortname, shortlen, + name, len, NULL, NULL); + Safefree(shortname); + } + return name; +} + char* CPerlHost::GetChildDir(void) { dTHX; - int length; char* ptr; - Newx(ptr, MAX_PATH+1, char); - if(ptr) { - m_pvDir->GetCurrentDirectoryA(MAX_PATH+1, ptr); - length = strlen(ptr); - if (length > 3) { - if ((ptr[length-1] == '\\') || (ptr[length-1] == '/')) - ptr[length-1] = 0; - } + size_t length; + + if (IsWin95()) { + Newx(ptr, MAX_PATH+1, char); + m_pvDir->GetCurrentDirectoryA(MAX_PATH+1, ptr); + } + else { + WCHAR path[MAX_PATH+1]; + m_pvDir->GetCurrentDirectoryW(MAX_PATH+1, path); + ptr = get_valid_filename(aTHX_ path); + } + length = strlen(ptr); + if (length > 3) { + if ((ptr[length-1] == '\\') || (ptr[length-1] == '/')) + ptr[length-1] = 0; } return ptr; } diff --git a/win32/vdir.h b/win32/vdir.h index 10119ea..fb80e38 100644 --- a/win32/vdir.h +++ b/win32/vdir.h @@ -34,47 +34,48 @@ public: inline char* GetCurrentDirectoryA(int dwBufSize, char *lpBuffer) { char* ptr = dirTableA[nDefault]; - while (dwBufSize--) + while (--dwBufSize) { if ((*lpBuffer++ = *ptr++) == '\0') break; } - return lpBuffer; + *lpBuffer = '\0'; + return /* unused */ NULL; }; inline WCHAR* GetCurrentDirectoryW(int dwBufSize, WCHAR *lpBuffer) { WCHAR* ptr = dirTableW[nDefault]; - while (dwBufSize--) + while (--dwBufSize) { if ((*lpBuffer++ = *ptr++) == '\0') break; } - return lpBuffer; + *lpBuffer = '\0'; + return /* unused */ NULL; }; - DWORD CalculateEnvironmentSpace(void); LPSTR BuildEnvironmentSpace(LPSTR lpStr); protected: int SetDirA(char const *pPath, int index); + int SetDirW(WCHAR const *pPath, int index); void FromEnvA(char *pEnv, int index); + void FromEnvW(WCHAR *pEnv, int index); + inline const char *GetDefaultDirA(void) { return dirTableA[nDefault]; }; - inline void SetDefaultDirA(char const *pPath, int index) { SetDirA(pPath, index); nDefault = index; }; - int SetDirW(WCHAR const *pPath, int index); inline const WCHAR *GetDefaultDirW(void) { return dirTableW[nDefault]; }; - inline void SetDefaultDirW(WCHAR const *pPath, int index) { SetDirW(pPath, index); @@ -134,9 +135,6 @@ VDir::VDir(int bManageDir /* = 1 */) void VDir::Init(VDir* pDir, VMem *p) { int index; - DWORD driveBits; - int nSave; - char szBuffer[MAX_PATH*driveCount]; pMem = p; if (pDir) { @@ -146,23 +144,47 @@ void VDir::Init(VDir* pDir, VMem *p) nDefault = pDir->GetDefault(); } else { - nSave = bManageDirectory; + int bSave = bManageDirectory; + DWORD driveBits = GetLogicalDrives(); + OSVERSIONINFO osver; + + memset(&osver, 0, sizeof(osver)); + osver.dwOSVersionInfoSize = sizeof(osver); + GetVersionEx(&osver); + bManageDirectory = 0; - driveBits = GetLogicalDrives(); - if (GetLogicalDriveStrings(sizeof(szBuffer), szBuffer)) { - char* pEnv = (char*)GetEnvironmentStrings(); - char* ptr = szBuffer; - for (index = 0; index < driveCount; ++index) { - if (driveBits & (1<