|
|
/*
* comc.c - Shared routines. */
/* Headers
**********/
#include "project.h"
#pragma hdrstop
/****************************** Public Functions *****************************/
/*
** CatPath() ** ** Appends a filename to a path string. ** ** Arguments: pszPath - path string that file name is to be appended to ** pcszSubPath - path to append ** ** Returns: void ** ** Side Effects: none ** ** N.b., truncates path to MAX_PATH_LEN characters in length. ** ** Examples: ** ** input path input file name output path ** ---------- --------------- ----------- ** c:\ foo c:\foo ** c: foo c:foo ** c:\foo\bar\ goo c:\foo\bar\goo ** c:\foo\bar\ \goo c:\foo\bar\goo ** c:\foo\bar\ goo\shoe c:\foo\bar\goo\shoe ** c:\foo\bar\ \goo\shoe\ c:\foo\bar\goo\shoe\ ** foo\bar\ goo foo\bar\goo ** <empty string> <empty string> <empty string> ** <empty string> foo foo ** foo <empty string> foo ** fred bird fred\bird */ PUBLIC_CODE void CatPath(LPTSTR pszPath, LPCTSTR pcszSubPath, int cchMax) { LPTSTR pcsz; LPTSTR pcszLast;
ASSERT(IS_VALID_STRING_PTR(pszPath, STR)); ASSERT(IS_VALID_STRING_PTR(pcszSubPath, CSTR)); ASSERT(IS_VALID_WRITE_BUFFER_PTR(pszPath, STR, cchMax));
/* Find last character in path string. */
for (pcsz = pcszLast = pszPath; *pcsz; pcsz = CharNext(pcsz)) pcszLast = pcsz;
if (IS_SLASH(*pcszLast) && IS_SLASH(*pcszSubPath)) pcszSubPath++; else if (! IS_SLASH(*pcszLast) && ! IS_SLASH(*pcszSubPath)) { if (*pcszLast && *pcszLast != COLON && *pcszSubPath && ((lstrlen(pszPath) + 1) < cchMax)) *pcsz++ = TEXT('\\'); }
MyLStrCpyN(pcsz, pcszSubPath, cchMax - (int)(pcsz - pszPath));
ASSERT(IS_VALID_STRING_PTR(pszPath, STR));
return; }
/*
** MapIntToComparisonResult() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PUBLIC_CODE COMPARISONRESULT MapIntToComparisonResult(int nResult) { COMPARISONRESULT cr;
/* Any integer is valid input. */
if (nResult < 0) cr = CR_FIRST_SMALLER; else if (nResult > 0) cr = CR_FIRST_LARGER; else cr = CR_EQUAL;
return(cr); }
/*
** MyLStrCpyN() ** ** Like lstrcpyn(), but the copy is limited to ucb bytes. The destination ** string is always null-terminated. ** ** Arguments: pszDest - pointer to destination buffer ** pcszSrc - pointer to source string ** ncb - maximum number of bytes to copy, including null ** terminator ** ** Returns: void ** ** Side Effects: none ** ** N.b., this function behaves quite differently than strncpy()! It does not ** pad out the destination buffer with null characters, and it always null ** terminates the destination string. */ PUBLIC_CODE void MyLStrCpyN(LPTSTR pszDest, LPCTSTR pcszSrc, int ncch) { ASSERT(IS_VALID_WRITE_BUFFER_PTR(pszDest, STR, ncch * sizeof(TCHAR))); ASSERT(IS_VALID_STRING_PTR(pcszSrc, CSTR)); ASSERT(ncch > 0);
while (ncch > 1) { ncch--;
*pszDest = *pcszSrc;
if (*pcszSrc) { pszDest++; pcszSrc++; } else break; }
if (ncch == 1) *pszDest = TEXT('\0');
ASSERT(IS_VALID_STRING_PTR(pszDest, STR)); ASSERT(lstrlen(pszDest) < ncch); ASSERT(lstrlen(pszDest) <= lstrlen(pcszSrc));
return; }
#ifdef DEBUG
/*
** IsStringContained() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PUBLIC_CODE BOOL IsStringContained(LPCTSTR pcszBigger, LPCTSTR pcszSuffix) { ASSERT(IS_VALID_STRING_PTR(pcszBigger, CSTR)); ASSERT(IS_VALID_STRING_PTR(pcszSuffix, CSTR));
return(pcszSuffix >= pcszBigger && pcszSuffix <= pcszBigger + lstrlen(pcszBigger)); }
#endif
#if defined(_SYNCENG_) || defined(_LINKINFO_)
/*
** DeleteLastPathElement() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PUBLIC_CODE void DeleteLastPathElement(LPTSTR pszPath) { LPTSTR psz; LPTSTR pszLastSep;
ASSERT(IS_VALID_STRING_PTR(pszPath, STR));
psz = pszPath; pszLastSep = psz;
while (*psz) { if (*psz == TEXT('\\')) pszLastSep = psz;
psz = CharNext(psz); }
/*
* Now truncate the path at the last separator found, or the beginning of * the path if no path separators were found. */
*pszLastSep = TEXT('\0');
ASSERT(IS_VALID_STRING_PTR(pszPath, STR));
return; }
/*
** GetDefaultRegKeyValue() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PUBLIC_CODE LONG GetDefaultRegKeyValue(HKEY hkeyParent, LPCTSTR pcszSubKey, LPTSTR pszBuf, PDWORD pdwcbBufLen) { LONG lResult; HKEY hkeySubKey;
ASSERT(IS_VALID_HANDLE(hkeyParent, KEY)); ASSERT(IS_VALID_STRING_PTR(pcszSubKey, CSTR)); ASSERT(! pszBuf || IS_VALID_WRITE_BUFFER_PTR(pszBuf, STR, *pdwcbBufLen));
lResult = RegOpenKeyEx(hkeyParent, pcszSubKey, 0, KEY_QUERY_VALUE, &hkeySubKey);
if (lResult == ERROR_SUCCESS) { DWORD dwValueType;
lResult = RegQueryValueEx(hkeySubKey, NULL, NULL, &dwValueType, (PBYTE)pszBuf, pdwcbBufLen);
if (lResult == ERROR_SUCCESS) { ASSERT(dwValueType == REG_SZ); /* (+ 1) for null terminator. */ ASSERT(! pszBuf || (DWORD)(lstrlen(pszBuf) + 1) * sizeof(TCHAR) == *pdwcbBufLen);
TRACE_OUT((TEXT("GetDefaultRegKeyValue(): Default key value for subkey %s is \"%s\"."), pcszSubKey, pszBuf)); } else TRACE_OUT((TEXT("GetDefaultRegKeyValue(): RegQueryValueEx() for subkey %s failed, returning %ld."), pcszSubKey, lResult));
EVAL(RegCloseKey(hkeySubKey) == ERROR_SUCCESS); } else TRACE_OUT((TEXT("GetDefaultRegKeyValue(): RegOpenKeyEx() for subkey %s failed, returning %ld."), pcszSubKey, lResult));
return(lResult); }
/*
** StringCopy() ** ** ** ** Arguments: ** ** Returns: TWINRESULT ** ** Side Effects: none */ PUBLIC_CODE BOOL StringCopy(LPCTSTR pcszSrc, LPTSTR *ppszCopy) { BOOL bResult;
ASSERT(IS_VALID_STRING_PTR(pcszSrc, CSTR)); ASSERT(IS_VALID_WRITE_PTR(ppszCopy, LPTSTR));
/* (+ 1) for null terminator. */
bResult = AllocateMemory((lstrlen(pcszSrc) + 1) * sizeof(TCHAR), ppszCopy);
if (bResult) lstrcpy(*ppszCopy, pcszSrc); // allocated dynamically above
ASSERT(! bResult || IS_VALID_STRING_PTR(*ppszCopy, STR));
return(bResult); }
/*
** ComparePathStrings() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PUBLIC_CODE COMPARISONRESULT ComparePathStrings(LPCTSTR pcszFirst, LPCTSTR pcszSecond) { ASSERT(IS_VALID_STRING_PTR(pcszFirst, CSTR)); ASSERT(IS_VALID_STRING_PTR(pcszSecond, CSTR));
return(MapIntToComparisonResult(lstrcmpi(pcszFirst, pcszSecond))); }
/*
** MyStrChr() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PUBLIC_CODE BOOL MyStrChr(LPCTSTR pcsz, TCHAR chTarget, LPCTSTR *ppcszTarget) { LPCTSTR pcszFound;
ASSERT(IS_VALID_STRING_PTR(pcsz, CSTR)); ASSERT(! ppcszTarget || IS_VALID_WRITE_PTR(ppcszTarget, LPCTSTR));
/* This works correctly if chTarget is the null terminator '\0'. */
while (*pcsz && *pcsz != chTarget) pcsz = CharNext(pcsz);
if (*pcsz == chTarget) pcszFound = pcsz; else pcszFound = NULL;
if (ppcszTarget) *ppcszTarget = pcszFound;
return(pcszFound != NULL); }
/*
** PathExists() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PUBLIC_CODE BOOL PathExists(LPCTSTR pcszPath) { DWORD dwErrMode; BOOL fResult;
ASSERT(IS_VALID_STRING_PTR(pcszPath, CSTR));
dwErrMode = SetErrorMode(SEM_FAILCRITICALERRORS);
fResult = (GetFileAttributes(pcszPath) != -1);
SetErrorMode(dwErrMode);
return fResult; }
/*
** IsDrivePath() ** ** Determines whether or not a path is in "c:\" form. ** ** Arguments: pcszPath - path to examine ** ** Returns: TRUE if path is in "c:\" form. FALSE if not. ** ** Side Effects: none */ PUBLIC_CODE BOOL IsDrivePath(LPCTSTR pcszFullPath) { BOOL bResult;
ASSERT(IsFullPath(pcszFullPath));
if (lstrlen(pcszFullPath) >= 3 && IsCharAlpha(pcszFullPath[0]) && pcszFullPath[1] == COLON && IS_SLASH(pcszFullPath[2])) bResult = TRUE; else bResult = FALSE;
return(bResult); }
#if defined(DEBUG) || defined(VSTF)
/*
** IsValidDriveType() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PUBLIC_CODE BOOL IsValidDriveType(UINT uDriveType) { BOOL bResult;
switch (uDriveType) { case DRIVE_UNKNOWN: case DRIVE_NO_ROOT_DIR: case DRIVE_REMOVABLE: case DRIVE_FIXED: case DRIVE_REMOTE: case DRIVE_CDROM: case DRIVE_RAMDISK: bResult = TRUE; break;
default: ERROR_OUT((TEXT("IsValidDriveType(): Invalid drive type %u."), uDriveType)); bResult = FALSE; break; }
return(bResult); }
/*
** IsValidPathSuffix() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none ** ** A path suffix should not begin or end with a slash. */ PUBLIC_CODE BOOL IsValidPathSuffix(LPCTSTR pcszPathSuffix) { return(IS_VALID_STRING_PTR(pcszPathSuffix, CSTR) && EVAL(lstrlen(pcszPathSuffix) < MAX_PATH_LEN) && EVAL(! IS_SLASH(*pcszPathSuffix)) && EVAL(! IS_SLASH(*CharPrev(pcszPathSuffix, pcszPathSuffix + lstrlen(pcszPathSuffix))))); }
#endif /* DEBUG || VSTF */
#ifdef DEBUG
/*
** IsRootPath() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PUBLIC_CODE BOOL IsRootPath(LPCTSTR pcszFullPath) { TCHAR rgchCanonicalPath[MAX_PATH_LEN]; DWORD dwOutFlags; TCHAR rgchNetResource[MAX_PATH_LEN]; LPTSTR pszRootPathSuffix;
ASSERT(IsFullPath(pcszFullPath));
return(GetCanonicalPathInfo(pcszFullPath, rgchCanonicalPath, &dwOutFlags, rgchNetResource, &pszRootPathSuffix) && ! *pszRootPathSuffix); }
/*
** IsTrailingSlashCanonicalized() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PUBLIC_CODE BOOL IsTrailingSlashCanonicalized(LPCTSTR pcszFullPath) { BOOL bResult; BOOL bSlashLast; LPCTSTR pcszLastPathChar;
ASSERT(IsFullPath(pcszFullPath));
/* Make sure that the path only ends in a slash for root paths. */
pcszLastPathChar = CharPrev(pcszFullPath, pcszFullPath + lstrlen(pcszFullPath));
ASSERT(pcszLastPathChar >= pcszFullPath);
bSlashLast = IS_SLASH(*pcszLastPathChar);
/* Is this a root path? */
if (IsRootPath(pcszFullPath)) bResult = bSlashLast; else bResult = ! bSlashLast;
return(bResult); }
/*
** IsFullPath() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PUBLIC_CODE BOOL IsFullPath(LPCTSTR pcszPath) { BOOL bResult = FALSE; TCHAR rgchFullPath[MAX_PATH_LEN];
if (IS_VALID_STRING_PTR(pcszPath, CSTR) && EVAL(lstrlen(pcszPath) < MAX_PATH_LEN)) { DWORD dwPathLen; LPTSTR pszFileName;
dwPathLen = GetFullPathName(pcszPath, ARRAYSIZE(rgchFullPath), rgchFullPath, &pszFileName);
if (EVAL(dwPathLen > 0) && EVAL(dwPathLen < ARRAYSIZE(rgchFullPath))) bResult = EVAL(ComparePathStrings(pcszPath, rgchFullPath) == CR_EQUAL); }
return(bResult); }
/*
** IsCanonicalPath() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PUBLIC_CODE BOOL IsCanonicalPath(LPCTSTR pcszPath) { return(EVAL(IsFullPath(pcszPath)) && EVAL(IsTrailingSlashCanonicalized(pcszPath)));
}
/*
** IsValidCOMPARISONRESULT() ** ** ** ** Arguments: ** ** Returns: ** ** Side Effects: none */ PUBLIC_CODE BOOL IsValidCOMPARISONRESULT(COMPARISONRESULT cr) { BOOL bResult;
switch (cr) { case CR_FIRST_SMALLER: case CR_EQUAL: case CR_FIRST_LARGER: bResult = TRUE; break;
default: WARNING_OUT((TEXT("IsValidCOMPARISONRESULT(): Unknown COMPARISONRESULT %d."), cr)); bResult = FALSE; break; }
return(bResult); }
#endif /* DEBUG */
#endif /* _SYNCENG_ || _LINKINFO_ */
|