#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);
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;
}
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);
void VDir::Init(VDir* pDir, VMem *p)
{
int index;
- DWORD driveBits;
- int nSave;
- char szBuffer[MAX_PATH*driveCount];
pMem = p;
if (pDir) {
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<<index)) {
- ptr += SetDirA(ptr, index) + 1;
- FromEnvA(pEnv, index);
- }
- }
- FreeEnvironmentStrings(pEnv);
- }
- SetDefaultA(".");
- bManageDirectory = nSave;
- }
+ if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
+ char szBuffer[MAX_PATH*driveCount];
+ if (GetLogicalDriveStringsA(sizeof(szBuffer), szBuffer)) {
+ char* pEnv = (char*)GetEnvironmentStringsA();
+ char* ptr = szBuffer;
+ for (index = 0; index < driveCount; ++index) {
+ if (driveBits & (1<<index)) {
+ ptr += SetDirA(ptr, index) + 1;
+ FromEnvA(pEnv, index);
+ }
+ }
+ FreeEnvironmentStringsA(pEnv);
+ }
+ SetDefaultA(".");
+ }
+ else { /* Windows NT or later */
+ WCHAR szBuffer[MAX_PATH*driveCount];
+ if (GetLogicalDriveStringsW(sizeof(szBuffer), szBuffer)) {
+ WCHAR* pEnv = GetEnvironmentStringsW();
+ WCHAR* ptr = szBuffer;
+ for (index = 0; index < driveCount; ++index) {
+ if (driveBits & (1<<index)) {
+ ptr += SetDirW(ptr, index) + 1;
+ FromEnvW(pEnv, index);
+ }
+ }
+ FreeEnvironmentStringsW(pEnv);
+ }
+ SetDefaultW(L".");
+ }
+ bManageDirectory = bSave;
+ }
}
int VDir::SetDirA(char const *pPath, int index)
}
}
+void VDir::FromEnvW(WCHAR *pEnv, int index)
+{ /* gets the directory for index from the environment variable. */
+ while (*pEnv != '\0') {
+ if ((pEnv[0] == '=') && (DriveIndex((char)pEnv[1]) == index)) {
+ SetDirW(&pEnv[4], index);
+ break;
+ }
+ else
+ pEnv += wcslen(pEnv)+1;
+ }
+}
+
void VDir::SetDefaultA(char const *pDefault)
{
char szBuffer[MAX_PATH+1];