//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1998 - 1998. // // File: fileutil.cxx // // Contents: Utility functions for file migration // // Classes: // // Functions: // // History: 07-Sep-99 PhilipLa Created // //---------------------------------------------------------------------------- #include "common.hxx" #include "fileutil.hxx" #include #define LINEBUFSIZE 1024 DWORD StatePrintfA (HANDLE h, CHAR *szFormat, ...) { CHAR szBuffer[LINEBUFSIZE]; #if 0 #ifdef UNICODE WCHAR wszFormat[LINEBUFSIZE]; //Convert to Unicode UINT uCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP; if (0 == MultiByteToWideChar(uCodePage, 0, szFormat, -1, wszFormat, LINEBUFSIZE)) { return GetLastError(); } ptsFormat = wszFormat; #else ptsFormat = szFormat; #endif #endif va_list va; ULONG ulWritten; ULONG ulLen; va_start (va, szFormat); ulLen = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, szFormat, 0, 0, szBuffer, LINEBUFSIZE, &va); va_end(va); if (FALSE == WriteFile (h, szBuffer, ulLen, &ulWritten, NULL)) return GetLastError(); else { if (ulWritten != ulLen) // incomplete write return ERROR_WRITE_FAULT; // last error may not be set } return ERROR_SUCCESS; } BOOL MatchString(const TCHAR *ptsPattern, const TCHAR *ptsString, const BOOL bRequireNullPatMatch) { ULONG iPat = 0; ULONG iStr = 0; TCHAR tcPat; TCHAR tcStr; if (ptsPattern[0] == 0) { //No pattern to match if (bRequireNullPatMatch == FALSE) return TRUE; if ( ptsString[0] == 0) return TRUE; return FALSE; } //Special case: Empty string, * as pattern if (ptsString[0] == 0 && ptsPattern[0] == TEXT('*') && ptsPattern[1] == 0) { return TRUE; } while (ptsString[iStr]) { tcPat = (TCHAR)_totlower(ptsPattern[iPat]); tcStr = (TCHAR)_totlower(ptsString[iStr]); if (tcPat == 0) { //Reached end of pattern, return FALSE; return FALSE; } if (tcPat == TEXT('?')) { // Never match '\' if (tcStr == TEXT('\\')) { return FALSE; } //Match any single character in the string and continue. iPat++; iStr++; } else if (tcPat != TEXT('*')) { //Match character if (tcPat != tcStr) { return FALSE; } iPat++; iStr++; } else { while (ptsPattern[iPat + 1] == TEXT('*')) { //Skip consecutive *s iPat++; } //If * all the way to the end, return true. if (ptsPattern[iPat + 1] == 0) return TRUE; // Lookahead one tcPat = (TCHAR)_totlower(ptsPattern[iPat + 1]); if ((tcPat == tcStr) || (tcPat == TEXT('?'))) { // Next character matches, continue with expression if (MatchString(ptsPattern + iPat + 1, ptsString + iStr, bRequireNullPatMatch)) return TRUE; } // Eat another character with the '*' pattern iStr++; } } if (!ptsPattern[iPat] && !ptsString[iStr]) return TRUE; // If only ?s and *s left in pattern, then call it a match if ( _tcsspnp(ptsPattern+iPat, TEXT("?*")) == NULL ) return TRUE; return FALSE; } BOOL IsPatternMatchFull(const TCHAR *ptsPatternFull, const TCHAR *ptsPath, const TCHAR *ptsFilename) { TCHAR tsPatternPath[MAX_PATH + 1]; TCHAR tsPatternFile[MAX_PATH + 1]; TCHAR tsPatternExt[MAX_PATH + 1]; DeconstructFilename(ptsPatternFull, tsPatternPath, tsPatternFile, tsPatternExt); return IsPatternMatch(tsPatternPath, tsPatternFile, tsPatternExt, ptsPath, ptsFilename); } BOOL IsPatternMatch(const TCHAR *ptsPatternDir, const TCHAR *ptsPatternFile, const TCHAR *ptsPatternExt, const TCHAR *ptsPath, const TCHAR *ptsFilename) { BOOL fRet; TCHAR tsFilePath[MAX_PATH]; TCHAR tsFileName[MAX_PATH]; TCHAR tsFileExt[MAX_PATH]; BOOL bRequireNullMatch = FALSE; DeconstructFilename(ptsFilename, NULL, tsFileName, tsFileExt); //Special case: Directories have a ptsFilename of NULL, but shouldn't //match on *.* if ((ptsFilename == NULL) && (ptsPatternDir[0] == 0)) { //Return FALSE; fRet = FALSE; } else { if ((ptsPatternFile == NULL) && (ptsPatternExt == NULL) && (tsFileName[0] == 0) && (tsFileExt[0] == 0)) { //Directory only fRet = MatchString(ptsPatternDir, ptsPath, FALSE); } else { // If filename or extension is specified in the pattern, // match a null file piece only if pattern is null too. // i.e.: ".txt" and "*." if ( ptsPatternFile[0] != 0 || ptsPatternExt[0] != 0 ) bRequireNullMatch = TRUE; fRet = (MatchString(ptsPatternDir, ptsPath, FALSE) && MatchString(ptsPatternFile, tsFileName, bRequireNullMatch) && MatchString(ptsPatternExt, tsFileExt, bRequireNullMatch)); } } return fRet; } BOOL DeconstructFilename(const TCHAR *ptsString, TCHAR *ptsPath, TCHAR *ptsName, TCHAR *ptsExt) { const TCHAR *ptsLastSlash; const TCHAR *ptsLastDot; ptsLastSlash = (ptsString) ? _tcsrchr(ptsString, TEXT('\\')) : NULL; if (ptsLastSlash == NULL) { if (ptsPath) ptsPath[0] = 0; ptsLastSlash = ptsString; } else { if (ptsPath) { if (ptsLastSlash - ptsString + 1 > MAX_PATH) { if (DebugOutput) { Win32Printf(LogFile, "Error: ptsString too long %*s\r\n", ptsLastSlash - ptsString + 1, ptsString); } ptsPath[0] = 0; return FALSE; } _tcsncpy(ptsPath, ptsString, ptsLastSlash - ptsString + 1); ptsPath[ptsLastSlash - ptsString + 1] = 0; } ptsLastSlash++; } ptsLastDot = (ptsLastSlash) ? _tcsrchr(ptsLastSlash, TEXT('.')) : NULL; if (ptsLastDot == NULL) { if (ptsExt) ptsExt[0] = 0; if (ptsName) { if (ptsLastSlash) { if (_tcslen(ptsLastSlash) > MAX_PATH) { if (DebugOutput) { Win32Printf(LogFile, "Error: ptsLastSlash too long %s\r\n", ptsLastSlash); } ptsName[0] = 0; return FALSE; } _tcscpy(ptsName, ptsLastSlash); } else { ptsName[0] = 0; } } } else { if (ptsExt) { if (_tcslen(ptsLastDot+1) > MAX_PATH) { if (DebugOutput) { Win32Printf(LogFile, "Error: ptsLastDot too long %s\r\n", ptsLastDot+1); } ptsExt[0] = 0; return FALSE; } _tcscpy(ptsExt, ptsLastDot + 1); } if (ptsName) { if (ptsLastDot - ptsLastSlash > MAX_PATH) { if (DebugOutput) { Win32Printf(LogFile, "Error: ptsLastSlash Too Long %*s\r\n", ptsLastDot - ptsLastSlash, ptsLastSlash); } ptsName[0] = 0; return FALSE; } _tcsncpy(ptsName, ptsLastSlash, ptsLastDot - ptsLastSlash); ptsName[ptsLastDot - ptsLastSlash] = 0; } } return TRUE; }