class VDir
{
public:
- VDir();
+ VDir(int bManageDir = 1);
~VDir() {};
void Init(VDir* pDir, VMem *pMem);
WCHAR* MapPathW(const WCHAR *pInName);
int SetCurrentDirectoryA(char *lpBuffer);
int SetCurrentDirectoryW(WCHAR *lpBuffer);
- inline const char *GetDirA(int index)
- {
- return dirTableA[index];
- };
- inline const WCHAR *GetDirW(int index)
- {
- return dirTableW[index];
- };
inline int GetDefault(void) { return nDefault; };
inline char* GetCurrentDirectoryA(int dwBufSize, char *lpBuffer)
SetDirW(pPath, index);
nDefault = index;
};
+ inline const char *GetDirA(int index)
+ {
+ char *ptr = dirTableA[index];
+ if (!ptr) {
+ /* simulate the existance of this drive */
+ ptr = szLocalBufferA;
+ ptr[0] = 'A' + index;
+ ptr[1] = ':';
+ ptr[2] = '\\';
+ ptr[3] = 0;
+ }
+ return ptr;
+ };
+ inline const WCHAR *GetDirW(int index)
+ {
+ WCHAR *ptr = dirTableW[index];
+ if (!ptr) {
+ /* simulate the existance of this drive */
+ ptr = szLocalBufferW;
+ ptr[0] = 'A' + index;
+ ptr[1] = ':';
+ ptr[2] = '\\';
+ ptr[3] = 0;
+ }
+ return ptr;
+ };
inline int DriveIndex(char chr)
{
};
VMem *pMem;
- int nDefault;
+ int nDefault, bManageDirectory;
char *dirTableA[driveCount];
char szLocalBufferA[MAX_PATH+1];
WCHAR *dirTableW[driveCount];
};
-VDir::VDir()
+VDir::VDir(int bManageDir /* = 1 */)
{
nDefault = 0;
+ bManageDirectory = bManageDir;
memset(dirTableA, 0, sizeof(dirTableA));
memset(dirTableW, 0, sizeof(dirTableW));
}
{
int index;
DWORD driveBits;
+ int nSave;
char szBuffer[MAX_PATH*driveCount];
pMem = p;
nDefault = pDir->GetDefault();
}
else {
+ nSave = bManageDirectory;
+ bManageDirectory = 0;
driveBits = GetLogicalDrives();
if (GetLogicalDriveStrings(sizeof(szBuffer), szBuffer)) {
char* pEnv = GetEnvironmentStrings();
FreeEnvironmentStrings(pEnv);
}
SetDefaultA(".");
+ bManageDirectory = nSave;
}
}
}
}
}
+
+ if(bManageDirectory)
+ ::SetCurrentDirectoryA(pPath);
+
return length;
}
}
}
}
+
+ if(bManageDirectory)
+ ::SetCurrentDirectoryW(pPath);
+
return length;
}
GetFullPathNameA(lpBuffer, dwSize, Dest, &pPtr);
}
+inline bool IsSpecialFileName(const char* pName)
+{
+ /* specical file names are devices that the system can open
+ * these include AUX, CON, NUL, PRN, COMx, LPTx, CLOCK$, CONIN$, CONOUT$
+ * (x is a single digit, and names are case-insensitive)
+ */
+ char ch = (pName[0] & ~0x20);
+ switch (ch)
+ {
+ case 'A': /* AUX */
+ if (((pName[1] & ~0x20) == 'U')
+ && ((pName[2] & ~0x20) == 'X')
+ && !pName[3])
+ return true;
+ break;
+ case 'C': /* CLOCK$, COMx, CON, CONIN$ CONOUT$ */
+ ch = (pName[1] & ~0x20);
+ switch (ch)
+ {
+ case 'L': /* CLOCK$ */
+ if (((pName[2] & ~0x20) == 'O')
+ && ((pName[3] & ~0x20) == 'C')
+ && ((pName[4] & ~0x20) == 'K')
+ && (pName[5] == '$')
+ && !pName[6])
+ return true;
+ break;
+ case 'O': /* COMx, CON, CONIN$ CONOUT$ */
+ if ((pName[2] & ~0x20) == 'M') {
+ if ((pName[3] >= '1') && (pName[3] <= '9')
+ && !pName[4])
+ return true;
+ }
+ else if ((pName[2] & ~0x20) == 'N') {
+ if (!pName[3])
+ return true;
+ else if ((pName[3] & ~0x20) == 'I') {
+ if (((pName[4] & ~0x20) == 'N')
+ && (pName[5] == '$')
+ && !pName[6])
+ return true;
+ }
+ else if ((pName[3] & ~0x20) == 'O') {
+ if (((pName[4] & ~0x20) == 'U')
+ && ((pName[5] & ~0x20) == 'T')
+ && (pName[6] == '$')
+ && !pName[7])
+ return true;
+ }
+ }
+ break;
+ }
+ break;
+ case 'L': /* LPTx */
+ if (((pName[1] & ~0x20) == 'U')
+ && ((pName[2] & ~0x20) == 'X')
+ && (pName[3] >= '1') && (pName[3] <= '9')
+ && !pName[4])
+ return true;
+ break;
+ case 'N': /* NUL */
+ if (((pName[1] & ~0x20) == 'U')
+ && ((pName[2] & ~0x20) == 'L')
+ && !pName[3])
+ return true;
+ break;
+ case 'P': /* PRN */
+ if (((pName[1] & ~0x20) == 'R')
+ && ((pName[2] & ~0x20) == 'N')
+ && !pName[3])
+ return true;
+ break;
+ }
+ return false;
+}
+
char *VDir::MapPathA(const char *pInName)
{ /*
* possiblities -- relative path or absolute path with or without drive letter
}
else {
/* relative path */
- strcat(szBuffer, pInName);
- if (strlen(szBuffer) > MAX_PATH)
- szBuffer[MAX_PATH] = '\0';
+ if (IsSpecialFileName(pInName)) {
+ return (char*)pInName;
+ }
+ else {
+ strcat(szBuffer, pInName);
+ if (strlen(szBuffer) > MAX_PATH)
+ szBuffer[MAX_PATH] = '\0';
- DoGetFullPathNameA(szBuffer, sizeof(szLocalBufferA), szLocalBufferA);
+ DoGetFullPathNameA(szBuffer, sizeof(szLocalBufferA), szLocalBufferA);
+ }
}
}
}
HANDLE hHandle;
WIN32_FIND_DATA win32FD;
char szBuffer[MAX_PATH+1], *pPtr;
- int nRet = -1;
+ int length, nRet = -1;
GetFullPathNameA(MapPathA(lpBuffer), sizeof(szBuffer), szBuffer, &pPtr);
+ /* if the last char is a '\\' or a '/' then add
+ * an '*' before calling FindFirstFile
+ */
+ length = strlen(szBuffer);
+ if(length > 0 && IsPathSep(szBuffer[length-1])) {
+ szBuffer[length] = '*';
+ szBuffer[length+1] = '\0';
+ }
- hHandle = FindFirstFile(szBuffer, &win32FD);
+ hHandle = FindFirstFileA(szBuffer, &win32FD);
if (hHandle != INVALID_HANDLE_VALUE) {
FindClose(hHandle);
- SetDefaultDirA(szBuffer, DriveIndex(szBuffer[0]));
- nRet = 0;
- }
- return nRet;
-}
-int VDir::SetCurrentDirectoryW(WCHAR *lpBuffer)
-{
- HANDLE hHandle;
- WIN32_FIND_DATAW win32FD;
- WCHAR szBuffer[MAX_PATH+1], *pPtr;
- int nRet = -1;
-
- GetFullPathNameW(MapPathW(lpBuffer), (sizeof(szBuffer)/sizeof(WCHAR)), szBuffer, &pPtr);
+ /* if an '*' was added remove it */
+ if(szBuffer[length] == '*')
+ szBuffer[length] = '\0';
- hHandle = FindFirstFileW(szBuffer, &win32FD);
- if (hHandle != INVALID_HANDLE_VALUE) {
- FindClose(hHandle);
- SetDefaultDirW(szBuffer, DriveIndex((char)szBuffer[0]));
+ SetDefaultDirA(szBuffer, DriveIndex(szBuffer[0]));
nRet = 0;
}
return nRet;
GetFullPathNameW(lpBuffer, dwSize, Dest, &pPtr);
}
+inline bool IsSpecialFileName(const WCHAR* pName)
+{
+ /* specical file names are devices that the system can open
+ * these include AUX, CON, NUL, PRN, COMx, LPTx, CLOCK$, CONIN$, CONOUT$
+ * (x is a single digit, and names are case-insensitive)
+ */
+ WCHAR ch = (pName[0] & ~0x20);
+ switch (ch)
+ {
+ case 'A': /* AUX */
+ if (((pName[1] & ~0x20) == 'U')
+ && ((pName[2] & ~0x20) == 'X')
+ && !pName[3])
+ return true;
+ break;
+ case 'C': /* CLOCK$, COMx, CON, CONIN$ CONOUT$ */
+ ch = (pName[1] & ~0x20);
+ switch (ch)
+ {
+ case 'L': /* CLOCK$ */
+ if (((pName[2] & ~0x20) == 'O')
+ && ((pName[3] & ~0x20) == 'C')
+ && ((pName[4] & ~0x20) == 'K')
+ && (pName[5] == '$')
+ && !pName[6])
+ return true;
+ break;
+ case 'O': /* COMx, CON, CONIN$ CONOUT$ */
+ if ((pName[2] & ~0x20) == 'M') {
+ if ((pName[3] >= '1') && (pName[3] <= '9')
+ && !pName[4])
+ return true;
+ }
+ else if ((pName[2] & ~0x20) == 'N') {
+ if (!pName[3])
+ return true;
+ else if ((pName[3] & ~0x20) == 'I') {
+ if (((pName[4] & ~0x20) == 'N')
+ && (pName[5] == '$')
+ && !pName[6])
+ return true;
+ }
+ else if ((pName[3] & ~0x20) == 'O') {
+ if (((pName[4] & ~0x20) == 'U')
+ && ((pName[5] & ~0x20) == 'T')
+ && (pName[6] == '$')
+ && !pName[7])
+ return true;
+ }
+ }
+ break;
+ }
+ break;
+ case 'L': /* LPTx */
+ if (((pName[1] & ~0x20) == 'U')
+ && ((pName[2] & ~0x20) == 'X')
+ && (pName[3] >= '1') && (pName[3] <= '9')
+ && !pName[4])
+ return true;
+ break;
+ case 'N': /* NUL */
+ if (((pName[1] & ~0x20) == 'U')
+ && ((pName[2] & ~0x20) == 'L')
+ && !pName[3])
+ return true;
+ break;
+ case 'P': /* PRN */
+ if (((pName[1] & ~0x20) == 'R')
+ && ((pName[2] & ~0x20) == 'N')
+ && !pName[3])
+ return true;
+ break;
+ }
+ return false;
+}
+
WCHAR* VDir::MapPathW(const WCHAR *pInName)
{ /*
* possiblities -- relative path or absolute path with or without drive letter
}
else {
/* relative path */
- wcscat(szBuffer, pInName);
- if (wcslen(szBuffer) > MAX_PATH)
- szBuffer[MAX_PATH] = '\0';
+ if (IsSpecialFileName(pInName)) {
+ return (WCHAR*)pInName;
+ }
+ else {
+ wcscat(szBuffer, pInName);
+ if (wcslen(szBuffer) > MAX_PATH)
+ szBuffer[MAX_PATH] = '\0';
- DoGetFullPathNameW(szBuffer, (sizeof(szLocalBufferW)/sizeof(WCHAR)), szLocalBufferW);
+ DoGetFullPathNameW(szBuffer, (sizeof(szLocalBufferW)/sizeof(WCHAR)), szLocalBufferW);
+ }
}
}
}
return szLocalBufferW;
}
+int VDir::SetCurrentDirectoryW(WCHAR *lpBuffer)
+{
+ HANDLE hHandle;
+ WIN32_FIND_DATAW win32FD;
+ WCHAR szBuffer[MAX_PATH+1], *pPtr;
+ int length, nRet = -1;
+
+ GetFullPathNameW(MapPathW(lpBuffer), (sizeof(szBuffer)/sizeof(WCHAR)), szBuffer, &pPtr);
+ /* if the last char is a '\\' or a '/' then add
+ * an '*' before calling FindFirstFile
+ */
+ length = wcslen(szBuffer);
+ if(length > 0 && IsPathSep(szBuffer[length-1])) {
+ szBuffer[length] = '*';
+ szBuffer[length+1] = '\0';
+ }
+
+ hHandle = FindFirstFileW(szBuffer, &win32FD);
+ if (hHandle != INVALID_HANDLE_VALUE) {
+ FindClose(hHandle);
+
+ /* if an '*' was added remove it */
+ if(szBuffer[length] == '*')
+ szBuffer[length] = '\0';
+
+ SetDefaultDirW(szBuffer, DriveIndex((char)szBuffer[0]));
+ nRet = 0;
+ }
+ return nRet;
+}
#endif /* ___VDir_H___ */