Leaked source code of windows server 2003
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.

696 lines
23 KiB

  1. /*++
  2. Copyright (c) 1994-1999 Microsoft Corporation
  3. Module Name :
  4. strvalid.cpp
  5. Abstract:
  6. String Functions
  7. Author:
  8. Aaron Lee (aaronl)
  9. Project:
  10. Internet Services Manager
  11. Revision History:
  12. --*/
  13. //
  14. // Include Files
  15. //
  16. #include "stdafx.h"
  17. #include "common.h"
  18. #include "iisdebug.h"
  19. #include <pudebug.h>
  20. #ifdef _DEBUG
  21. #undef THIS_FILE
  22. static char BASED_CODE THIS_FILE[] = __FILE__;
  23. #endif
  24. #define new DEBUG_NEW
  25. //
  26. // Procedure removes all characters in the second string from the first one.
  27. //
  28. INT RemoveChars(LPTSTR pszStr,LPTSTR pszRemoved)
  29. {
  30. INT iCharsRemovedCount = 0;
  31. INT iOrgStringLength = _tcslen(pszStr);
  32. INT cbRemoved = _tcslen(pszRemoved);
  33. INT iSrc, iDest;
  34. for (iSrc = iDest = 0; pszStr[iSrc]; iSrc++, iDest++)
  35. {
  36. // Check if this char is the in the list of stuf
  37. // we are supposed to remove.
  38. // if it is then just set iSrc to iSrc +1
  39. #ifdef UNICODE
  40. while (wmemchr(pszRemoved, pszStr[iSrc], cbRemoved))
  41. #else
  42. while (memchr(pszRemoved, pszStr[iSrc], cbRemoved))
  43. #endif
  44. {
  45. iCharsRemovedCount++;
  46. iSrc++;
  47. }
  48. // copy the character to itself
  49. pszStr[iDest] = pszStr[iSrc];
  50. }
  51. // Cut off the left over strings
  52. // which we didn't erase. but need to.
  53. if (iCharsRemovedCount >= 0){pszStr[iOrgStringLength - iCharsRemovedCount]= '\0';}
  54. return iDest - 1;
  55. }
  56. BOOL IsContainInvalidChars(LPCTSTR szUncOrDirOrFilePart,LPCTSTR szListOfInvalidChars)
  57. {
  58. LPTSTR psz = (LPTSTR) szUncOrDirOrFilePart;
  59. if (NULL == psz)
  60. return FALSE;
  61. if (NULL == szListOfInvalidChars)
  62. return FALSE;
  63. while (*psz)
  64. {
  65. // Check if this characters is in the "bad" set.
  66. if (_tcschr(szListOfInvalidChars,*psz))
  67. {
  68. DebugTrace(_T("Path:Contains bad character '%c'"),*psz);
  69. return TRUE;
  70. }
  71. psz = ::CharNext(psz);
  72. }
  73. return FALSE;
  74. }
  75. // This character set is invalid for:
  76. // 1. Anything in a UNC path (includes servername,servershare,path,dir)
  77. // 2. Anything in the dir part of the path (doesn't include drive part -- obviously c: -- includes a colon)
  78. // 3. Anything in the filepart of the path
  79. BOOL IsContainInvalidChars(LPCTSTR szUncOrDirOrFilePart)
  80. {
  81. return IsContainInvalidChars(szUncOrDirOrFilePart,_T(":|<>/*?\t\r\n"));
  82. }
  83. BOOL IsContainInvalidCharsUNC(LPCTSTR lpFullFileNamePath)
  84. {
  85. return IsContainInvalidChars(lpFullFileNamePath);
  86. }
  87. BOOL IsContainInvalidCharsAfterDrivePart(LPCTSTR lpFullFileNamePath)
  88. {
  89. TCHAR szPath_only[_MAX_PATH];
  90. _tsplitpath(lpFullFileNamePath, NULL, szPath_only, NULL, NULL);
  91. if (szPath_only)
  92. {
  93. return IsContainInvalidChars(szPath_only);
  94. }
  95. return FALSE;
  96. }
  97. BOOL IsContainInvalidCharsFilePart(LPCTSTR szFilenameOnly)
  98. {
  99. return IsContainInvalidChars(szFilenameOnly);
  100. }
  101. BOOL IsDirPartExist(LPCTSTR lpFullFileNamePath)
  102. {
  103. TCHAR szDrive_only[_MAX_DRIVE];
  104. TCHAR szPath_only[_MAX_PATH];
  105. TCHAR szTemp[_MAX_PATH];
  106. _tsplitpath(lpFullFileNamePath, szDrive_only, szPath_only, NULL, NULL);
  107. // Get the Dirpart and see if it exists
  108. _tcscpy(szTemp,szDrive_only);
  109. _tcscat(szTemp,szPath_only);
  110. // Check if it's a directory
  111. if (PathIsDirectory(szTemp))
  112. {
  113. // it's an existing valid directory.
  114. return TRUE;
  115. }
  116. return FALSE;
  117. }
  118. // bForFullFilePath = TRUE, if for something like \\servername\servershare\mydir\myfile.txt
  119. // bForFullFilePath = FALSE, if for something like \\servername\servershare\mydir
  120. BOOL IsValidUNCSpecialCases(LPCTSTR path,BOOL bLocal,BOOL bForFullFilePath)
  121. {
  122. BOOL bReturn = TRUE;
  123. CString csPathMunged = path;
  124. TCHAR * pszRoot = NULL;
  125. if (!PathIsUNC(csPathMunged))
  126. {
  127. bReturn = FALSE;
  128. goto IsValidUNCSpecialCases_Exit;
  129. }
  130. if (PathIsUNCServer(csPathMunged))
  131. {
  132. bReturn = TRUE;
  133. goto IsValidUNCSpecialCases_Exit;
  134. }
  135. if (PathIsUNCServerShare(csPathMunged))
  136. {
  137. bReturn = TRUE;
  138. goto IsValidUNCSpecialCases_Exit;
  139. }
  140. // From this point on.
  141. // it is likely
  142. // \\servername\servershare\somepath
  143. // \\servername\servershare\somepath\somefilename.txt
  144. // looking for an invalid UNC...
  145. // Test for something lame like \\servername\\dir
  146. // add enough space for an extra "\" at the beginning.
  147. pszRoot = (TCHAR *) LocalAlloc(LPTR, ((_tcslen(csPathMunged)+2) * sizeof(TCHAR)));
  148. if (pszRoot)
  149. {
  150. // Add an extra "\" at the beginning.
  151. _tcscpy(pszRoot,_T("\\"));
  152. _tcscat(pszRoot,csPathMunged);
  153. // for some reason a UNC like this: \\\servername\dir
  154. // will be valid for PathIsUNCServer.
  155. // but a UNC like this: \\\\servername\dir will be invalid
  156. // we want to ensure that \\\servername\dir is invalid
  157. // that's why we added an extra "\"
  158. if (PathStripToRoot(pszRoot))
  159. {
  160. // if we get back just the \\server name
  161. // then we have an invalid path.
  162. // we're supposed to get back \\servername\servershare
  163. if (PathIsUNCServer(pszRoot))
  164. {
  165. bReturn = FALSE;
  166. DebugTrace(_T("Path:Bad UNC path"));
  167. goto IsValidUNCSpecialCases_Exit;
  168. }
  169. }
  170. // We have \\servername\Servershare now...
  171. if (bForFullFilePath)
  172. {
  173. // set it back to the real path without the extra "\"
  174. _tcscpy(pszRoot,csPathMunged);
  175. if (PathStripToRoot(pszRoot))
  176. {
  177. // if we get back just the \\server name
  178. // then we have an invalid path.
  179. // we're supposed to get back \\servername\servershare
  180. if (PathIsUNCServer(pszRoot))
  181. {
  182. bReturn = FALSE;
  183. DebugTrace(_T("Path:Bad UNC path"));
  184. goto IsValidUNCSpecialCases_Exit;
  185. }
  186. else
  187. {
  188. _tcscpy(pszRoot,csPathMunged);
  189. // it's a sharename.
  190. // let's check if that is valid even...
  191. TCHAR * pszAfterRoot = NULL;
  192. pszAfterRoot = PathSkipRoot(pszRoot);
  193. if (pszAfterRoot)
  194. {
  195. if (0 == _tcslen(pszAfterRoot))
  196. {
  197. if (bForFullFilePath)
  198. {
  199. // don't accept something like "\\servername\fileshare\"
  200. bReturn = FALSE;
  201. DebugTrace(_T("Path:Bad UNC path:no accept \\\\s\\f\\ (ending slash)"));
  202. goto IsValidUNCSpecialCases_Exit;
  203. }
  204. }
  205. else if (0 == _tcsicmp(pszAfterRoot,_T(".")))
  206. {
  207. // don't accept something like "\\servername\fileshare\."
  208. bReturn = FALSE;
  209. DebugTrace(_T("Path:Bad UNC path:no accept \\\\s\\f\\."));
  210. goto IsValidUNCSpecialCases_Exit;
  211. }
  212. else
  213. {
  214. // otherwise it's probably
  215. // \\servername\servershare\somedir
  216. // \\servername\servershare\somedir\somefilename.txt
  217. }
  218. }
  219. }
  220. }
  221. }
  222. }
  223. IsValidUNCSpecialCases_Exit:
  224. if (pszRoot){LocalFree(pszRoot);}
  225. return bReturn;
  226. }
  227. // return 0 on success
  228. // error code on failure
  229. FILERESULT MyValidatePath(LPCTSTR path,BOOL bLocal,INT iPathTypeWanted,DWORD dwAllowedFlags,DWORD dwCharSetFlags)
  230. {
  231. FILERESULT dwReturn = SEVERITY_SUCCESS;
  232. CString csPathMunged = path;
  233. CComBSTR bstrTempString;
  234. // verify all parameters are filled in...
  235. if (iPathTypeWanted != CHKPATH_WANT_FILE && iPathTypeWanted != CHKPATH_WANT_DIR)
  236. {
  237. return E_INVALIDARG;
  238. }
  239. if (dwAllowedFlags > CHKPATH_ALLOW_MAX)
  240. {
  241. return E_INVALIDARG;
  242. }
  243. if (dwCharSetFlags < CHKPATH_CHARSET_GENERAL || dwCharSetFlags > CHKPATH_CHARSET_MAX)
  244. {
  245. return E_INVALIDARG;
  246. }
  247. // ------------
  248. // length check
  249. // ------------
  250. {
  251. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_INVALID_LENGTH,CHKPATH_FAIL_INVALID_EMPTY);
  252. // check if it's empty
  253. if (path == NULL || *path == 0)
  254. {
  255. dwReturn |= CHKPATH_FAIL_INVALID_EMPTY;
  256. DebugTrace(_T("Path:Empty"));
  257. goto MyValidatePath_Exit;
  258. }
  259. // check if it's empty
  260. if (0 == _tcslen(path))
  261. {
  262. dwReturn |= CHKPATH_FAIL_INVALID_EMPTY;
  263. DebugTrace(_T("Path:Empty"));
  264. goto MyValidatePath_Exit;
  265. }
  266. // check length
  267. if (_tcslen(path) >= 256)
  268. {
  269. dwReturn |= CHKPATH_FAIL_INVALID_TOO_LONG;
  270. // it's empty, please specify something!
  271. DebugTrace(_T("Path:too long"));
  272. goto MyValidatePath_Exit;
  273. }
  274. // length check passes
  275. dwReturn = SEVERITY_SUCCESS;
  276. }
  277. // ------------------------
  278. // Invalid characters check
  279. // ------------------------
  280. {
  281. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_INVALID_CHARSET,CHKPATH_FAIL_INVALID_CHARSET_GENERAL);
  282. // check for invalid characters...
  283. bstrTempString = _T("\t\r\n");
  284. if (IS_FLAG_SET(dwCharSetFlags,CHKPATH_CHARSET_GENERAL))
  285. {
  286. bstrTempString = CHKPATH_INVALID_CHARSET_GENERAL;
  287. }
  288. if (IS_FLAG_SET(dwCharSetFlags,CHKPATH_CHARSET_GENERAL_NO_COMMA))
  289. {
  290. // user wants to make sure that comma is an invalid entry
  291. bstrTempString = bstrTempString + CHKPATH_INVALID_CHARSET_COMMA;
  292. }
  293. if (IS_FLAG_SET(dwCharSetFlags,CHKPATH_CHARSET_GENERAL_ALLOW_QUESTION))
  294. {
  295. // user wants to allow Question marks...
  296. RemoveChars((LPTSTR) bstrTempString,CHKPATH_INVALID_CHARSET_QUESTION);
  297. }
  298. if (IsContainInvalidChars(path,bstrTempString))
  299. {
  300. dwReturn |= CHKPATH_FAIL_INVALID_CHARSET_GENERAL;
  301. DebugTrace(_T("Path:invalid chars"));
  302. goto MyValidatePath_Exit;
  303. }
  304. // invalid chars check passes
  305. dwReturn = SEVERITY_SUCCESS;
  306. }
  307. // -------------------------------------------------------------
  308. // Before we do anything we need to see if it's a "special" path
  309. //
  310. // Everything after this function must validate against csPathMunged...
  311. // this is because GetSpecialPathRealPath could have munged it...
  312. // -------------------------------------------------------------
  313. csPathMunged = path;
  314. #ifdef SUPPORT_SLASH_SLASH_QUESTIONMARK_SLASH_TYPE_PATHS
  315. GetSpecialPathRealPath(0,path,csPathMunged);
  316. #endif
  317. // ------------------------
  318. // Do we allow device type paths
  319. // \\.\myfile.txt
  320. // ------------------------
  321. if (IsDevicePath(csPathMunged))
  322. {
  323. if (IS_FLAG_SET(dwAllowedFlags,CHKPATH_ALLOW_DEVICE_PATH))
  324. {
  325. // user allows device path
  326. // Do we want to verify it further??
  327. dwReturn = SEVERITY_SUCCESS;
  328. DebugTrace(_T("Path:accept device path"));
  329. }
  330. else
  331. {
  332. // user won't allow device path
  333. // so return failure
  334. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_NOT_ALLOWED,CHKPATH_FAIL_NOT_ALLOWED_DEVICE_PATH);
  335. DebugTrace(_T("Path:no accept device path"));
  336. }
  337. goto MyValidatePath_Exit;
  338. }
  339. // ------------------------
  340. // Do we allow device relative paths
  341. // ..\testing\test.txt
  342. // ------------------------
  343. if (PathIsRelative(csPathMunged))
  344. {
  345. if (IS_FLAG_SET(dwAllowedFlags,CHKPATH_ALLOW_RELATIVE_PATH))
  346. {
  347. // we have a relative path...
  348. // Check to see if it is valid...
  349. // BUGBUG:aaronl: do more work here...
  350. dwReturn = SEVERITY_SUCCESS;
  351. DebugTrace(_T("Path:accept relative path"));
  352. }
  353. else
  354. {
  355. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_NOT_ALLOWED,CHKPATH_FAIL_NOT_ALLOWED_RELATIVE_PATH);
  356. DebugTrace(_T("Path:no accept relative path"));
  357. }
  358. goto MyValidatePath_Exit;
  359. }
  360. // -------------------------------------------------------------
  361. // UNC Validation
  362. // -------------------------------------------------------------
  363. if (PathIsUNC(csPathMunged))
  364. {
  365. // ------------------------
  366. // Do we allow UNC type paths at all?
  367. // \\servername
  368. // \\servername\servershare
  369. // \\servername\servershare\dir
  370. // \\servername\servershare\dir\filename.txt
  371. // ------------------------
  372. if (!IS_FLAG_SET(dwAllowedFlags,CHKPATH_ALLOW_UNC_PATH))
  373. {
  374. // We are not allowing UNC paths...
  375. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_NOT_ALLOWED,CHKPATH_FAIL_NOT_ALLOWED_UNC_PATH);
  376. DebugTrace(_T("Path:no accept UNC path"));
  377. goto MyValidatePath_Exit;
  378. }
  379. // ------------------------
  380. // Do we allow servername only?
  381. // \\servername
  382. // ------------------------
  383. if (PathIsUNCServer(csPathMunged))
  384. {
  385. if (IS_FLAG_SET(dwAllowedFlags,CHKPATH_ALLOW_UNC_SERVERNAME_ONLY))
  386. {
  387. dwReturn = SEVERITY_SUCCESS;
  388. DebugTrace(_T("Path:accept only servername"));
  389. }
  390. else
  391. {
  392. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_NOT_ALLOWED,CHKPATH_FAIL_NOT_ALLOWED_UNC_SERVERNAME);
  393. DebugTrace(_T("Path:no accept only servername"));
  394. }
  395. goto MyValidatePath_Exit;
  396. }
  397. // ------------------------
  398. // Do we allow servershare only?
  399. // \\servername\servershare
  400. // ------------------------
  401. if (PathIsUNCServerShare(csPathMunged))
  402. {
  403. if (IS_FLAG_SET(dwAllowedFlags,CHKPATH_ALLOW_UNC_SERVERSHARE_ONLY))
  404. {
  405. dwReturn = SEVERITY_SUCCESS;
  406. DebugTrace(_T("Path:accept only servershare"));
  407. }
  408. else
  409. {
  410. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_NOT_ALLOWED,CHKPATH_FAIL_NOT_ALLOWED_UNC_SERVERSHARE);
  411. DebugTrace(_T("Path:no accept only servershare"));
  412. }
  413. goto MyValidatePath_Exit;
  414. }
  415. // Check for invalid chars in UNC path
  416. if (IsContainInvalidCharsUNC(csPathMunged))
  417. {
  418. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_INVALID_CHARSET,CHKPATH_FAIL_INVALID_CHARSET_FOR_UNC);
  419. DebugTrace(_T("Path:Bad UNC share contains ':'"));
  420. goto MyValidatePath_Exit;
  421. }
  422. // ------------------------
  423. // Check for special case invalid UNC paths...
  424. // \\servername\servershare\
  425. // \\servername\servershare\.
  426. // ------------------------
  427. BOOL bWantFilePart = FALSE;
  428. if (iPathTypeWanted == CHKPATH_WANT_FILE)
  429. {
  430. bWantFilePart = TRUE;
  431. }
  432. if (!IsValidUNCSpecialCases(csPathMunged,bLocal,bWantFilePart))
  433. {
  434. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_INVALID_PARTS,CHKPATH_FAIL_INVALID_BAD_UNC_PART);
  435. DebugTrace(_T("Path:Bad UNC share"));
  436. goto MyValidatePath_Exit;
  437. }
  438. // this function is UNC friendly
  439. if (bLocal)
  440. {
  441. if (PathIsDirectory(csPathMunged))
  442. {
  443. if (iPathTypeWanted == CHKPATH_WANT_FILE)
  444. {
  445. // it is a valid directory...but we don't want that
  446. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_NOT_ALLOWED,CHKPATH_FAIL_NOT_ALLOWED_DIR_PATH);
  447. DebugTrace(_T("Path:PathIsDirectory:DIR specified, should be filename"));
  448. goto MyValidatePath_Exit;
  449. }
  450. }
  451. else
  452. {
  453. // path is not directory
  454. // check if that is what they wanted.
  455. if (iPathTypeWanted == CHKPATH_WANT_DIR)
  456. {
  457. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_NOT_ALLOWED,CHKPATH_FAIL_NOT_ALLOWED_DIR_NOT_EXIST);
  458. DebugTrace(_T("Path:PathIsDirectory:DIR not exist"));
  459. // the directory doesn't exist...
  460. goto MyValidatePath_Exit;
  461. }
  462. }
  463. }
  464. // if we are here, then we passed all the above ways that we could figure
  465. // out if this is an invalid UNC.
  466. // now we just need to determine if it's what the user wants!
  467. // is there anyway we can verify that is is a filename
  468. // and not a dir???
  469. goto MyValidatePath_Exit;
  470. }
  471. // -------------------------------------------------------------
  472. // Regular filepath Validation
  473. // -------------------------------------------------------------
  474. // ensure that we have a valid drive path...
  475. // "c:myfile.txt" is not valid!
  476. // we have to have all parts
  477. // Not -- just directory paths, we need filename part
  478. // check if it has these 3 parts "c:\"
  479. if (!IsFullyQualifiedPath(csPathMunged))
  480. {
  481. // Missing drive part
  482. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_INVALID_PARTS,CHKPATH_FAIL_INVALID_BAD_DRIVE_PART);
  483. DebugTrace(_T("Path:IsFullyQualifiedPath:Bad Drive path"));
  484. goto MyValidatePath_Exit;
  485. }
  486. // check if dir part contains invalid chars
  487. if (IsContainInvalidCharsAfterDrivePart(csPathMunged))
  488. {
  489. // Bad path portion
  490. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_INVALID_CHARSET,CHKPATH_FAIL_INVALID_CHARSET_FOR_DIR);
  491. DebugTrace(_T("Path:IsContainInvalidCharsAfterDrivePart:Bad Dir path"));
  492. goto MyValidatePath_Exit;
  493. }
  494. // check if specified path, has a filename part
  495. if (iPathTypeWanted == CHKPATH_WANT_FILE)
  496. {
  497. TCHAR szFullPath[_MAX_PATH];
  498. LPTSTR pFilePart = NULL;
  499. if (0 == GetFullPathName(csPathMunged, _MAX_PATH, szFullPath, &pFilePart))
  500. {
  501. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_INVALID_PARTS,CHKPATH_FAIL_INVALID_BAD_PATH);
  502. DebugTrace(_T("Path:GetFullPathName FAILED"));
  503. goto MyValidatePath_Exit;
  504. }
  505. if (NULL == pFilePart)
  506. {
  507. // Missing filename
  508. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_INVALID_PARTS,CHKPATH_FAIL_INVALID_BAD_FILE_PART);
  509. DebugTrace(_T("Path:GetFullPathName missing filename"));
  510. goto MyValidatePath_Exit;
  511. }
  512. else
  513. {
  514. // Check if the file part contains a ":"
  515. // since this is invalid for a filename...
  516. // Check if it contains an invalid character like ':'
  517. if (IsContainInvalidCharsFilePart(pFilePart))
  518. {
  519. // contains a bad character
  520. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_INVALID_CHARSET,CHKPATH_FAIL_INVALID_CHARSET_FOR_FILE);
  521. DebugTrace(_T("Path:filename contains bad char ':'"));
  522. goto MyValidatePath_Exit;
  523. }
  524. }
  525. }
  526. // check if it's a directory
  527. if (bLocal)
  528. {
  529. // ------------------------------------------------
  530. // check for a filename at the end
  531. // the user wants a path with a filename at the end
  532. // ------------------------------------------------
  533. if (iPathTypeWanted == CHKPATH_WANT_FILE)
  534. {
  535. // Check if it's a directory
  536. if (PathIsDirectory(csPathMunged))
  537. {
  538. // it is a valid directory...but we don't want that
  539. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_NOT_ALLOWED,CHKPATH_FAIL_NOT_ALLOWED_DIR_PATH);
  540. DebugTrace(_T("Path:PathIsDirectory:DIR specified, should be filename!"));
  541. goto MyValidatePath_Exit;
  542. }
  543. // strip off the filename part and
  544. // check if the user specified a valid directory in the dir portion
  545. if (IsContainInvalidCharsAfterDrivePart(csPathMunged))
  546. {
  547. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_INVALID_PARTS,CHKPATH_FAIL_INVALID_BAD_DIR_PART);
  548. DebugTrace(_T("Path:DirectoryIsInvalid:Bad Dir Part"));
  549. goto MyValidatePath_Exit;
  550. }
  551. if (FALSE == IsDirPartExist(csPathMunged))
  552. {
  553. // it's not a directory that exists...
  554. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_NOT_ALLOWED,CHKPATH_FAIL_NOT_ALLOWED_DIR_NOT_EXIST);
  555. DebugTrace(_T("Path:Dir Part doesnt exist"));
  556. goto MyValidatePath_Exit;
  557. }
  558. {
  559. // check if the filename part is valid
  560. // dont' accept c:\\\a.dll, or c:\\a.dll
  561. TCHAR * pszAfterRoot = NULL;
  562. pszAfterRoot = PathSkipRoot(csPathMunged);
  563. if (pszAfterRoot)
  564. {
  565. // check if there are any \ in the beginning.
  566. if ( pszAfterRoot[0] == '\\' )
  567. {
  568. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_INVALID_PARTS,CHKPATH_FAIL_INVALID_BAD_FILE_PART);
  569. DebugTrace(_T("Path:bad filename:%s"),pszAfterRoot);
  570. goto MyValidatePath_Exit;
  571. }
  572. }
  573. }
  574. /*
  575. if (!PathFileExists(csPathMunged))
  576. {
  577. // err, file does not exists
  578. }
  579. */
  580. }
  581. else
  582. {
  583. // ------------------------------------------------
  584. // check for dir
  585. // the user wants a dir with no filename
  586. // ------------------------------------------------
  587. // Check if it's a directory
  588. if (!PathIsDirectory(csPathMunged))
  589. {
  590. // it's not a directory that exists...
  591. dwReturn = MAKE_FILERESULT(SEVERITY_ERROR,CHKPATH_FAIL_NOT_ALLOWED,CHKPATH_FAIL_NOT_ALLOWED_DIR_NOT_EXIST);
  592. DebugTrace(_T("Path:DirectoryIsInvalid:Bad Dir Part"));
  593. goto MyValidatePath_Exit;
  594. }
  595. }
  596. }
  597. MyValidatePath_Exit:
  598. DebugTrace(_T("MyValidatePath(%s)=0x%x:"),path,dwReturn);
  599. if (IS_FLAG_SET(dwReturn,CHKPATH_FAIL_INVALID_LENGTH))
  600. {
  601. DebugTrace(_T("CHKPATH_FAIL_INVALID_LENGTH\r\n"));
  602. }
  603. if (IS_FLAG_SET(dwReturn,CHKPATH_FAIL_INVALID_CHARSET))
  604. {
  605. DebugTrace(_T("CHKPATH_FAIL_INVALID_CHARSET\r\n"));
  606. }
  607. if (IS_FLAG_SET(dwReturn,CHKPATH_FAIL_INVALID_PARTS))
  608. {
  609. DebugTrace(_T("CHKPATH_FAIL_INVALID_PARTS\r\n"));
  610. }
  611. if (IS_FLAG_SET(dwReturn,CHKPATH_FAIL_NOT_ALLOWED))
  612. {
  613. DebugTrace(_T("CHKPATH_FAIL_NOT_ALLOWED\r\n"));
  614. }
  615. return dwReturn;
  616. }