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.

709 lines
24 KiB

  1. #include "precomp.h"
  2. #include <regstr.h>
  3. // Private forward decalarations
  4. static DWORD pepHrToPep(HRESULT hr);
  5. static void pepHrCallToHrResult(HRESULT hrCall, HRESULT &hrResult);
  6. static BOOL replaceSubString(LPTSTR pszSrc, LPCTSTR pcszSub, LPCTSTR pcszReplace);
  7. BOOL PathCreatePath(LPCTSTR pszPathToCreate)
  8. {
  9. TCHAR szGrowingPath[MAX_PATH],
  10. szBuffer[MAX_PATH];
  11. LPTSTR pszNext;
  12. if (!PathIsValidPath(pszPathToCreate))
  13. return FALSE;
  14. if (PathIsUNCServer(pszPathToCreate))
  15. return FALSE;
  16. if (PathIsRoot(pszPathToCreate))
  17. return TRUE;
  18. szGrowingPath[0] = TEXT('\0');
  19. StrCpy(szBuffer, pszPathToCreate);
  20. pszPathToCreate = &szBuffer[0];
  21. pszNext = PathSkipRoot(pszPathToCreate);
  22. if (pszNext != NULL) {
  23. // copy the root to szGrowingPath
  24. StrCpyN(szGrowingPath, pszPathToCreate, INT(pszNext - pszPathToCreate) + 1);
  25. pszPathToCreate = pszNext;
  26. }
  27. // loop through each dir in the path and if it doesn't exist, create it
  28. for (; (pszNext = PathFindNextComponent(pszPathToCreate)) != NULL; pszPathToCreate = pszNext) {
  29. if (*pszNext != TEXT('\0')) {
  30. ASSERT(pszNext > pszPathToCreate);
  31. *(pszNext - 1) = TEXT('\0');
  32. }
  33. PathAppend(szGrowingPath, pszPathToCreate);
  34. if (!PathFileExists(szGrowingPath))
  35. if (!CreateDirectory(szGrowingPath, NULL) && !PathFileExists(szGrowingPath))
  36. return FALSE;
  37. else
  38. if (!PathIsDirectory(szGrowingPath))
  39. return FALSE;
  40. }
  41. return TRUE;
  42. }
  43. BOOL PathIsValidPath(LPCTSTR pszPath, DWORD dwFlags /*= PIVP_DEFAULT*/)
  44. {
  45. return (PathIsValidPathEx(pszPath, dwFlags) == PIVP_VALID);
  46. }
  47. BOOL PathIsValidFile(LPCTSTR pszFile, DWORD dwFlags /*= PIVP_DEFAULT*/)
  48. {
  49. return (PathIsValidPathEx(pszFile, dwFlags | PIVP_FILENAME_ONLY) == PIVP_VALID);
  50. }
  51. DWORD PathIsValidPathEx(LPCTSTR pszPath, DWORD dwFlags /*= PIVP_DEFAULT*/, LPCTSTR *ppszError /*= NULL*/)
  52. {
  53. LPCTSTR pszCur, pszPrev;
  54. UINT nType;
  55. int i;
  56. DWORD dwResult;
  57. dwResult = PIVP_VALID;
  58. if (ppszError != NULL)
  59. *ppszError = NULL;
  60. if (pszPath == NULL)
  61. return PIVP_ARG;
  62. for (i = 0, pszCur = pszPath, pszPrev = NULL;
  63. dwResult == PIVP_VALID && *pszCur != TEXT('\0');
  64. i++, pszPrev = pszCur, pszCur = CharNext(pszCur)) {
  65. nType = PathGetCharType(*pszCur);
  66. if (HasFlag(nType, GCT_INVALID) || HasFlag(nType, GCT_WILD))
  67. dwResult = HasFlag(nType, GCT_WILD) ? PIVP_WILD : PIVP_CHAR;
  68. else if (HasFlag(nType, GCT_SEPARATOR)) {
  69. if (HasFlag(dwFlags, PIVP_FILENAME_ONLY))
  70. dwResult = PIVP_CHAR;
  71. else { /* !HasFlag(dwFlag, PIVP_FILENAME_ONLY)) */
  72. if (*pszCur == TEXT('\\')) {
  73. if (i == 0) {
  74. ASSERTA(!IsDBCSLeadByte(*pszCur));
  75. if (!HasFlag(dwFlags, PIVP_RELATIVE_VALID) &&
  76. *(pszCur + 1) != TEXT('\\'))
  77. dwResult = PIVP_RELATIVE;
  78. }
  79. else if (i == 1) {
  80. ASSERT(pszPrev != NULL);
  81. if (*pszPrev == TEXT('\\'))
  82. ;
  83. else if (*pszPrev != TEXT(' ') &&
  84. HasFlag(PathGetCharType(*pszPrev), GCT_LFNCHAR))
  85. ;
  86. else
  87. dwResult = PIVP_FIRST_CHAR;
  88. }
  89. else { /* if (i >= 2) */
  90. ASSERT(pszPrev != NULL);
  91. if (*pszPrev != TEXT(' ')) {
  92. if (!HasFlag(PathGetCharType(*pszPrev), GCT_LFNCHAR))
  93. dwResult = PIVP_PRESLASH;
  94. if (dwResult != PIVP_VALID && i == 2)
  95. dwResult = (*pszPrev != TEXT(':')) ? dwResult : PIVP_VALID;
  96. }
  97. else
  98. dwResult = PIVP_SPACE;
  99. }
  100. }
  101. else if (*pszCur == TEXT('/'))
  102. dwResult = PIVP_FWDSLASH;
  103. else if (*pszCur == TEXT(':'))
  104. if (i != 1)
  105. dwResult = PIVP_COLON;
  106. else {
  107. int iDrive;
  108. ASSERT(pszPrev == pszPath);
  109. iDrive = PathGetDriveNumber(pszPath);
  110. dwResult = (iDrive < 0 || iDrive > 25) ? PIVP_DRIVE : PIVP_VALID;
  111. }
  112. else /* any other separator */
  113. dwResult = PIVP_SEPARATOR; // better be safe than sorry
  114. } /* !HasFlag(dwFlag, PIVP_FILENAME_ONLY)) */
  115. } /* HasFlag(nType, GCT_SEPARATOR) */
  116. else if (HasFlag(nType, GCT_LFNCHAR)) {
  117. LPCSTR pcszBuffer = NULL; // used only to check DBCS and 0x5c validity
  118. CHAR szAbuff[3];
  119. #ifndef _UNICODE
  120. pcszBuffer = pszCur;
  121. *szAbuff = TEXT('\0');
  122. #else
  123. // convert the character to ANSI to check for invalid DBCS and 5c
  124. {
  125. WCHAR szWbuff[2];
  126. szWbuff[0] = *pszCur;
  127. szWbuff[1] = TEXT('\0');
  128. W2Abuf(szWbuff, szAbuff, countof(szAbuff));
  129. pcszBuffer = szAbuff;
  130. }
  131. #endif
  132. if (HasFlag(dwFlags, PIVP_DBCS_INVALID))
  133. if (IsDBCSLeadByte(*pcszBuffer))
  134. dwResult = PIVP_DBCS;
  135. if (dwResult == PIVP_VALID && HasFlag(dwFlags, PIVP_0x5C_INVALID))
  136. if (IsDBCSLeadByte(*pcszBuffer) && *(pcszBuffer + 1) == 0x5C)
  137. dwResult = PIVP_0x5C;
  138. if (dwResult == PIVP_VALID && HasFlag(dwFlags, PIVP_EXCHAR_INVALID))
  139. if (*pszCur & 0x80)
  140. dwResult = PIVP_EXCHAR;
  141. if (dwResult == PIVP_VALID && i == 2) {
  142. ASSERT(pszPrev != NULL);
  143. if (*pszPrev == TEXT(':'))
  144. dwResult = PIVP_COLON;
  145. }
  146. }
  147. else
  148. dwResult = PIVP_CHAR;
  149. }
  150. if (dwResult == PIVP_VALID && HasFlag(dwFlags, PIVP_MUST_EXIST))
  151. if (!PathFileExists(pszPath)) {
  152. dwResult = PIVP_DOESNT_EXIST;
  153. pszPrev = pszPath;
  154. }
  155. else {
  156. SetFlag((LPDWORD)&dwFlags, PIVP_MUST_EXIST, FALSE);
  157. if (PathIsDirectory(pszPath)) {
  158. if (HasFlag(dwFlags, PIVP_FILE_ONLY)) {
  159. dwResult = PIVP_NOT_FILE;
  160. pszPrev = pszPath;
  161. }
  162. }
  163. else /* it's a file */
  164. if (HasFlag(dwFlags, PIVP_FOLDER_ONLY)) {
  165. dwResult = PIVP_NOT_FOLDER;
  166. pszPrev = pszPath;
  167. }
  168. }
  169. if (dwResult != PIVP_VALID && ppszError != NULL)
  170. *ppszError = pszPrev;
  171. return dwResult;
  172. }
  173. HRESULT PathEnumeratePath(LPCTSTR pszPath, DWORD dwFlags, PFNPATHENUMPATHPROC pfnEnumProc, LPARAM lParam,
  174. PDWORD *ppdwReserved /*= NULL*/)
  175. {
  176. WIN32_FIND_DATA fd;
  177. TCHAR szPath[MAX_PATH];
  178. HANDLE hFindFile;
  179. HRESULT hrFirst, hrSecond, hrResult;
  180. PDWORD pdwEnum, pdwRcrs,
  181. pdwRslt, pdwSrc;
  182. DWORD rgdwRslt[PEP_RCRS_OUTPOS_LAST],
  183. rgdwEnum[PEP_ENUM_OUTPOS_LAST],
  184. rgdwRcrs[PEP_RCRS_OUTPOS_LAST],
  185. dwBelowFlags, dwBelowFlags2;
  186. BOOL fOwnEnum, fOwnRcrs;
  187. if (pszPath == NULL || pfnEnumProc == NULL)
  188. return E_INVALIDARG;
  189. if (ppdwReserved != NULL && *ppdwReserved != NULL)
  190. ZeroMemory(*ppdwReserved, sizeof(rgdwRslt));
  191. PathCombine(szPath, pszPath, TEXT("*.*"));
  192. hFindFile = FindFirstFile(szPath, &fd);
  193. if (hFindFile == INVALID_HANDLE_VALUE)
  194. return E_FAIL;
  195. hrResult = S_OK;
  196. dwBelowFlags = dwFlags;
  197. ZeroMemory(rgdwRslt, sizeof(rgdwRslt));
  198. do {
  199. PathCombine(szPath, pszPath, fd.cFileName);
  200. //----- Filter out non-interesting objects -----
  201. if (HasFlag(fd.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY)) {
  202. if (StrCmp(fd.cFileName, TEXT(".")) == 0 || StrCmp(fd.cFileName, TEXT("..")) == 0)
  203. continue;
  204. if (HasFlag(dwFlags, PEP_SCPE_NOFOLDERS))
  205. continue;
  206. }
  207. else
  208. if (HasFlag(dwFlags, PEP_SCPE_NOFILES))
  209. continue;
  210. //----- Initialize loop variables -----
  211. hrFirst = S_OK;
  212. hrSecond = S_OK;
  213. pdwEnum = NULL;
  214. pdwRcrs = NULL;
  215. fOwnEnum = FALSE;
  216. fOwnRcrs = FALSE;
  217. ZeroMemory(rgdwEnum, sizeof(rgdwEnum));
  218. ZeroMemory(rgdwRcrs, sizeof(rgdwRcrs));
  219. //----- The order is: recourse first then go into the callback -----
  220. if (!HasFlag(dwFlags, PEP_CTRL_ENUMPROCFIRST)) {
  221. //_____ Recourse processing _____
  222. if (HasFlag(fd.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY)) {
  223. if (HasFlag(dwFlags, PEP_CTRL_USECONTROL)) {
  224. pdwRcrs = rgdwRcrs;
  225. fOwnRcrs = TRUE;
  226. }
  227. hrFirst = PathEnumeratePath(szPath, dwBelowFlags, pfnEnumProc, lParam, &pdwRcrs);
  228. ASSERT(pdwRcrs == NULL ||
  229. (!HasFlag(pdwRcrs[PEP_RCRS_OUTPOS_BELOW], PEP_RCRS_ALL) &&
  230. !HasFlag(pdwRcrs[PEP_RCRS_OUTPOS_THISLEVEL], PEP_RCRS_ALL)));
  231. }
  232. //_____ Callback processing _____
  233. if (!HasFlag(dwFlags, PEP_CTRL_NOSECONDCALL) &&
  234. (pdwRcrs == NULL || !HasFlag(pdwRcrs[PEP_RCRS_OUTPOS_SECONDCALL], PEP_CTRL_NOSECONDCALL))) {
  235. if (HasFlag(dwFlags, PEP_CTRL_USECONTROL) ||
  236. (pdwRcrs != NULL && HasFlag(pdwRcrs[PEP_RCRS_OUTPOS_SECONDCALL], PEP_CTRL_USECONTROL))) {
  237. rgdwEnum[PEP_ENUM_INPOS_FLAGS] = dwFlags;
  238. if (pdwRcrs != NULL)
  239. if (HasFlag(pdwRcrs[PEP_RCRS_OUTPOS_SECONDCALL], PEP_CTRL_RESET))
  240. rgdwEnum[PEP_ENUM_INPOS_FLAGS] = 0;
  241. else {
  242. rgdwEnum[PEP_ENUM_INPOS_FLAGS] = pdwRcrs[PEP_RCRS_OUTPOS_SECONDCALL];
  243. SetFlag(&rgdwEnum[PEP_ENUM_INPOS_FLAGS], PEP_CTRL_USECONTROL, FALSE);
  244. }
  245. // callback also needs to know:
  246. rgdwEnum[PEP_ENUM_INPOS_FLAGS] |= pepHrToPep(hrFirst); // how recourse for this object worked
  247. rgdwEnum[PEP_ENUM_INPOS_RECOURSEFLAGS] = dwBelowFlags; // what flags recourse was called with
  248. pdwEnum = rgdwEnum;
  249. fOwnEnum = TRUE;
  250. }
  251. hrSecond = pfnEnumProc(szPath, &fd, lParam, &pdwEnum);
  252. }
  253. }
  254. //----- The order is: go into callback then recourse -----
  255. else { /* if (HasFlag(dwFlags, PEP_CTRL_ENUMPROCFIRST)) */
  256. //_____ Callback processing _____
  257. if (HasFlag(dwFlags, PEP_CTRL_USECONTROL)) {
  258. rgdwEnum[PEP_ENUM_INPOS_FLAGS] = dwFlags;
  259. pdwEnum = rgdwEnum;
  260. fOwnEnum = TRUE;
  261. }
  262. hrFirst = pfnEnumProc(szPath, &fd, lParam, &pdwEnum);
  263. //_____ Recourse processing _____
  264. if (HasFlag(fd.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY) &&
  265. !HasFlag(dwFlags, PEP_CTRL_NOSECONDCALL) &&
  266. (pdwEnum == NULL || !HasFlag(pdwEnum[PEP_ENUM_OUTPOS_SECONDCALL], PEP_CTRL_NOSECONDCALL))) {
  267. dwBelowFlags2 = dwBelowFlags;
  268. if (pdwEnum != NULL && pdwEnum[PEP_ENUM_OUTPOS_SECONDCALL] != 0)
  269. if (HasFlag(pdwEnum[PEP_ENUM_OUTPOS_SECONDCALL], PEP_CTRL_RESET))
  270. dwBelowFlags2 = 0;
  271. else {
  272. dwBelowFlags2 = pdwEnum[PEP_ENUM_OUTPOS_SECONDCALL];
  273. SetFlag(&dwBelowFlags2, PEP_CTRL_USECONTROL, FALSE);
  274. }
  275. if (HasFlag(dwFlags, PEP_CTRL_USECONTROL) ||
  276. (pdwEnum != NULL && HasFlag(pdwEnum[PEP_ENUM_OUTPOS_SECONDCALL], PEP_CTRL_USECONTROL))) {
  277. pdwRcrs = rgdwRcrs;
  278. fOwnRcrs = TRUE;
  279. }
  280. hrSecond = PathEnumeratePath(szPath, dwBelowFlags2, pfnEnumProc, lParam, &pdwRcrs);
  281. ASSERT(pdwRcrs == NULL ||
  282. (pdwRcrs[PEP_RCRS_OUTPOS_SECONDCALL] == 0 &&
  283. !HasFlag(pdwRcrs[PEP_RCRS_OUTPOS_BELOW], PEP_RCRS_ALL) &&
  284. !HasFlag(pdwRcrs[PEP_RCRS_OUTPOS_THISLEVEL], PEP_RCRS_ALL)));
  285. }
  286. }
  287. //----- Setting preliminary out-parameters -----
  288. // PEP_ENUM_OUTPOS_SECONDCALL
  289. pdwRslt = &rgdwRslt[PEP_RCRS_OUTPOS_SECONDCALL];
  290. if (!HasFlag(dwFlags, PEP_CTRL_ENUMPROCFIRST)) {
  291. pdwSrc = (pdwEnum != NULL) ? &pdwEnum[PEP_ENUM_OUTPOS_SECONDCALL] : NULL;
  292. if (pdwSrc != NULL && *pdwSrc != 0)
  293. *pdwRslt = *pdwSrc;
  294. }
  295. // PEP_RCRS_OUTPOS_BELOW
  296. pdwRslt = &rgdwRslt[PEP_RCRS_OUTPOS_BELOW];
  297. if (!HasFlag(dwFlags, PEP_CTRL_ENUMPROCFIRST)) {
  298. pdwSrc = (pdwEnum != NULL) ? &pdwEnum[PEP_ENUM_OUTPOS_ABOVE_SIBLINGS] : NULL;
  299. if (pdwSrc != NULL && *pdwSrc != 0)
  300. *pdwRslt = *pdwSrc;
  301. else {
  302. pdwSrc = (pdwRcrs != NULL) ? &pdwRcrs[PEP_RCRS_OUTPOS_BELOW] : NULL;
  303. if (pdwSrc != NULL && HasFlag(*pdwSrc, PEP_CTRL_KEEPAPPLY))
  304. *pdwRslt = *pdwSrc;
  305. }
  306. }
  307. else {
  308. pdwSrc = (pdwRcrs != NULL) ? &pdwRcrs[PEP_RCRS_OUTPOS_BELOW] : NULL;
  309. if (pdwSrc != NULL && HasFlag(*pdwSrc, PEP_CTRL_KEEPAPPLY))
  310. *pdwRslt = *pdwSrc;
  311. else {
  312. pdwSrc = (pdwEnum != NULL) ? &pdwEnum[PEP_ENUM_OUTPOS_ABOVE_SIBLINGS] : NULL;
  313. if (pdwSrc != NULL && *pdwSrc != 0)
  314. *pdwRslt = *pdwSrc;
  315. }
  316. }
  317. // PEP_RCRS_OUTPOS_THISLEVEL
  318. pdwRslt = &rgdwRslt[PEP_RCRS_OUTPOS_THISLEVEL];
  319. if (!HasFlag(dwFlags, PEP_CTRL_ENUMPROCFIRST)) {
  320. pdwSrc = (pdwEnum != NULL) ? &pdwEnum[PEP_ENUM_OUTPOS_ABOVE] : NULL;
  321. if (pdwSrc != NULL && *pdwSrc != 0)
  322. *pdwRslt = *pdwSrc;
  323. else {
  324. pdwSrc = (pdwRcrs != NULL) ? &pdwRcrs[PEP_RCRS_OUTPOS_THISLEVEL] : NULL;
  325. if (pdwSrc != NULL && HasFlag(*pdwSrc, PEP_CTRL_KEEPAPPLY))
  326. *pdwRslt = *pdwSrc;
  327. }
  328. }
  329. else {
  330. pdwSrc = (pdwRcrs != NULL) ? &pdwRcrs[PEP_RCRS_OUTPOS_THISLEVEL] : NULL;
  331. if (pdwSrc != NULL && HasFlag(*pdwSrc, PEP_CTRL_KEEPAPPLY))
  332. *pdwRslt = *pdwSrc;
  333. else {
  334. pdwSrc = (pdwEnum != NULL) ? &pdwEnum[PEP_ENUM_OUTPOS_ABOVE] : NULL;
  335. if (pdwSrc != NULL && *pdwSrc != 0)
  336. *pdwRslt = *pdwSrc;
  337. }
  338. }
  339. //----- Adjust to the new control settings -----
  340. // dwBelowFlags
  341. if (!HasFlag(dwFlags, PEP_CTRL_ENUMPROCFIRST)) {
  342. pdwSrc = (pdwEnum != NULL) ? &pdwEnum[PEP_ENUM_OUTPOS_BELOW] : NULL;
  343. if (pdwSrc != NULL && *pdwSrc != 0)
  344. dwBelowFlags = *pdwSrc;
  345. else {
  346. pdwSrc = (pdwRcrs != NULL) ? &pdwRcrs[PEP_RCRS_OUTPOS_BELOW] : NULL;
  347. if (pdwSrc != NULL && *pdwSrc != 0)
  348. dwBelowFlags = *pdwSrc;
  349. }
  350. }
  351. else {
  352. pdwSrc = (pdwRcrs != NULL) ? &pdwRcrs[PEP_RCRS_OUTPOS_BELOW] : NULL;
  353. if (pdwSrc != NULL && *pdwSrc != 0)
  354. dwBelowFlags = *pdwSrc;
  355. else {
  356. pdwSrc = (pdwEnum != NULL) ? &pdwEnum[PEP_ENUM_OUTPOS_BELOW] : NULL;
  357. if (pdwSrc != NULL && *pdwSrc != 0)
  358. dwBelowFlags = *pdwSrc;
  359. }
  360. }
  361. // dwFlags
  362. if (!HasFlag(dwFlags, PEP_CTRL_ENUMPROCFIRST)) {
  363. pdwSrc = (pdwEnum != NULL) ? &pdwEnum[PEP_ENUM_OUTPOS_THISLEVEL] : NULL;
  364. if (pdwSrc != NULL && *pdwSrc != 0)
  365. dwFlags = *pdwSrc;
  366. else {
  367. pdwSrc = (pdwRcrs != NULL) ? &pdwRcrs[PEP_RCRS_OUTPOS_THISLEVEL] : NULL;
  368. if (pdwSrc != NULL && *pdwSrc != 0)
  369. dwFlags = *pdwSrc;
  370. }
  371. }
  372. else {
  373. pdwSrc = (pdwRcrs != NULL) ? &pdwRcrs[PEP_RCRS_OUTPOS_THISLEVEL] : NULL;
  374. if (pdwSrc != NULL && *pdwSrc != 0)
  375. dwFlags = *pdwSrc;
  376. else {
  377. pdwSrc = (pdwEnum != NULL) ? &pdwEnum[PEP_ENUM_OUTPOS_THISLEVEL] : NULL;
  378. if (pdwSrc != NULL && *pdwSrc != 0)
  379. dwFlags = *pdwSrc;
  380. }
  381. }
  382. //----- Release the memory not owned here -----
  383. if (!fOwnEnum && pdwEnum != NULL)
  384. CoTaskMemFree(pdwEnum);
  385. if (!fOwnRcrs && pdwRcrs != NULL)
  386. CoTaskMemFree(pdwRcrs);
  387. //----- Process result codes from both calls -----
  388. pepHrCallToHrResult(hrFirst, hrResult); // modifies hrResult by reference
  389. if (hrResult == S_FALSE || FAILED(hrResult))
  390. break;
  391. pepHrCallToHrResult(hrSecond, hrResult); // modifies hrResult by reference
  392. if (hrResult == S_FALSE || FAILED(hrResult))
  393. break;
  394. } while (FindNextFile(hFindFile, &fd));
  395. FindClose(hFindFile);
  396. //----- Set an out-parameter(s) -----
  397. if (ppdwReserved != NULL) {
  398. if (*ppdwReserved == NULL &&
  399. (rgdwRslt[PEP_RCRS_OUTPOS_SECONDCALL] != 0 ||
  400. rgdwRslt[PEP_RCRS_OUTPOS_BELOW] != 0 ||
  401. rgdwRslt[PEP_RCRS_OUTPOS_THISLEVEL] != 0)) {
  402. *ppdwReserved = (PDWORD)CoTaskMemAlloc(sizeof(rgdwRslt));
  403. if (*ppdwReserved == NULL)
  404. return E_OUTOFMEMORY;
  405. }
  406. if (*ppdwReserved != NULL)
  407. CopyMemory(*ppdwReserved, rgdwRslt, sizeof(rgdwRslt));
  408. }
  409. return hrResult;
  410. }
  411. BOOL PathRemovePath(LPCTSTR pszPath, DWORD dwFlags /*= 0*/)
  412. {
  413. USES_CONVERSION;
  414. return (DelNode(T2CA(pszPath), dwFlags) == S_OK);
  415. }
  416. BOOL PathIsLocalPath(LPCTSTR pszPath)
  417. {
  418. if (pszPath == NULL || *pszPath == TEXT('\0') || PathIsUNC(pszPath) || PathIsURL(pszPath))
  419. return FALSE;
  420. if (pszPath[1] == TEXT(':')) { // drive letter present, check if it's a network drive
  421. TCHAR szDrive[4];
  422. // NOTE: Need not worry about DBCS chars here because
  423. // (1) 'a' thru 'z', 'A' thru 'Z' and ':' are not DBCS lead byte chars
  424. // (2) ':' is not a DBCS trailing byte char
  425. szDrive[0] = pszPath[0];
  426. szDrive[1] = pszPath[1];
  427. szDrive[2] = TEXT('\\');
  428. szDrive[3] = TEXT('\0');
  429. return GetDriveType(szDrive) != DRIVE_REMOTE;
  430. }
  431. // not a fully qualified path, so must be local
  432. return TRUE;
  433. }
  434. BOOL PathFileExistsInDir(LPCTSTR pcszFile, LPCTSTR pcszDir)
  435. {
  436. TCHAR szFile[MAX_PATH];
  437. if (pcszFile == NULL || pcszDir == NULL || ISNULL(pcszFile) || ISNULL(pcszDir))
  438. return FALSE;
  439. PathCombine(szFile, pcszDir, pcszFile);
  440. return PathFileExists(szFile);
  441. }
  442. BOOL PathHasBackslash(LPCTSTR pcszPath)
  443. {
  444. if (pcszPath == NULL || *pcszPath == TEXT('\0'))
  445. return FALSE;
  446. return *CharPrev(pcszPath, pcszPath + StrLen(pcszPath)) == TEXT('\\');
  447. }
  448. BOOL PathIsEmptyPath(LPCTSTR pcszPath, DWORD dwFlags /*= FILES_AND_DIRS*/, LPCTSTR pcszExcludeFile /*= NULL*/)
  449. // pcszExcludeFile - file to be excluded while searching in the path.
  450. // Return TRUE if pcszPath is non-existent or empty; otherwise, return FALSE
  451. {
  452. BOOL fRet = TRUE;
  453. TCHAR szSrcFile[MAX_PATH];
  454. WIN32_FIND_DATA fd;
  455. HANDLE hFindFile;
  456. if (!PathIsDirectory(pcszPath))
  457. return TRUE;
  458. PathCombine(szSrcFile, pcszPath, TEXT("*.*"));
  459. if (pcszExcludeFile != NULL)
  460. pcszExcludeFile = PathFindFileName(pcszExcludeFile);
  461. if ((hFindFile = FindFirstFile(szSrcFile, &fd)) != INVALID_HANDLE_VALUE)
  462. {
  463. do
  464. {
  465. if (StrCmpI(fd.cFileName, TEXT(".")) && StrCmpI(fd.cFileName, TEXT("..")))
  466. {
  467. if(((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && HasFlag(dwFlags, FILES_ONLY)) ||
  468. (pcszExcludeFile != NULL && StrCmpI(fd.cFileName, pcszExcludeFile) == 0))
  469. continue;
  470. // pcszPath is not empty
  471. fRet = FALSE;
  472. break;
  473. }
  474. } while (FindNextFile(hFindFile, &fd));
  475. FindClose(hFindFile);
  476. }
  477. return fRet;
  478. }
  479. void PathReplaceWithLDIDs(LPTSTR pszPath)
  480. {
  481. TCHAR szSearchDir[MAX_PATH];
  482. DWORD dwSize;
  483. // check IE dir first since IE is usually under programs files
  484. dwSize = sizeof(szSearchDir);
  485. if (SHGetValue(HKEY_LOCAL_MACHINE, REGSTR_PATH_APPPATHS TEXT("\\iexplore.exe"), NULL, NULL,
  486. szSearchDir, &dwSize) == ERROR_SUCCESS)
  487. {
  488. PathRemoveFileSpec(szSearchDir);
  489. // note: we assume that IE install dir has been defined as custom LDID 49100 here
  490. if (replaceSubString(pszPath, szSearchDir, TEXT("%49100%")))
  491. return;
  492. }
  493. dwSize = sizeof(szSearchDir);
  494. if (SHGetValue(HKEY_LOCAL_MACHINE, REGSTR_PATH_SETUP, TEXT("ProgramFilesDir"), NULL,
  495. szSearchDir, &dwSize) == ERROR_SUCCESS)
  496. {
  497. PathRemoveBackslash(szSearchDir);
  498. // note: we assume that program files has been defined as custom LDID 49000 here
  499. if (replaceSubString(pszPath, szSearchDir, TEXT("%49000%")))
  500. return;
  501. }
  502. // check system before windows since windows is usually a substring of system
  503. if (GetSystemDirectory(szSearchDir, countof(szSearchDir)))
  504. {
  505. PathRemoveBackslash(szSearchDir);
  506. if (replaceSubString(pszPath, szSearchDir, TEXT("%11%")))
  507. return;
  508. }
  509. // check windows dir last
  510. if (GetWindowsDirectory(szSearchDir, countof(szSearchDir)))
  511. {
  512. PathRemoveBackslash(szSearchDir);
  513. if (replaceSubString(pszPath, szSearchDir, TEXT("%10%")))
  514. return;
  515. }
  516. }
  517. /////////////////////////////////////////////////////////////////////////////
  518. // Implementation helpers routines (private)
  519. DWORD pepHrToPep(HRESULT hr)
  520. {
  521. DWORD dwResult;
  522. if (hr == S_OK)
  523. dwResult = PEP_RCRS_DEFAULT;
  524. else if (hr == S_FALSE)
  525. dwResult = PEP_RCRS_FALSE;
  526. else if (hr == PEP_S_CONTINUE)
  527. dwResult = PEP_RCRS_CONTINUE;
  528. else if (hr == PEP_S_CONTINUE_FALSE)
  529. dwResult = PEP_RCRS_CONTINUE_FALSE;
  530. else {
  531. ASSERT(FAILED(hr));
  532. dwResult = PEP_RCRS_FAILED;
  533. }
  534. return dwResult;
  535. }
  536. void pepHrCallToHrResult(HRESULT hrCall, HRESULT &hrResult)
  537. {
  538. if (hrCall == S_OK)
  539. hrResult = hrCall;
  540. else if (hrCall == S_FALSE) {
  541. ASSERT(hrResult == S_OK || hrResult == PEP_S_CONTINUE);
  542. hrResult = ((hrResult != PEP_S_CONTINUE) ? S_FALSE : PEP_S_CONTINUE_FALSE);
  543. }
  544. else if (hrCall == PEP_S_CONTINUE)
  545. hrCall = PEP_S_CONTINUE;
  546. else {
  547. ASSERT(FAILED(hrCall));
  548. hrResult = hrCall;
  549. }
  550. }
  551. BOOL replaceSubString(LPTSTR pszSrc, LPCTSTR pcszSub, LPCTSTR pcszReplace)
  552. {
  553. LPTSTR pszStart = NULL;
  554. // replace pcszSub in pszSrc with pcszReplace (assumes pcszReplace is shorter than pcszSub)
  555. if ((pszStart = StrStrI(pszSrc, pcszSub)) != NULL) {
  556. int iReplace, iCurrent;
  557. // replace the substring
  558. iReplace = StrLen(pcszReplace);
  559. iCurrent = StrLen(pcszSub);
  560. StrCpy(pszStart, pcszReplace);
  561. StrCpy(pszStart+iReplace, pszStart + iCurrent);
  562. return TRUE;
  563. }
  564. return FALSE;
  565. }