Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

360 lines
9.3 KiB

//+---------------------------------------------------------------------------
//
// 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 <tchar.h>
#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;
}