comc.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 13k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /*
  2.  * comc.c - Shared routines.
  3.  */
  4. /* Headers
  5.  **********/
  6. #include "project.h"
  7. #pragma hdrstop
  8. /****************************** Public Functions *****************************/
  9. /*
  10. ** CatPath()
  11. **
  12. ** Appends a filename to a path string.
  13. **
  14. ** Arguments:     pszPath - path string that file name is to be appended to
  15. **                pcszSubPath - path to append
  16. **
  17. ** Returns:       void
  18. **
  19. ** Side Effects:  none
  20. **
  21. ** N.b., truncates path to MAX_PATH_LEN characters in length.
  22. **
  23. ** Examples:
  24. **
  25. **    input path        input file name      output path
  26. **    ----------        ---------------      -----------
  27. **    c:               foo                  c:foo
  28. **    c:                foo                  c:foo
  29. **    c:foobar       goo                  c:foobargoo
  30. **    c:foobar       goo                 c:foobargoo
  31. **    c:foobar       gooshoe             c:foobargooshoe
  32. **    c:foobar       gooshoe           c:foobargooshoe
  33. **    foobar          goo                  foobargoo
  34. **    <empty string>    <empty string>       <empty string>
  35. **    <empty string>    foo                  foo
  36. **    foo               <empty string>       foo
  37. **    fred              bird                 fredbird
  38. */
  39. PUBLIC_CODE void CatPath(LPTSTR pszPath, LPCTSTR pcszSubPath)
  40. {
  41.    LPTSTR pcsz;
  42.    LPTSTR pcszLast;
  43.    ASSERT(IS_VALID_STRING_PTR(pszPath, STR));
  44.    ASSERT(IS_VALID_STRING_PTR(pcszSubPath, CSTR));
  45.    ASSERT(IS_VALID_WRITE_BUFFER_PTR(pszPath, STR, MAX_PATH_LEN - lstrlen(pszPath)));
  46.    /* Find last character in path string. */
  47.    for (pcsz = pcszLast = pszPath; *pcsz; pcsz = CharNext(pcsz))
  48.       pcszLast = pcsz;
  49.    if (IS_SLASH(*pcszLast) && IS_SLASH(*pcszSubPath))
  50.       pcszSubPath++;
  51.    else if (! IS_SLASH(*pcszLast) && ! IS_SLASH(*pcszSubPath))
  52.    {
  53.       if (*pcszLast && *pcszLast != COLON && *pcszSubPath)
  54.          *pcsz++ = TEXT('\');
  55.    }
  56.    MyLStrCpyN(pcsz, pcszSubPath, MAX_PATH_LEN - (int)(pcsz - pszPath));
  57.    ASSERT(IS_VALID_STRING_PTR(pszPath, STR));
  58.    return;
  59. }
  60. /*
  61. ** MapIntToComparisonResult()
  62. **
  63. **
  64. **
  65. ** Arguments:
  66. **
  67. ** Returns:
  68. **
  69. ** Side Effects:  none
  70. */
  71. PUBLIC_CODE COMPARISONRESULT MapIntToComparisonResult(int nResult)
  72. {
  73.    COMPARISONRESULT cr;
  74.    /* Any integer is valid input. */
  75.    if (nResult < 0)
  76.       cr = CR_FIRST_SMALLER;
  77.    else if (nResult > 0)
  78.       cr = CR_FIRST_LARGER;
  79.    else
  80.       cr = CR_EQUAL;
  81.    return(cr);
  82. }
  83. /*
  84. ** MyLStrCpyN()
  85. **
  86. ** Like lstrcpy(), but the copy is limited to ucb bytes.  The destination
  87. ** string is always null-terminated.
  88. **
  89. ** Arguments:     pszDest - pointer to destination buffer
  90. **                pcszSrc - pointer to source string
  91. **                ncb - maximum number of bytes to copy, including null
  92. **                      terminator
  93. **
  94. ** Returns:       void
  95. **
  96. ** Side Effects:  none
  97. **
  98. ** N.b., this function behaves quite differently than strncpy()!  It does not
  99. ** pad out the destination buffer with null characters, and it always null
  100. ** terminates the destination string.
  101. */
  102. PUBLIC_CODE void MyLStrCpyN(LPTSTR pszDest, LPCTSTR pcszSrc, int ncch)
  103. {
  104.    ASSERT(IS_VALID_WRITE_BUFFER_PTR(pszDest, STR, ncch * sizeof(TCHAR)));
  105.    ASSERT(IS_VALID_STRING_PTR(pcszSrc, CSTR));
  106.    ASSERT(ncch > 0);
  107.    while (ncch > 1)
  108.    {
  109.       ncch--;
  110.       *pszDest = *pcszSrc;
  111.       if (*pcszSrc)
  112.       {
  113.          pszDest++;
  114.          pcszSrc++;
  115.       }
  116.       else
  117.          break;
  118.    }
  119.    if (ncch == 1)
  120.       *pszDest = TEXT('');
  121.    ASSERT(IS_VALID_STRING_PTR(pszDest, STR));
  122.    ASSERT(lstrlen(pszDest) < ncch);
  123.    ASSERT(lstrlen(pszDest) <= lstrlen(pcszSrc));
  124.    return;
  125. }
  126. #ifdef DEBUG
  127. /*
  128. ** IsStringContained()
  129. **
  130. **
  131. **
  132. ** Arguments:
  133. **
  134. ** Returns:
  135. **
  136. ** Side Effects:  none
  137. */
  138. PUBLIC_CODE BOOL IsStringContained(LPCTSTR pcszBigger, LPCTSTR pcszSuffix)
  139. {
  140.    ASSERT(IS_VALID_STRING_PTR(pcszBigger, CSTR));
  141.    ASSERT(IS_VALID_STRING_PTR(pcszSuffix, CSTR));
  142.    return(pcszSuffix >= pcszBigger &&
  143.           pcszSuffix <= pcszBigger + lstrlen(pcszBigger));
  144. }
  145. #endif
  146. #if defined(_SYNCENG_) || defined(_LINKINFO_)
  147. /*
  148. ** DeleteLastPathElement()
  149. **
  150. **
  151. **
  152. ** Arguments:
  153. **
  154. ** Returns:
  155. **
  156. ** Side Effects:  none
  157. */
  158. PUBLIC_CODE void DeleteLastPathElement(LPTSTR pszPath)
  159. {
  160.    LPTSTR psz;
  161.    LPTSTR pszLastSep;
  162.    ASSERT(IS_VALID_STRING_PTR(pszPath, STR));
  163.    psz = pszPath;
  164.    pszLastSep = psz;
  165.    while (*psz)
  166.    {
  167.       if (*psz == TEXT('\'))
  168.          pszLastSep = psz;
  169.       psz = CharNext(psz);
  170.    }
  171.    /*
  172.     * Now truncate the path at the last separator found, or the beginning of
  173.     * the path if no path separators were found.
  174.     */
  175.    *pszLastSep = TEXT('');
  176.    ASSERT(IS_VALID_STRING_PTR(pszPath, STR));
  177.    return;
  178. }
  179. /*
  180. ** GetDefaultRegKeyValue()
  181. **
  182. **
  183. **
  184. ** Arguments:
  185. **
  186. ** Returns:
  187. **
  188. ** Side Effects:  none
  189. */
  190. PUBLIC_CODE LONG GetDefaultRegKeyValue(HKEY hkeyParent, LPCTSTR pcszSubKey,
  191.                                   LPTSTR pszBuf, PDWORD pdwcbBufLen)
  192. {
  193.    LONG lResult;
  194.    HKEY hkeySubKey;
  195.    ASSERT(IS_VALID_HANDLE(hkeyParent, KEY));
  196.    ASSERT(IS_VALID_STRING_PTR(pcszSubKey, CSTR));
  197.    ASSERT(! pszBuf ||
  198.           IS_VALID_WRITE_BUFFER_PTR(pszBuf, STR, *pdwcbBufLen));
  199.    lResult = RegOpenKeyEx(hkeyParent, pcszSubKey, 0, KEY_QUERY_VALUE,
  200.                           &hkeySubKey);
  201.    if (lResult == ERROR_SUCCESS)
  202.    {
  203.       DWORD dwValueType;
  204.       lResult = RegQueryValueEx(hkeySubKey, NULL, NULL, &dwValueType,
  205.                                 (PBYTE)pszBuf, pdwcbBufLen);
  206.       if (lResult == ERROR_SUCCESS)
  207.       {
  208.          ASSERT(dwValueType == REG_SZ);
  209.          /* (+ 1) for null terminator. */
  210.          ASSERT(! pszBuf ||
  211.                 (DWORD)(lstrlen(pszBuf) + 1) * sizeof(TCHAR) == *pdwcbBufLen);
  212.          TRACE_OUT((TEXT("GetDefaultRegKeyValue(): Default key value for subkey %s is "%s"."),
  213.                     pcszSubKey,
  214.                     pszBuf));
  215.       }
  216.       else
  217.          TRACE_OUT((TEXT("GetDefaultRegKeyValue(): RegQueryValueEx() for subkey %s failed, returning %ld."),
  218.                     pcszSubKey,
  219.                     lResult));
  220.       EVAL(RegCloseKey(hkeySubKey) == ERROR_SUCCESS);
  221.    }
  222.    else
  223.       TRACE_OUT((TEXT("GetDefaultRegKeyValue(): RegOpenKeyEx() for subkey %s failed, returning %ld."),
  224.                  pcszSubKey,
  225.                  lResult));
  226.    return(lResult);
  227. }
  228. /*
  229. ** StringCopy()
  230. **
  231. **
  232. **
  233. ** Arguments:
  234. **
  235. ** Returns:       TWINRESULT
  236. **
  237. ** Side Effects:  none
  238. */
  239. PUBLIC_CODE BOOL StringCopy(LPCTSTR pcszSrc, LPTSTR *ppszCopy)
  240. {
  241.    BOOL bResult;
  242.    ASSERT(IS_VALID_STRING_PTR(pcszSrc, CSTR));
  243.    ASSERT(IS_VALID_WRITE_PTR(ppszCopy, LPTSTR));
  244.    /* (+ 1) for null terminator. */
  245.    bResult = AllocateMemory((lstrlen(pcszSrc) + 1) * sizeof(TCHAR), ppszCopy);
  246.    if (bResult)
  247.       lstrcpy(*ppszCopy, pcszSrc);
  248.    ASSERT(! bResult ||
  249.           IS_VALID_STRING_PTR(*ppszCopy, STR));
  250.    return(bResult);
  251. }
  252. /*
  253. ** ComparePathStrings()
  254. **
  255. **
  256. **
  257. ** Arguments:
  258. **
  259. ** Returns:
  260. **
  261. ** Side Effects:  none
  262. */
  263. PUBLIC_CODE COMPARISONRESULT ComparePathStrings(LPCTSTR pcszFirst, LPCTSTR pcszSecond)
  264. {
  265.    ASSERT(IS_VALID_STRING_PTR(pcszFirst, CSTR));
  266.    ASSERT(IS_VALID_STRING_PTR(pcszSecond, CSTR));
  267.    return(MapIntToComparisonResult(lstrcmpi(pcszFirst, pcszSecond)));
  268. }
  269. /*
  270. ** MyStrChr()
  271. **
  272. **
  273. **
  274. ** Arguments:
  275. **
  276. ** Returns:
  277. **
  278. ** Side Effects:  none
  279. */
  280. PUBLIC_CODE BOOL MyStrChr(LPCTSTR pcsz, TCHAR chTarget, LPCTSTR *ppcszTarget)
  281. {
  282.    LPCTSTR pcszFound;
  283.    ASSERT(IS_VALID_STRING_PTR(pcsz, CSTR));
  284.    ASSERT(! ppcszTarget || IS_VALID_WRITE_PTR(ppcszTarget, LPCTSTR));
  285.    /* This works correctly if chTarget is the null terminator ''. */
  286.    while (*pcsz && *pcsz != chTarget)
  287.       pcsz = CharNext(pcsz);
  288.    if (*pcsz == chTarget)
  289.       pcszFound = pcsz;
  290.    else
  291.       pcszFound = NULL;
  292.    if (ppcszTarget)
  293.       *ppcszTarget = pcszFound;
  294.    return(pcszFound != NULL);
  295. }
  296. /*
  297. ** PathExists()
  298. **
  299. **
  300. **
  301. ** Arguments:
  302. **
  303. ** Returns:
  304. **
  305. ** Side Effects:  none
  306. */
  307. PUBLIC_CODE BOOL PathExists(LPCTSTR pcszPath)
  308. {
  309.    DWORD dwErrMode;
  310.    BOOL fResult;
  311.    ASSERT(IS_VALID_STRING_PTR(pcszPath, CSTR));
  312.    dwErrMode = SetErrorMode(SEM_FAILCRITICALERRORS);
  313.    fResult = (GetFileAttributes(pcszPath) != -1);
  314.    SetErrorMode(dwErrMode);
  315.    return fResult;
  316. }
  317. /*
  318. ** IsDrivePath()
  319. **
  320. ** Determines whether or not a path is in "c:" form.
  321. **
  322. ** Arguments:     pcszPath - path to examine
  323. **
  324. ** Returns:       TRUE if path is in "c:" form.  FALSE if not.
  325. **
  326. ** Side Effects:  none
  327. */
  328. PUBLIC_CODE BOOL IsDrivePath(LPCTSTR pcszFullPath)
  329. {
  330.    BOOL bResult;
  331.    ASSERT(IsFullPath(pcszFullPath));
  332.    if (lstrlen(pcszFullPath) >= 3 &&
  333.        IsCharAlpha(pcszFullPath[0]) &&
  334.        pcszFullPath[1] == COLON &&
  335.        IS_SLASH(pcszFullPath[2]))
  336.       bResult = TRUE;
  337.    else
  338.       bResult = FALSE;
  339.    return(bResult);
  340. }
  341. #if defined(DEBUG) || defined(VSTF)
  342. /*
  343. ** IsValidDriveType()
  344. **
  345. **
  346. **
  347. ** Arguments:
  348. **
  349. ** Returns:
  350. **
  351. ** Side Effects:  none
  352. */
  353. PUBLIC_CODE BOOL IsValidDriveType(UINT uDriveType)
  354. {
  355.    BOOL bResult;
  356.    switch (uDriveType)
  357.    {
  358.       case DRIVE_UNKNOWN:
  359.       case DRIVE_NO_ROOT_DIR:
  360.       case DRIVE_REMOVABLE:
  361.       case DRIVE_FIXED:
  362.       case DRIVE_REMOTE:
  363.       case DRIVE_CDROM:
  364.       case DRIVE_RAMDISK:
  365.          bResult = TRUE;
  366.          break;
  367.       default:
  368.          ERROR_OUT((TEXT("IsValidDriveType(): Invalid drive type %u."),
  369.                     uDriveType));
  370.          bResult = FALSE;
  371.          break;
  372.    }
  373.    return(bResult);
  374. }
  375. /*
  376. ** IsValidPathSuffix()
  377. **
  378. **
  379. **
  380. ** Arguments:
  381. **
  382. ** Returns:
  383. **
  384. ** Side Effects:  none
  385. **
  386. ** A path suffix should not begin or end with a slash.
  387. */
  388. PUBLIC_CODE BOOL IsValidPathSuffix(LPCTSTR pcszPathSuffix)
  389. {
  390.    return(IS_VALID_STRING_PTR(pcszPathSuffix, CSTR) &&
  391.           EVAL(lstrlen(pcszPathSuffix) < MAX_PATH_LEN) &&
  392.           EVAL(! IS_SLASH(*pcszPathSuffix)) &&
  393.           EVAL(! IS_SLASH(*CharPrev(pcszPathSuffix, pcszPathSuffix + lstrlen(pcszPathSuffix)))));
  394. }
  395. #endif   /* DEBUG || VSTF */
  396. #ifdef DEBUG
  397. /*
  398. ** IsRootPath()
  399. **
  400. **
  401. **
  402. ** Arguments:
  403. **
  404. ** Returns:
  405. **
  406. ** Side Effects:  none
  407. */
  408. PUBLIC_CODE BOOL IsRootPath(LPCTSTR pcszFullPath)
  409. {
  410.    TCHAR rgchCanonicalPath[MAX_PATH_LEN];
  411.    DWORD dwOutFlags;
  412.    TCHAR rgchNetResource[MAX_PATH_LEN];
  413.    LPTSTR pszRootPathSuffix;
  414.    ASSERT(IsFullPath(pcszFullPath));
  415.    return(GetCanonicalPathInfo(pcszFullPath, rgchCanonicalPath, &dwOutFlags,
  416.                                rgchNetResource, &pszRootPathSuffix) &&
  417.           ! *pszRootPathSuffix);
  418. }
  419. /*
  420. ** IsTrailingSlashCanonicalized()
  421. **
  422. **
  423. **
  424. ** Arguments:
  425. **
  426. ** Returns:
  427. **
  428. ** Side Effects:  none
  429. */
  430. PUBLIC_CODE BOOL IsTrailingSlashCanonicalized(LPCTSTR pcszFullPath)
  431. {
  432.    BOOL bResult;
  433.    BOOL bSlashLast;
  434.    LPCTSTR pcszLastPathChar;
  435.    ASSERT(IsFullPath(pcszFullPath));
  436.    /* Make sure that the path only ends in a slash for root paths. */
  437.    pcszLastPathChar = CharPrev(pcszFullPath, pcszFullPath + lstrlen(pcszFullPath));
  438.    ASSERT(pcszLastPathChar >= pcszFullPath);
  439.    bSlashLast = IS_SLASH(*pcszLastPathChar);
  440.    /* Is this a root path? */
  441.    if (IsRootPath(pcszFullPath))
  442.       bResult = bSlashLast;
  443.    else
  444.       bResult = ! bSlashLast;
  445.    return(bResult);
  446. }
  447. /*
  448. ** IsFullPath()
  449. **
  450. **
  451. **
  452. ** Arguments:
  453. **
  454. ** Returns:
  455. **
  456. ** Side Effects:  none
  457. */
  458. PUBLIC_CODE BOOL IsFullPath(LPCTSTR pcszPath)
  459. {
  460.    BOOL bResult = FALSE;
  461.    TCHAR rgchFullPath[MAX_PATH_LEN];
  462.    if (IS_VALID_STRING_PTR(pcszPath, CSTR) &&
  463.        EVAL(lstrlen(pcszPath) < MAX_PATH_LEN))
  464.    {
  465.       DWORD dwPathLen;
  466.       LPTSTR pszFileName;
  467.       dwPathLen = GetFullPathName(pcszPath, ARRAYSIZE(rgchFullPath), rgchFullPath,
  468.                                   &pszFileName);
  469.       if (EVAL(dwPathLen > 0) &&
  470.           EVAL(dwPathLen < ARRAYSIZE(rgchFullPath)))
  471.          bResult = EVAL(ComparePathStrings(pcszPath, rgchFullPath) == CR_EQUAL);
  472.    }
  473.    return(bResult);
  474. }
  475. /*
  476. ** IsCanonicalPath()
  477. **
  478. **
  479. **
  480. ** Arguments:
  481. **
  482. ** Returns:
  483. **
  484. ** Side Effects:  none
  485. */
  486. PUBLIC_CODE BOOL IsCanonicalPath(LPCTSTR pcszPath)
  487. {
  488.    return(EVAL(IsFullPath(pcszPath)) &&
  489.           EVAL(IsTrailingSlashCanonicalized(pcszPath)));
  490. }
  491. /*
  492. ** IsValidCOMPARISONRESULT()
  493. **
  494. **
  495. **
  496. ** Arguments:
  497. **
  498. ** Returns:
  499. **
  500. ** Side Effects:  none
  501. */
  502. PUBLIC_CODE BOOL IsValidCOMPARISONRESULT(COMPARISONRESULT cr)
  503. {
  504.    BOOL bResult;
  505.    switch (cr)
  506.    {
  507.       case CR_FIRST_SMALLER:
  508.       case CR_EQUAL:
  509.       case CR_FIRST_LARGER:
  510.          bResult = TRUE;
  511.          break;
  512.       default:
  513.          WARNING_OUT((TEXT("IsValidCOMPARISONRESULT(): Unknown COMPARISONRESULT %d."),
  514.                       cr));
  515.          bResult = FALSE;
  516.          break;
  517.    }
  518.    return(bResult);
  519. }
  520. #endif   /* DEBUG */
  521. #endif   /* _SYNCENG_ || _LINKINFO_ */