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.

1532 lines
35 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. Utils.c
  5. Abstract:
  6. none.
  7. Author:
  8. Shishir Pardikar [Shishirp] 01-jan-1995
  9. Revision History:
  10. Joe Linn [JoeLinn] 23-jan-97 Ported for use on NT
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. #pragma code_seg("PAGE")
  15. #ifndef CSC_RECORDMANAGER_WINNT
  16. #define WIN32_APIS
  17. #include "cshadow.h"
  18. #endif //ifndef CSC_RECORDMANAGER_WINNT
  19. #include <stdlib.h>
  20. #include <ctype.h>
  21. #include <string.h>
  22. // #include "error.h"
  23. #include <vmmreg.h> // Must be after error.h
  24. #include "vxdwraps.h"
  25. #define SIGN_BIT 0x80000000
  26. #define UCHAR_OFFLINE ((USHORT)'_')
  27. #define HIGH_ONE_SEC 0x98
  28. #define LOW_ONE_SEC 0x9680
  29. #pragma intrinsic (memcmp, memcpy, memset, strcat, strcmp, strcpy, strlen)
  30. #define cBackSlash '\\'
  31. #define cNull 0
  32. #ifdef MAYBE
  33. ULONG UlGetDefaultShadowStore(LPSTR lpDrive);
  34. #endif //MAYBE
  35. AssertData
  36. AssertError
  37. extern char pathbuff[MAX_PATH+1];
  38. extern char vszShadowDir[MAX_SHADOW_DIR_NAME+1];
  39. char vszEnableShadow[]="EnableShadow";
  40. char vszEnableRemoteLog[]="EnableRemoteLog";
  41. char vszEnableDisconnect[]="EnableDisconnect";
  42. char vszMaxShadowStoreHex[]="MaxShadowStoreHex";
  43. char vszMaxLogfileSize[]="MaxLogfileSize";
  44. char vszExcludeList[] = "ExcludeExtensions";
  45. char vszIncludeList[] = "IncludeExtensions";
  46. char vszExclDelim[]=" ;,";
  47. char vszRemoteAccess[]="System\\CurrentControlSet\\Services\\RemoteAccess";
  48. char vszRemoteConnection[]="Remote Connection";
  49. char vszEnableSpeadOpt[]="EnableSpeadOpt";
  50. char vszDefShadowDir[] = "c:\\shadow";
  51. char vszCSCDirName[] = "CSC\\";
  52. USHORT *rgwzHeuristicExtensionTab[] =
  53. {
  54. L".exe",
  55. L".dll"
  56. };
  57. #ifndef CSC_RECORDMANAGER_WINNT
  58. #pragma VxD_LOCKED_CODE_SEG
  59. #endif //ifndef CSC_RECORDMANAGER_WINNT
  60. int PUBLIC GetServerPart(
  61. LPPE lppeServer,
  62. USHORT *lpBuff,
  63. int cBuff
  64. )
  65. {
  66. return(PpeToSvr(lppeServer, (LPSTR)lpBuff, cBuff, UNICODE));
  67. }
  68. ULONG PUBLIC GetNextPathElement(
  69. LPPP lppp,
  70. ULONG indx,
  71. USHORT *lpBuff,
  72. ULONG cBuff
  73. )
  74. {
  75. LPPE lppe;
  76. #if VERBOSE > 3
  77. KdPrint(("GetNextPathElement: input index=%d \r\n", indx));
  78. #endif //VERBOSE > 3
  79. lppe = (LPPE)&(((LPBYTE)(lppp->pp_elements))[indx]);
  80. if (lpBuff)
  81. {
  82. Assert(cBuff);
  83. memset(lpBuff, 0, cBuff);
  84. memcpy(lpBuff, lppe->pe_unichars, min(lppe->pe_length-2, (int)cBuff));
  85. // UniToBCS(lpBuff, lppe->pe_unichars, lppe->pe_length-2, cBuff-1, BCS_OEM);
  86. }
  87. #if VERBOSE > 3
  88. KdPrint(("GetNextPathElement: output index=%d \r\n", indx));
  89. #endif //VERBOSE > 3
  90. indx += lppe->pe_length;
  91. return ((indx < IFSPathLength(lppp))?indx:0xffff);
  92. }
  93. VOID PUBLIC GetLeafPtr
  94. (
  95. PIOREQ pir,
  96. USHORT *lpBuff,
  97. ULONG cBuff
  98. )
  99. {
  100. LPPE lpLast;
  101. Assert(cBuff);
  102. lpLast = IFSLastElement((LPPP)(pir->ir_ppath));
  103. memset(lpBuff, 0, cBuff);
  104. memcpy(lpBuff, lpLast->pe_unichars, min(lpLast->pe_length-2, (int)cBuff));
  105. }
  106. VOID PUBLIC BreakPath(
  107. LPPP lppp,
  108. ULONG indx,
  109. USHORT *pusCookie
  110. )
  111. {
  112. USHORT u;
  113. LPPE lppe;
  114. #if VERBOSE > 3
  115. UniToBCSPath(pathbuff, &lppp->pp_elements[0], MAX_PATH, BCS_OEM);
  116. KdPrint(("BreakPath In %s \r\n", pathbuff));
  117. #endif //VERBOSE > 3
  118. *pusCookie = lppp->pp_totalLength;
  119. *(pusCookie+1) = lppp->pp_prefixLength;
  120. *(pusCookie+2) = 0;
  121. if (IFSPathLength(lppp) > indx)
  122. {
  123. if (!indx)
  124. {
  125. lppp->pp_totalLength = lppp->pp_prefixLength = 4;
  126. }
  127. else
  128. {
  129. for (lppe = lppp->pp_elements, u=0;;)
  130. {
  131. u += lppe->pe_length;
  132. // This condition must happen
  133. if (u >= indx)
  134. {
  135. lppp->pp_totalLength = u+4;
  136. lppp->pp_prefixLength = u - lppe->pe_length+4;
  137. break;
  138. }
  139. lppe = IFSNextElement(lppe);
  140. }
  141. }
  142. *(pusCookie+2) = *(USHORT *)&(((LPBYTE)(lppp->pp_elements))[indx]);
  143. *(USHORT *)&(((LPBYTE)(lppp->pp_elements))[indx]) = 0;
  144. }
  145. #if VERBOSE > 3
  146. KdPrint(("BreakPath saved=%x \r\n", uSav));
  147. UniToBCSPath(pathbuff, &lppp->pp_elements[0], MAX_PATH, BCS_OEM);
  148. KdPrint(("BreakPath out %s \r\n", pathbuff));
  149. #endif //VERBOSE > 3
  150. }
  151. VOID PUBLIC MendPath(
  152. LPPP lppp,
  153. ULONG indx,
  154. USHORT *pusCookie
  155. )
  156. {
  157. lppp->pp_totalLength = *pusCookie ;
  158. lppp->pp_prefixLength = *(pusCookie+1);
  159. if (indx < IFSPathLength(lppp))
  160. {
  161. *(USHORT *)&(((LPBYTE)(lppp->pp_elements))[indx])
  162. = *(pusCookie+2);
  163. }
  164. #if VERBOSE > 3
  165. UniToBCSPath(pathbuff, &lppp->pp_elements[0], MAX_PATH, BCS_OEM);
  166. KdPrint(("MendPath %s \r\n", pathbuff));
  167. #endif //VERBOSE > 3
  168. }
  169. int PUBLIC GetPathLevel(
  170. LPPP ppath
  171. )
  172. {
  173. PathElement *ppe;
  174. int level = 1;
  175. ppe = ppath->pp_elements;
  176. while(ppe->pe_length)
  177. {
  178. ++level;
  179. ppe = IFSNextElement(ppe);
  180. }
  181. return (level);
  182. }
  183. int PUBLIC HexToA(
  184. ULONG ulHex,
  185. LPSTR lpName,
  186. int count)
  187. {
  188. int i;
  189. LPSTR lp = lpName+count-1;
  190. UCHAR uch;
  191. for (i=0; i<count; ++i)
  192. {
  193. uch = (UCHAR)(ulHex & 0xf) + '0';
  194. if (uch > '9')
  195. uch += 7; // A becomes '0' + A + 7 which is 'A'
  196. *lp = uch;
  197. --lp;
  198. ulHex >>= 4;
  199. }
  200. *(lpName+count) = cNull;
  201. return 0;
  202. }
  203. ULONG PUBLIC AtoHex(
  204. LPSTR lpStr,
  205. int count
  206. )
  207. {
  208. int i;
  209. LPSTR lp = lpStr;
  210. UCHAR uch;
  211. ULONG ulHex = 0L;
  212. for (i=0; i<count; ++i)
  213. {
  214. uch = *lp;
  215. if (uch>= '0' && uch <= '9')
  216. ulHex += (uch - '0');
  217. else if (uch >= 'A' && uch <= 'F')
  218. ulHex += (uch - '0' - 7);
  219. else
  220. break;
  221. ++lp;
  222. ulHex <<= 4;
  223. }
  224. return ulHex;
  225. }
  226. int PpeToSvr( LPPE lppe,
  227. LPSTR lpBuff,
  228. int cBuff,
  229. ULONG type
  230. )
  231. {
  232. LPSTR lpTmp = lpBuff;
  233. memset(lpTmp, 0, cBuff);
  234. if (type != UNICODE)
  235. {
  236. if (cBuff <= (lppe->pe_length+IFSNextElement(lppe)->pe_length)/2)
  237. return 0;
  238. *lpTmp = '\\';
  239. UniToBCS(lpTmp+1, lppe->pe_unichars, lppe->pe_length-2, cBuff, BCS_OEM);
  240. lpTmp += (lppe->pe_length)/2;
  241. lppe = IFSNextElement(lppe);
  242. *lpTmp = '\\';
  243. UniToBCS(lpTmp+1, lppe->pe_unichars, lppe->pe_length-2, cBuff, BCS_OEM);
  244. }
  245. else
  246. {
  247. USHORT *lpUni;
  248. lpUni = (USHORT *)lpTmp;
  249. if (cBuff < (lppe->pe_length+IFSNextElement(lppe)->pe_length))
  250. return 0;
  251. *lpUni = '\\';
  252. memcpy(lpUni+1, lppe->pe_unichars, lppe->pe_length);
  253. lpUni = (USHORT *)((LPSTR)lpUni+lppe->pe_length);
  254. lppe = IFSNextElement(lppe);
  255. *lpUni = '\\';
  256. memcpy(lpUni+1, lppe->pe_unichars, lppe->pe_length);
  257. }
  258. return (1);
  259. }
  260. int IPathCompare( LPPP lpppDst,
  261. LPPP lpppSrc
  262. )
  263. {
  264. LPPE lppeDst, lppeSrc;
  265. if (lpppDst->pp_totalLength != lpppSrc->pp_totalLength)
  266. return -1;
  267. if (lpppDst->pp_prefixLength != lpppSrc->pp_prefixLength)
  268. return -1;
  269. lppeDst = lpppDst->pp_elements;
  270. lppeSrc = lpppSrc->pp_elements;
  271. for (;;)
  272. {
  273. if (!lppeDst->pe_length || !lppeSrc->pe_length)
  274. break;
  275. if (lppeDst->pe_length != lppeSrc->pe_length)
  276. return -1;
  277. if (wstrnicmp(lppeDst->pe_unichars, lppeSrc->pe_unichars, lppeSrc->pe_length))
  278. return -1;
  279. lppeDst = IFSNextElement(lppeDst);
  280. lppeSrc = IFSNextElement(lppeSrc);
  281. }
  282. return 0;
  283. }
  284. int wstrnicmp( const USHORT *pStr1,
  285. const USHORT *pStr2,
  286. ULONG count
  287. )
  288. {
  289. USHORT c1, c2;
  290. int iRet;
  291. ULONG i=0;
  292. for(;;)
  293. {
  294. c1 = *pStr1++;
  295. c2 = *pStr2++;
  296. c1 = _wtoupper(c1);
  297. c2 = _wtoupper(c2);
  298. if (c1!=c2)
  299. break;
  300. if (!c1)
  301. break;
  302. i+=2;
  303. if (i >= count)
  304. break;
  305. }
  306. iRet = ((c1 > c2)?1:((c1==c2)?0:-1));
  307. return iRet;
  308. }
  309. #ifndef CSC_RECORDMANAGER_WINNT
  310. int mystrnicmp(
  311. const char *pStr1,
  312. const char *pStr2,
  313. unsigned count
  314. )
  315. #else
  316. _CRTIMP int __cdecl mystrnicmp(
  317. const char *pStr1,
  318. const char *pStr2,
  319. size_t count
  320. )
  321. #endif //ifndef CSC_RECORDMANAGER_WINNT
  322. {
  323. char c1, c2;
  324. int iRet;
  325. ULONG i=0;
  326. for(;;)
  327. {
  328. c1 = *pStr1++;
  329. c2 = *pStr2++;
  330. c1 = _mytoupper(c1);
  331. c2 = _mytoupper(c2);
  332. if (c1!=c2)
  333. break;
  334. if (!c1)
  335. break;
  336. if (++i >= count)
  337. break;
  338. }
  339. iRet = ((c1 > c2)?1:((c1==c2)?0:-1));
  340. return iRet;
  341. }
  342. ULONG strmcpy( LPSTR lpDst,
  343. LPSTR lpSrc,
  344. ULONG cTchar
  345. )
  346. {
  347. ULONG i;
  348. if (!cTchar)
  349. return 0;
  350. for(i=cTchar;i;--i)
  351. if (!(*lpDst++ = *lpSrc++))
  352. break;
  353. lpDst[cTchar-i] ='\0';
  354. return(cTchar-i);
  355. }
  356. ULONG wstrlen(
  357. USHORT *lpuStr
  358. )
  359. {
  360. ULONG i;
  361. for (i=0; *lpuStr; ++lpuStr, ++i);
  362. return (i);
  363. }
  364. int DosToWin32FileSize( ULONG uDosFileSize,
  365. int *lpnFileSizeHigh,
  366. int *lpnFileSizeLow
  367. )
  368. {
  369. int iRet;
  370. if (uDosFileSize & SIGN_BIT)
  371. {
  372. *lpnFileSizeHigh = 1;
  373. *lpnFileSizeLow = uDosFileSize & SIGN_BIT;
  374. iRet = 1;
  375. }
  376. else
  377. {
  378. *lpnFileSizeHigh = 0;
  379. *lpnFileSizeLow = uDosFileSize;
  380. iRet = 0;
  381. }
  382. return (iRet);
  383. }
  384. int Win32ToDosFileSize( int nFileSizeHigh,
  385. int nFileSizeLow,
  386. ULONG *lpuDosFileSize
  387. )
  388. {
  389. int iRet;
  390. *lpuDosFileSize = nFileSizeLow;
  391. if (nFileSizeHigh == 1)
  392. {
  393. *lpuDosFileSize += SIGN_BIT;
  394. iRet = 1;
  395. }
  396. else
  397. iRet = 0;
  398. return (iRet);
  399. }
  400. int CompareTimes( _FILETIME ftDst,
  401. _FILETIME ftSrc
  402. )
  403. {
  404. int iRet = 0;
  405. if (ftDst.dwHighDateTime
  406. > ftSrc.dwHighDateTime)
  407. iRet = 1;
  408. else if (ftDst.dwHighDateTime == ftSrc.dwHighDateTime)
  409. {
  410. if (ftDst.dwLowDateTime > ftSrc.dwLowDateTime)
  411. iRet = 1;
  412. else if (ftDst.dwLowDateTime == ftSrc.dwLowDateTime)
  413. iRet = 0;
  414. else
  415. iRet = -1;
  416. }
  417. else
  418. iRet = -1;
  419. return (iRet);
  420. }
  421. int CompareTimesAtDosTimePrecision( _FILETIME ftDst,
  422. _FILETIME ftSrc
  423. )
  424. {
  425. dos_time dostDst, dostSrc;
  426. int diff;
  427. dostDst = IFSMgr_Win32ToDosTime(ftDst);
  428. dostSrc = IFSMgr_Win32ToDosTime(ftSrc);
  429. diff = (int)(*(ULONG *)&dostDst - *(ULONG *)&dostSrc);
  430. if (diff > 1)
  431. return 1;
  432. else if (diff < -1)
  433. return -1;
  434. else
  435. return 0;
  436. }
  437. int CompareSize(
  438. long nHighDst,
  439. long nLowDst,
  440. long nHighSrc,
  441. long nLowSrc
  442. )
  443. {
  444. int iRet = 0;
  445. if (nHighDst > nHighSrc)
  446. iRet = 1;
  447. else if (nHighDst == nHighSrc)
  448. {
  449. if (nLowDst > nLowSrc)
  450. iRet = 1;
  451. else if (nLowDst == nLowSrc)
  452. iRet = 0;
  453. else
  454. iRet = -1;
  455. }
  456. else
  457. iRet = -1;
  458. return (iRet);
  459. }
  460. void InitFind32FromIoreq
  461. (
  462. PIOREQ pir,
  463. LPFIND32 lpFind32,
  464. ULONG uFlags
  465. )
  466. {
  467. if (uFlags & IF32_LOCAL)
  468. {
  469. memset(lpFind32, 0, sizeof(WIN32_FIND_DATA));
  470. InitFind32Names(lpFind32,
  471. ((pir->ir_attr & FILE_FLAG_KEEP_CASE)&&(uFlags&IF32_LAST_ELEMENT))?
  472. pir->ir_uFName:
  473. IFSLastElement(pir->ir_ppath)->pe_unichars,
  474. (pir->ir_attr & FILE_FLAG_IS_LFN)? NULL:IFSLastElement((LPPP)(pir->ir_ppath))->pe_unichars);
  475. }
  476. if (!(uFlags & IF32_DIRECTORY))
  477. {
  478. lpFind32->dwFileAttributes =
  479. ((((pir->ir_attr) & ~FILE_ATTRIBUTE_DIRECTORY) | FILE_ATTRIBUTE_ARCHIVE)
  480. & FILE_ATTRIBUTE_EVERYTHING);
  481. }
  482. else
  483. {
  484. lpFind32->dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
  485. }
  486. if (uFlags & IF32_LOCAL)
  487. {
  488. //CODE.IMPROVEMENT very ugly.....define a platform specific macro....
  489. #ifndef CSC_RECORDMANAGER_WINNT
  490. lpFind32->ftCreationTime = IFSMgr_NetToWin32Time(IFSMgr_Get_NetTime());
  491. #else
  492. //lpFind32->ftCreationTime = IFSMgr_NetToWin32Time(IFSMgr_Get_NetTime());
  493. KeQuerySystemTime(((PLARGE_INTEGER)(&lpFind32->ftCreationTime)));
  494. #endif //ifndef CSC_RECORDMANAGER_WINNT
  495. lpFind32->ftLastAccessTime = lpFind32->ftLastWriteTime = lpFind32->ftCreationTime;
  496. }
  497. lpFind32->nFileSizeHigh = lpFind32->nFileSizeLow = 0;
  498. }
  499. void InitIoreqFromFind32
  500. (
  501. LPFIND32 lpFind32,
  502. PIOREQ pir
  503. )
  504. {
  505. pir->ir_attr = lpFind32->dwFileAttributes;
  506. pir->ir_size = lpFind32->nFileSizeLow;
  507. }
  508. void InitFind32Names( LPFIND32 lpFind32,
  509. USHORT *lpcFileName,
  510. USHORT *lpcAlternateFileName
  511. )
  512. {
  513. int len;
  514. memset(lpFind32->cFileName, 0, sizeof(lpFind32->cFileName));
  515. memset(lpFind32->cAlternateFileName, 0, sizeof(lpFind32->cAlternateFileName));
  516. len = wstrlen(lpcFileName)*2;
  517. len = min(len, (sizeof(lpFind32->cFileName)-2));
  518. memcpy(lpFind32->cFileName, lpcFileName, len);
  519. if (lpcAlternateFileName)
  520. {
  521. len = wstrlen(lpcAlternateFileName)*2;
  522. len = min(len, (sizeof(lpFind32->cAlternateFileName)-2));
  523. memset(lpFind32->cAlternateFileName, 0, sizeof(lpFind32->cAlternateFileName));
  524. UniToUpper(lpFind32->cAlternateFileName, lpcAlternateFileName, len);
  525. }
  526. }
  527. void Find32ToSearchEntry(LPFIND32 lpFind32, srch_entry *pse)
  528. {
  529. dos_time sDosTime;
  530. pse->se_attrib = (UCHAR)(lpFind32->dwFileAttributes);
  531. sDosTime = IFSMgr_Win32ToDosTime(lpFind32->ftLastWriteTime);
  532. pse->se_time = sDosTime.dt_time;
  533. pse->se_date = sDosTime.dt_date;
  534. Win32ToDosFileSize(lpFind32->nFileSizeHigh
  535. , lpFind32->nFileSizeLow
  536. , &(pse->se_size));
  537. memset(pse->se_name, 0, sizeof(pse->se_name));
  538. UniToBCS(pse->se_name
  539. , lpFind32->cAlternateFileName
  540. , wstrlen(lpFind32->cAlternateFileName) * 2
  541. , sizeof(pse->se_name)-1, BCS_OEM);
  542. }
  543. void PUBLIC Find32AFromFind32(
  544. LPFIND32A lpFind32ADst,
  545. LPFIND32 lpFind32WSrc,
  546. int type
  547. )
  548. {
  549. // Copy everything except the names, we know the size of that is the
  550. // same for both structures
  551. memcpy(lpFind32ADst, lpFind32WSrc, sizeof(_WIN32_FIND_DATAA)
  552. -sizeof(lpFind32ADst->cFileName)
  553. -sizeof(lpFind32ADst->cAlternateFileName));
  554. // Cleanup the destineation names so we don't get into NULL termination problems
  555. memset(lpFind32ADst->cFileName, 0, sizeof(lpFind32ADst->cFileName));
  556. memset(lpFind32ADst->cAlternateFileName, 0, sizeof(lpFind32ADst->cAlternateFileName));
  557. UniToBCS(lpFind32ADst->cFileName // Destination ANSI string
  558. , lpFind32WSrc->cFileName // Source unicode string
  559. , sizeof(lpFind32WSrc->cFileName) // bytes in the source
  560. - sizeof(lpFind32WSrc->cFileName[0])
  561. , sizeof(lpFind32ADst->cFileName) // max size of dst string wo NULL
  562. -sizeof(lpFind32ADst->cFileName[0])
  563. , type // ANSI or OEM
  564. );
  565. UniToBCS(lpFind32ADst->cAlternateFileName
  566. , lpFind32WSrc->cAlternateFileName
  567. , sizeof(lpFind32WSrc->cAlternateFileName)
  568. - sizeof(lpFind32WSrc->cAlternateFileName[0])
  569. , sizeof(lpFind32ADst->cAlternateFileName)
  570. -sizeof(lpFind32ADst->cAlternateFileName[0])
  571. , BCS_OEM);
  572. }
  573. void PUBLIC Find32FromFind32A(
  574. LPFIND32 lpFind32WDst,
  575. LPFIND32A lpFind32ASrc,
  576. int type
  577. )
  578. {
  579. memcpy(lpFind32WDst, lpFind32ASrc, sizeof(_WIN32_FIND_DATAA)
  580. -sizeof(lpFind32ASrc->cFileName)
  581. -sizeof(lpFind32ASrc->cAlternateFileName));
  582. memset(lpFind32WDst->cFileName, 0, sizeof(lpFind32WDst->cFileName));
  583. memset(lpFind32WDst->cAlternateFileName, 0, sizeof(lpFind32WDst->cAlternateFileName));
  584. BCSToUni(lpFind32WDst->cFileName
  585. , lpFind32ASrc->cFileName
  586. , sizeof(lpFind32ASrc->cFileName)
  587. - sizeof(lpFind32ASrc->cFileName[0])
  588. , type);
  589. BCSToUni(lpFind32WDst->cAlternateFileName
  590. , lpFind32ASrc->cAlternateFileName
  591. , sizeof(lpFind32ASrc->cAlternateFileName)
  592. - sizeof(lpFind32ASrc->cAlternateFileName[0])
  593. , BCS_OEM);
  594. }
  595. //** AddPathElement
  596. //
  597. // This routine adds a path element to an existing parsed path structure
  598. //
  599. // flag = 0 - no mapping
  600. // 1 - map from OEM to unicode
  601. //
  602. void AddPathElement( path_t ppath,
  603. string_t pstr,
  604. int flag)
  605. {
  606. PathElement *ppe;
  607. int len, unilen;
  608. ppe = IFSLastElement(ppath);
  609. ppath->pp_prefixLength+=ppe->pe_length; //update the prefix marker
  610. ppe = IFSNextElement(ppe);
  611. //add the new element
  612. if (flag)
  613. {
  614. //map to unicode
  615. len = strlen((char *)pstr);
  616. unilen = BCSToUni(ppe->pe_unichars, (char *) pstr, len, BCS_OEM);
  617. }
  618. else
  619. {
  620. //already in unicode
  621. unilen = wstrlen(pstr)*sizeof(USHORT);
  622. memcpy(ppe->pe_unichars, pstr, unilen);
  623. }
  624. ppe->pe_length = (USHORT)(unilen+sizeof(USHORT)); //include the length word
  625. //update the header
  626. ppath->pp_totalLength+=ppe->pe_length; //update total length
  627. //mark the end
  628. ppe = IFSNextElement(ppe);
  629. ppe->pe_length = 0;
  630. }
  631. //** MakePath
  632. //
  633. // Builds a parsed path from a ASCII string in the format "\\FOO\BAR.."
  634. //
  635. // ppath - points to a path buffer at least PATH_BUFF_SIZE
  636. // ppath - OEM path string
  637. //
  638. void MakePPath( path_t ppath,
  639. LPBYTE ps
  640. )
  641. {
  642. LPBYTE pc = ps;
  643. MakeNullPPath(ppath); //initialize the path
  644. while(*pc == '\\') //skip past leading '\'
  645. {
  646. pc++;
  647. }
  648. if (ps[0] =='\\') //ps points to first name
  649. {
  650. ps++;
  651. }
  652. for (;;)
  653. {
  654. if (*pc == '\\')
  655. {
  656. *pc = 0;
  657. AddPathElement(ppath, (string_t)ps, 1);
  658. *pc = '\\';
  659. ps = ++pc;
  660. }
  661. else if (*pc == 0)
  662. {
  663. AddPathElement(ppath, (string_t)ps, 1);
  664. break;
  665. }
  666. pc++;
  667. }
  668. }
  669. //** MakePathW
  670. //
  671. // Builds a parsed path from a unicode string in the format "\\FOO\BAR.."
  672. //
  673. // ppath - points to a path buffer at least PATH_BUFF_SIZE
  674. // ppath - OEM path string
  675. //
  676. void MakePPathW( path_t ppath,
  677. USHORT *puName
  678. )
  679. {
  680. USHORT *pu = puName;
  681. MakeNullPPath(ppath); //initialize the path
  682. while(*pu == L'\\') //skip past leading '\'
  683. {
  684. pu++;
  685. }
  686. if (pu[0] == L'\\') //ps points to first name
  687. {
  688. pu++;
  689. }
  690. for (;;)
  691. {
  692. if (*pu == L'\\')
  693. {
  694. *pu = 0;
  695. AddPathElement(ppath, (string_t)puName, 0);
  696. *pu = L'\\';
  697. puName = ++pu;
  698. }
  699. else if (*pu == 0)
  700. {
  701. AddPathElement(ppath, (string_t)puName, 0);
  702. break;
  703. }
  704. pu++;
  705. }
  706. }
  707. //** DeleteLastElement
  708. //
  709. // removes the last element from a parsed path
  710. //
  711. void DeleteLastElement( path_t ppath
  712. )
  713. {
  714. PathElement *ppe, *ppelast;
  715. ppe = IFSLastElement(ppath);
  716. ppath->pp_totalLength -= ppe->pe_length;
  717. ppe->pe_length = 0;
  718. //set the new prefix length
  719. ppe = ppath->pp_elements;
  720. ppath->pp_prefixLength = 4;
  721. while(ppe->pe_length)
  722. {
  723. ppelast = ppe;
  724. ppe = IFSNextElement(ppe);
  725. if (ppe)
  726. ppath->pp_prefixLength += ppelast->pe_length;
  727. }
  728. }
  729. int ResNameCmp(
  730. LPPE lppeSrc,
  731. LPPE lppeDst
  732. )
  733. {
  734. int i;
  735. for (i=0; i<2; ++i)
  736. {
  737. if (lppeSrc->pe_length != lppeDst->pe_length)
  738. break;
  739. if (wstrnicmp(lppeSrc->pe_unichars
  740. , lppeDst->pe_unichars
  741. , lppeSrc->pe_length-sizeof(lppeDst->pe_length)))
  742. break;
  743. lppeSrc = IFSNextElement(lppeSrc);
  744. lppeDst = IFSNextElement(lppeDst);
  745. }
  746. return (!(i==2));//return 0 if equal
  747. }
  748. int Conv83ToFcb(
  749. LPSTR lp83Name,
  750. LPSTR lpFcbName
  751. )
  752. {
  753. int i, j;
  754. char ch;
  755. memset(lpFcbName, ' ', 11);
  756. for(i=0; ((ch=lp83Name[i]) && (i<8)); ++i)
  757. {
  758. if (ch=='.')
  759. break;
  760. lpFcbName[i] = ch;
  761. }
  762. if (lp83Name[i]=='.')
  763. {
  764. // Step over the dot
  765. ++i;
  766. // point to the extension area in the FCB format
  767. j = 8;
  768. for(;((ch=lp83Name[i]) && (j<11)); ++i, ++j)
  769. {
  770. lpFcbName[j] = ch;
  771. }
  772. return (i);
  773. }
  774. else
  775. {
  776. return (i);
  777. }
  778. }
  779. int Conv83UniToFcbUni(
  780. USHORT *lp83Name,
  781. USHORT *lpFcbName
  782. )
  783. {
  784. int i, j;
  785. USHORT uch;
  786. for (i=0; i<11; ++i)
  787. {
  788. lpFcbName[i] = (USHORT)' ';
  789. }
  790. for(i=0; ((uch=lp83Name[i]) && (i<8)); ++i)
  791. {
  792. if (uch==(USHORT)'.')
  793. break;
  794. lpFcbName[i] = uch;
  795. }
  796. if (lp83Name[i]=='.')
  797. {
  798. // Step over the dot
  799. ++i;
  800. // point to the extension area in the FCB format
  801. j = 8;
  802. for(;((uch=lp83Name[i]) && (j<11)); ++i, ++j)
  803. {
  804. lpFcbName[j] = uch;
  805. }
  806. return (i);
  807. }
  808. else
  809. {
  810. return (i);
  811. }
  812. }
  813. void FillRootInfo(
  814. LPFIND32 lpFind32
  815. )
  816. {
  817. memset(lpFind32, 0, sizeof(WIN32_FIND_DATA));
  818. lpFind32->dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
  819. lpFind32->cFileName[0] = lpFind32->cAlternateFileName[0] = '\\';
  820. }
  821. int ReadInitValues()
  822. {
  823. VMMHKEY hKeyShadow;
  824. LPSTR lpWindir = NULL;
  825. int iSize = sizeof(int), lenWindir=0;
  826. DWORD dwType;
  827. extern int fLog, fShadow, fDiscon, fSpeadOpt, vlenShadowDir;
  828. extern ULONG ulMaxStoreSize, ulMaxLogfileSize;
  829. extern LPSTR vlpszShadowDir;
  830. if (_RegOpenKey(HKEY_LOCAL_MACHINE, REG_KEY_SHADOW, &hKeyShadow) == ERROR_SUCCESS)
  831. {
  832. #ifdef CSC_RECORDMANAGER_WINNT
  833. memset(vszShadowDir, 0, sizeof(vszShadowDir));
  834. iSize = MAX_SHADOW_DIR_NAME+1;
  835. if(_RegQueryValueEx(hKeyShadow, REG_STRING_DATABASE_LOCATION, NULL, &dwType, vszShadowDir, &iSize)!=ERROR_SUCCESS)
  836. {
  837. Assert(strlen(vszDefShadowDir) <= MAX_SHADOW_DIR_NAME);
  838. KdPrint(("ReadInitValues: No vszShadowDb value in registry\r\n"));
  839. memcpy(vszShadowDir, vszDefShadowDir, strlen(vszDefShadowDir));
  840. }
  841. #else
  842. #ifdef OLDCODE
  843. lpWindir = (LPSTR)GetConfigDir();
  844. if (!lpWindir)
  845. {
  846. // VMM promises this to be valid!!!
  847. Assert(FALSE);
  848. return (0);
  849. }
  850. lenWindir = strlen(lpWindir);
  851. vlpszShadowDir = AllocMem(lenWindir+strlen(vszCSCDirName)+3);
  852. if (!vlpszShadowDir)
  853. {
  854. KdPrint(("ReadInitValues: Failed memroy allocation while\r\n"));
  855. return (0);
  856. }
  857. memcpy(vlpszShadowDir, lpWindir, lenWindir);
  858. if ((*(lpWindir+lenWindir-1))!='\\')
  859. {
  860. *(vlpszShadowDir+lenWindir)='\\';
  861. }
  862. // NB vszCSCDirName has a trailing backslash
  863. strcat(vlpszShadowDir, vszCSCDirName);
  864. vlenShadowDir = strlen(vlpszShadowDir);
  865. KdPrint(("ReadInitValues: ShadowDbDir is %s\r\n", vlpszShadowDir));
  866. #endif // OLDCODE
  867. #endif // CSC_RECORDMANAGER_WINNT
  868. #ifdef MAYBE
  869. // we should let the agent decide whether shadowing should be on or off
  870. _RegQueryValueEx(hKeyShadow, vszEnableShadow, NULL, &dwType, &fShadow, &iSize);
  871. #endif // MAYBE
  872. iSize = sizeof(int);
  873. _RegQueryValueEx(hKeyShadow, vszEnableRemoteLog, NULL, &dwType, &fLog, &iSize);
  874. iSize = sizeof(int);
  875. _RegQueryValueEx(hKeyShadow, vszEnableDisconnect, NULL, &dwType, &fDiscon, &iSize);
  876. iSize = sizeof(int);
  877. _RegQueryValueEx(hKeyShadow, vszEnableSpeadOpt, NULL, &dwType, &fSpeadOpt, &iSize);
  878. iSize = sizeof(ULONG);
  879. _RegQueryValueEx(hKeyShadow, vszMaxShadowStoreHex, NULL, &dwType, &ulMaxStoreSize, &iSize);
  880. iSize = sizeof(ULONG);
  881. if(_RegQueryValueEx(hKeyShadow, vszMaxLogfileSize, NULL, &dwType, &ulMaxLogfileSize, &iSize)!=ERROR_SUCCESS)
  882. {
  883. ulMaxLogfileSize = MAX_LOGFILE_SIZE;
  884. }
  885. else if (ulMaxLogfileSize < MIN_LOGFILE_SIZE)
  886. {
  887. ulMaxLogfileSize = MIN_LOGFILE_SIZE;
  888. }
  889. _RegCloseKey(hKeyShadow);
  890. ulMaxStoreSize = 0xffffffff;
  891. #ifdef MAYBE
  892. ulMaxStoreSize = UlGetDefaultShadowStore(vszShadowDir);
  893. #endif //MAYBE
  894. return(1);
  895. }
  896. return (0);
  897. }
  898. BOOL IsSlowLink()
  899. {
  900. VMMHKEY hKeyRemote;
  901. int iSize = sizeof(int), fRemote=0;
  902. DWORD dwType;
  903. if (_RegOpenKey(HKEY_LOCAL_MACHINE, vszRemoteAccess, &hKeyRemote) == ERROR_SUCCESS)
  904. {
  905. _RegQueryValueEx(hKeyRemote, vszRemoteConnection, NULL, &dwType, &fRemote, &iSize);
  906. _RegCloseKey(hKeyRemote);
  907. }
  908. return (fRemote);
  909. }
  910. BOOL FHasWildcard(
  911. USHORT *lpuName,
  912. int cMax
  913. )
  914. {
  915. int i;
  916. BOOL fRet = FALSE;
  917. USHORT uT;
  918. for (i=0; i<cMax; ++i)
  919. {
  920. uT = *(lpuName+i);
  921. if (!uT)
  922. break;
  923. if (fRet = ((uT==(USHORT)'*')||(uT == (USHORT)'?')))
  924. break;
  925. }
  926. return (fRet);
  927. }
  928. int IncrementTime(
  929. LPFILETIME lpFt,
  930. int secs
  931. )
  932. {
  933. lpFt->dwHighDateTime += secs*(HIGH_ONE_SEC+1);
  934. return(0); //stop complaining about no return value
  935. }
  936. int FParentMatch(
  937. LPPP lpp1,
  938. LPPP lpp2
  939. )
  940. {
  941. PathElement *ppe1, *ppe2, *ppe1Last, *ppe2Last;
  942. int fMatch = FALSE;
  943. //If either of them is root then say they have invalid parents
  944. if (IFSIsRoot(lpp1) || IFSIsRoot(lpp2))
  945. return 0;
  946. ppe1Last = IFSLastElement(lpp1);
  947. ppe2Last = IFSLastElement(lpp2);
  948. ppe1 = lpp1->pp_elements;
  949. ppe2 = lpp2->pp_elements;
  950. while((ppe1!=ppe1Last) && (ppe2!= ppe2Last))
  951. {
  952. if (ppe1->pe_length!=ppe1->pe_length)
  953. return 0;
  954. if (wstrnicmp(ppe1->pe_unichars, ppe2->pe_unichars, ppe1->pe_length-2))
  955. return 0;
  956. ppe1 = IFSNextElement(ppe1);
  957. ppe2 = IFSNextElement(ppe2);
  958. }
  959. return ((ppe1==ppe1Last) && (ppe2==ppe2Last));
  960. }
  961. LPSTR mystrpbrk(
  962. LPSTR lpSrc,
  963. LPSTR lpDelim
  964. )
  965. {
  966. char c, c1;
  967. LPSTR lpSav;
  968. BOOL fBegin = FALSE;
  969. for(;c = *lpSrc; ++lpSrc)
  970. {
  971. // skip leading blanks
  972. if (!fBegin)
  973. {
  974. if (c==' ')
  975. continue;
  976. else
  977. fBegin = TRUE;
  978. }
  979. lpSav = lpDelim;
  980. while (c1 = *lpDelim++)
  981. {
  982. if (c==c1)
  983. return (lpSrc);
  984. }
  985. lpDelim = lpSav;
  986. }
  987. return (NULL);
  988. }
  989. LPWSTR
  990. wstrpbrk(
  991. LPWSTR lpSrc,
  992. LPWSTR lpDelim
  993. )
  994. {
  995. USHORT c, c1;
  996. LPWSTR lpSav;
  997. BOOL fBegin = FALSE;
  998. for(;c = *lpSrc; ++lpSrc)
  999. {
  1000. // skip leading blanks
  1001. if (!fBegin)
  1002. {
  1003. if (c==L' ')
  1004. {
  1005. continue;
  1006. }
  1007. else
  1008. {
  1009. fBegin = TRUE;
  1010. }
  1011. }
  1012. lpSav = lpDelim;
  1013. while (c1 = *lpDelim++)
  1014. {
  1015. if (c==c1)
  1016. {
  1017. return (lpSrc);
  1018. }
  1019. }
  1020. lpDelim = lpSav;
  1021. }
  1022. return (NULL);
  1023. }
  1024. int OfflineToOnlinePath
  1025. (
  1026. path_t ppath
  1027. )
  1028. {
  1029. if (!IFSIsRoot(ppath) && IsOfflinePE(ppath->pp_elements))
  1030. {
  1031. OfflineToOnlinePE(ppath->pp_elements);
  1032. ppath->pp_totalLength -= sizeof(USHORT);
  1033. ppath->pp_prefixLength-= sizeof(USHORT);
  1034. }
  1035. return(0); //stop complaining about no return value
  1036. }
  1037. int OnlineToOfflinePath
  1038. (
  1039. path_t ppath
  1040. )
  1041. {
  1042. // Must have space for one extra character
  1043. OnlineToOfflinePE(ppath->pp_elements);
  1044. ppath->pp_totalLength += sizeof(USHORT);
  1045. ppath->pp_prefixLength += sizeof(USHORT);
  1046. return(0); //stop complaining about no return value
  1047. }
  1048. BOOL IsOfflinePE
  1049. (
  1050. LPPE lppe
  1051. )
  1052. {
  1053. return(lppe->pe_unichars[1] == UCHAR_OFFLINE);
  1054. }
  1055. int OfflineToOnlinePE
  1056. (
  1057. LPPE lppe
  1058. )
  1059. {
  1060. ULONG size;
  1061. size = wstrlen(lppe->pe_unichars)*2+2;
  1062. mymemmove(&(lppe->pe_unichars[1])
  1063. ,&(lppe->pe_unichars[2])
  1064. ,size-2*sizeof(USHORT));
  1065. lppe->pe_length-= sizeof(USHORT);
  1066. return(0); //stop complaining about no return value
  1067. }
  1068. int OnlineToOfflinePE
  1069. (
  1070. LPPE lppe
  1071. )
  1072. {
  1073. ULONG size;
  1074. size = wstrlen(lppe->pe_unichars)*2+2;
  1075. // Must have space for one extra character
  1076. mymemmove(&(lppe->pe_unichars[2])
  1077. ,&(lppe->pe_unichars[1])
  1078. ,size-sizeof(USHORT));
  1079. lppe->pe_unichars[1] = UCHAR_OFFLINE;
  1080. lppe->pe_length += sizeof(USHORT);
  1081. return(0); //stop complaining about no return value
  1082. }
  1083. BOOL IsOfflineUni(
  1084. USHORT *lpuName
  1085. )
  1086. {
  1087. return(lpuName[2] == UCHAR_OFFLINE);
  1088. }
  1089. int OfflineToOnlineUni(
  1090. USHORT *lpuName,
  1091. ULONG size)
  1092. {
  1093. if (!size)
  1094. {
  1095. size = wstrlen(lpuName)*2+2;
  1096. }
  1097. mymemmove(&(lpuName[2])
  1098. ,&(lpuName[3])
  1099. ,size-3*sizeof(short));
  1100. return(0); //stop complaining about no return value
  1101. }
  1102. int OnlineToOfflineUni(
  1103. USHORT *lpuName,
  1104. ULONG size)
  1105. {
  1106. if (!size)
  1107. {
  1108. size = wstrlen(lpuName)*2+2;
  1109. }
  1110. // Must have space for one extra character
  1111. mymemmove(&(lpuName[3])
  1112. ,&(lpuName[2])
  1113. ,size-2*sizeof(USHORT));
  1114. lpuName[2] = UCHAR_OFFLINE;
  1115. return(0); //stop complaining about no return value
  1116. }
  1117. LPVOID mymemmove(
  1118. LPVOID lpDst,
  1119. LPVOID lpSrc,
  1120. ULONG size
  1121. )
  1122. {
  1123. int i;
  1124. if (!size)
  1125. return (lpDst);
  1126. // if lpDst does not fall within the source array, just do memcpy
  1127. if (!(
  1128. ( lpDst > lpSrc )
  1129. && ( ((LPBYTE)lpDst) < ((LPBYTE)lpSrc)+size ) ))
  1130. {
  1131. memcpy(lpDst, lpSrc, size);
  1132. }
  1133. else
  1134. {
  1135. // do reverse copy
  1136. for (i=size-1;i>=0;--i)
  1137. {
  1138. *((LPBYTE)lpDst+i) = *((LPBYTE)lpSrc+i);
  1139. }
  1140. }
  1141. return (lpDst);
  1142. }
  1143. #ifdef MAYBE
  1144. ULONG UlGetDefaultShadowStore(LPSTR lpDrive)
  1145. {
  1146. int indx;
  1147. ULONG ulSize=0;
  1148. ULONG uSectorsPerCluster, uBytesPerSector, uFreeClusters, uTotalClusters;
  1149. if (indx = GetDriveIndex(lpDrive))
  1150. {
  1151. if (GetDiskFreeSpace(indx , &uSectorsPerCluster
  1152. , &uBytesPerSector
  1153. , &uFreeClusters
  1154. , &uTotalClusters) >= 0)
  1155. {
  1156. ulSize = (uTotalClusters * uSectorsPerCluster * uBytesPerSector * 10)/100;
  1157. }
  1158. }
  1159. return ulSize;
  1160. }
  1161. #endif //MAYBE
  1162. #ifndef CSC_RECORDMANAGER_WINNT
  1163. int GetDriveIndex(LPSTR lpDrive)
  1164. {
  1165. int c;
  1166. if (*(lpDrive+1)==':')
  1167. {
  1168. c = *lpDrive;
  1169. c = _mytoupper(c);
  1170. return (c - 'A'+1);
  1171. }
  1172. return (0);
  1173. }
  1174. #endif
  1175. BOOL
  1176. HasHeuristicTypeExtensions(
  1177. USHORT *lpwzFileName
  1178. )
  1179. {
  1180. ULONG lenName = wstrlen(lpwzFileName);
  1181. int i;
  1182. if (lenName > 4)
  1183. {
  1184. for (i=0; i<(sizeof(rgwzHeuristicExtensionTab)/sizeof(USHORT *)); ++i)
  1185. {
  1186. if (!wstrnicmp(&lpwzFileName[lenName-4], rgwzHeuristicExtensionTab[i], 4*sizeof(USHORT)))
  1187. {
  1188. return (TRUE);
  1189. }
  1190. }
  1191. }
  1192. return (FALSE);
  1193. }
  1194. VOID
  1195. IncrementFileTime(
  1196. _FILETIME *lpft
  1197. )
  1198. {
  1199. DWORD dwTemp = lpft->dwLowDateTime;
  1200. ++lpft->dwLowDateTime;
  1201. // if it rolled over, there was a carry
  1202. if (lpft->dwLowDateTime < dwTemp)
  1203. lpft->dwHighDateTime++;
  1204. }
  1205. BOOL
  1206. CreateStringArrayFromDelimitedList(
  1207. IN LPWSTR lpwzDelimitedList,
  1208. IN LPWSTR lpwzDelimiters,
  1209. IN LPWSTR *lprgwzStringArray,
  1210. OUT LPDWORD lpdwCount
  1211. )
  1212. {
  1213. LPWSTR lpStart, lpEnd, lpTmp;
  1214. USHORT c;
  1215. BOOL fRet = FALSE;
  1216. *lpdwCount = 0;
  1217. lpStart = lpwzDelimitedList;
  1218. lpEnd = lpStart + wstrlen(lpwzDelimitedList); // points to null
  1219. // strip out the trailing spaces
  1220. for(;(lpStart<lpEnd);--lpEnd) {
  1221. c = *(lpEnd-1);
  1222. if (c != L' ') {
  1223. *lpEnd = 0;
  1224. break;
  1225. }
  1226. }
  1227. // bailout if this is an empty string
  1228. if (lpStart == lpEnd) {
  1229. fRet = TRUE;
  1230. goto done;
  1231. }
  1232. for (lpTmp = lpStart;(lpTmp && (lpEnd > lpStart)); lpStart = lpTmp+1) {
  1233. lpTmp = lpStart;
  1234. c = *lpStart;
  1235. if (c == L' ') {
  1236. continue;
  1237. }
  1238. Assert(*lpStart != L' ');
  1239. lpTmp = wstrpbrk(lpStart, lpwzDelimiters);
  1240. if (lprgwzStringArray) {
  1241. if (lpTmp) {
  1242. *lpTmp = 0; // create a string out of it
  1243. }
  1244. // plug the start pointer into the array
  1245. lprgwzStringArray[*lpdwCount] = lpStart;
  1246. }
  1247. ++*lpdwCount;
  1248. }
  1249. fRet = TRUE;
  1250. done:
  1251. return (fRet);
  1252. }
  1253. BOOL IsValidName(LPSTR lpName)
  1254. {
  1255. int len = strlen(lpName), ch, i=0;
  1256. if (len != INODE_STRING_LENGTH)
  1257. {
  1258. return FALSE;
  1259. }
  1260. while (len--)
  1261. {
  1262. ++i;
  1263. ch = *lpName++;
  1264. if (!(((ch>='0') && (ch <='9'))||
  1265. ((ch>='A') && (ch <='F'))||
  1266. ((ch>='a') && (ch <='f'))))
  1267. {
  1268. return FALSE;
  1269. }
  1270. }
  1271. if (i != INODE_STRING_LENGTH)
  1272. {
  1273. return FALSE;
  1274. }
  1275. return (TRUE);
  1276. }
  1277. BOOL
  1278. DeleteDirectoryFiles(
  1279. LPCSTR lpszDir
  1280. )
  1281. {
  1282. _WIN32_FIND_DATAA sFind32;
  1283. char buff[MAX_PATH+32];
  1284. CSCHFILE hFind;
  1285. int lenDir;
  1286. BOOL fOK = TRUE;
  1287. strcpy(buff, lpszDir);
  1288. lenDir = strlen(buff);
  1289. if (!lenDir)
  1290. {
  1291. return (FALSE);
  1292. }
  1293. if ((hFind = FindFirstFileLocal(buff, &sFind32)))
  1294. {
  1295. if (buff[lenDir-1] != '\\')
  1296. {
  1297. buff[lenDir++] ='\\';
  1298. buff[lenDir]=0;
  1299. }
  1300. do
  1301. {
  1302. buff[lenDir] = 0;
  1303. if (!(sFind32.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  1304. && IsValidName(sFind32.cFileName))
  1305. {
  1306. strcat(buff, sFind32.cFileName);
  1307. if(DeleteFileLocal(buff, ATTRIB_DEL_ANY) < 0)
  1308. {
  1309. fOK = FALSE;
  1310. break;
  1311. }
  1312. }
  1313. }
  1314. while(FindNextFileLocal(hFind, &sFind32) >= 0);
  1315. FindCloseLocal(hFind);
  1316. }
  1317. return (fOK);
  1318. }