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.

1319 lines
34 KiB

  1. /*****************************************************************************
  2. * This file is a ring 3 layer to call down to the VxD.
  3. */
  4. #include "pch.h"
  5. #pragma hdrstop
  6. #include "assert.h"
  7. #include "lib3.h"
  8. #include "debug.h"
  9. /*****************************************************************************
  10. Globals declared within this file
  11. */
  12. static char vszShadowDevice[] = "\\\\.\\shadow"; // name of vxd
  13. // must be declared in your OWN code...
  14. /* assert/debug stuff */
  15. AssertData;
  16. AssertError;
  17. //this variable is used as the receiver of the BytesReturned for DeviceIoControl Calls
  18. //the value is never actually used
  19. ULONG DummyBytesReturned, uShadowDeviceOpenCount=0;
  20. //HACKHACKHACK the agent will wait up to 7 minutes for the rdr to show up
  21. LONG NtWaitLoopMax = 7 * 60;
  22. LONG NtWaitLoopSleep = 5;
  23. /*****************************************************************************
  24. Call once to get the file handle opened to talk to the VxD
  25. */
  26. HANDLE
  27. OpenShadowDatabaseIOex(ULONG WaitForDriver, DWORD dwFlags)
  28. {
  29. HANDLE hShadowDB;
  30. LONG WaitLoopRemaining = NtWaitLoopMax;
  31. DWORD dwError;
  32. char buff[64];
  33. #if 0
  34. WAITLOOP_HACK:
  35. #endif
  36. if ((hShadowDB = CreateFileA(vszShadowDevice,
  37. FILE_EXECUTE, //GENERIC_READ | GENERIC_WRITE,
  38. FILE_SHARE_READ | FILE_SHARE_WRITE,
  39. NULL,
  40. OPEN_EXISTING,
  41. dwFlags,
  42. NULL)) == INVALID_HANDLE_VALUE ) {
  43. #if 0
  44. //HACKHACKHACK
  45. if (WaitForDriver && (WaitLoopRemaining > 0)) {
  46. Sleep(NtWaitLoopSleep * 1000);
  47. WaitLoopRemaining -= NtWaitLoopSleep;
  48. goto WAITLOOP_HACK;
  49. }
  50. #endif
  51. dwError = GetLastError();
  52. // DEBUG_PRINT(("lib3:CreateFile on CSC device failed Error = %d\r\n", dwError));
  53. return INVALID_HANDLE_VALUE; /* failure */
  54. }
  55. InterlockedIncrement(&uShadowDeviceOpenCount);
  56. return hShadowDB; /* success */
  57. }
  58. HANDLE
  59. __OpenShadowDatabaseIO(ULONG WaitForDriver)
  60. {
  61. return OpenShadowDatabaseIOex(WaitForDriver, 0);
  62. }
  63. /*****************************************************************************
  64. Call after we're all done to close down the IOCTL interface.
  65. */
  66. void
  67. CloseShadowDatabaseIO(HANDLE hShadowDB)
  68. {
  69. CloseHandle(hShadowDB);
  70. InterlockedDecrement(&uShadowDeviceOpenCount);
  71. }
  72. int BeginInodeTransactionHSHADOW(
  73. VOID
  74. )
  75. {
  76. int iRet;
  77. iRet = DoShadowMaintenance(INVALID_HANDLE_VALUE, SHADOW_BEGIN_INODE_TRANSACTION);
  78. if (!iRet)
  79. {
  80. SetLastError(ERROR_ACCESS_DENIED);
  81. }
  82. return (iRet);
  83. }
  84. int EndInodeTransactionHSHADOW(
  85. VOID
  86. )
  87. {
  88. int iRet;
  89. iRet = DoShadowMaintenance(INVALID_HANDLE_VALUE, SHADOW_END_INODE_TRANSACTION);
  90. if (!iRet)
  91. {
  92. SetLastError(ERROR_ACCESS_DENIED);
  93. }
  94. return (iRet);
  95. }
  96. /*****************************************************************************
  97. * Given an hDir and filename, find the hShadow, should it exist.
  98. */
  99. int
  100. GetShadowW(
  101. HANDLE hShadowDB,
  102. HSHADOW hDir,
  103. LPHSHADOW lphShadow,
  104. LPWIN32_FIND_DATAW lpFind32,
  105. unsigned long *lpuStatus
  106. )
  107. {
  108. int iRet;
  109. SHADOWINFO sSI;
  110. BOOL fDBOpened = FALSE;
  111. if (hShadowDB == INVALID_HANDLE_VALUE)
  112. {
  113. hShadowDB = OpenShadowDatabaseIO();
  114. if (hShadowDB == INVALID_HANDLE_VALUE)
  115. {
  116. return 0;
  117. }
  118. fDBOpened = TRUE;
  119. }
  120. memset(&sSI, 0, sizeof(SHADOWINFO));
  121. sSI.hDir = hDir;
  122. sSI.lpFind32 = lpFind32;
  123. iRet = DeviceIoControl(hShadowDB
  124. , IOCTL_GETSHADOW
  125. ,(LPVOID)(&sSI), 0
  126. , NULL, 0
  127. , &DummyBytesReturned, NULL);
  128. if (iRet) {
  129. *lpuStatus = sSI.uStatus;
  130. *lphShadow = sSI.hShadow;
  131. }
  132. if (fDBOpened)
  133. {
  134. CloseShadowDatabaseIO(hShadowDB);
  135. }
  136. if (!iRet)
  137. {
  138. SetLastError(sSI.dwError);
  139. }
  140. return (iRet);
  141. }
  142. /*****************************************************************************
  143. * Given an hDir and filename, get SHADOWINFO if it exists
  144. */
  145. int
  146. GetShadowExW(
  147. HANDLE hShadowDB,
  148. HSHADOW hDir,
  149. LPWIN32_FIND_DATAW lpFind32,
  150. LPSHADOWINFO lpSI
  151. )
  152. {
  153. int iRet;
  154. BOOL fDBOpened = FALSE;
  155. if (hShadowDB == INVALID_HANDLE_VALUE)
  156. {
  157. hShadowDB = OpenShadowDatabaseIO();
  158. if (hShadowDB == INVALID_HANDLE_VALUE)
  159. {
  160. return 0;
  161. }
  162. fDBOpened = TRUE;
  163. }
  164. memset(lpSI, 0, sizeof(SHADOWINFO));
  165. lpSI->hDir = hDir;
  166. lpSI->lpFind32 = lpFind32;
  167. iRet = DeviceIoControl(hShadowDB
  168. , IOCTL_GETSHADOW
  169. ,(LPVOID)(lpSI), 0
  170. , NULL, 0
  171. , &DummyBytesReturned, NULL);
  172. if (fDBOpened)
  173. {
  174. CloseShadowDatabaseIO(hShadowDB);
  175. }
  176. if (!iRet)
  177. {
  178. SetLastError(lpSI->dwError);
  179. }
  180. return (iRet);
  181. }
  182. /*****************************************************************************
  183. * Call down to the VxD to add a file to the shadow.
  184. * lphShadow is filled in with the new HSHADOW.
  185. * Set uStatus as necessary (ie: SPARSE or whatever...)
  186. */
  187. int
  188. CreateShadowW(
  189. HANDLE hShadowDB,
  190. HSHADOW hDir,
  191. LPWIN32_FIND_DATAW lpFind32,
  192. unsigned long uStatus,
  193. LPHSHADOW lphShadow
  194. )
  195. {
  196. int iRet;
  197. SHADOWINFO sSI;
  198. BOOL fDBOpened = FALSE;
  199. if (hShadowDB == INVALID_HANDLE_VALUE)
  200. {
  201. hShadowDB = OpenShadowDatabaseIO();
  202. if (hShadowDB == INVALID_HANDLE_VALUE)
  203. {
  204. return 0;
  205. }
  206. fDBOpened = TRUE;
  207. }
  208. memset(&sSI, 0, sizeof(SHADOWINFO));
  209. sSI.hDir = hDir;
  210. sSI.uStatus = uStatus;
  211. sSI.lpFind32 = lpFind32;
  212. iRet = DeviceIoControl(hShadowDB
  213. , IOCTL_SHADOW_CREATE
  214. ,(LPVOID)(&sSI), 0
  215. , NULL, 0
  216. , &DummyBytesReturned, NULL);
  217. if (iRet) {
  218. *lphShadow = sSI.hShadow;
  219. }
  220. if (fDBOpened)
  221. {
  222. CloseShadowDatabaseIO(hShadowDB);
  223. }
  224. if (!iRet)
  225. {
  226. SetLastError(sSI.dwError);
  227. }
  228. return (iRet);
  229. }
  230. /*****************************************************************************
  231. * given an hDir and hShadow, nuke the shadow
  232. */
  233. int
  234. DeleteShadow(
  235. HANDLE hShadowDB,
  236. HSHADOW hDir,
  237. HSHADOW hShadow
  238. )
  239. {
  240. SHADOWINFO sSI;
  241. BOOL fDBOpened = FALSE;
  242. int iRet;
  243. if (hShadowDB == INVALID_HANDLE_VALUE)
  244. {
  245. hShadowDB = OpenShadowDatabaseIO();
  246. if (hShadowDB == INVALID_HANDLE_VALUE)
  247. {
  248. return 0;
  249. }
  250. fDBOpened = TRUE;
  251. }
  252. memset(&sSI, 0, sizeof(SHADOWINFO));
  253. sSI.hDir = hDir;
  254. sSI.hShadow = hShadow;
  255. iRet = DeviceIoControl(hShadowDB , IOCTL_SHADOW_DELETE
  256. ,(LPVOID)(&sSI), 0
  257. , NULL, 0
  258. , &DummyBytesReturned, NULL);
  259. if (fDBOpened)
  260. {
  261. CloseShadowDatabaseIO(hShadowDB);
  262. }
  263. if (!iRet)
  264. {
  265. SetLastError(sSI.dwError);
  266. }
  267. return (iRet);
  268. }
  269. /*****************************************************************************
  270. * given an hDir and hShadow, get WIN32_FIND_DATAW about the file.
  271. */
  272. int
  273. GetShadowInfoW(
  274. HANDLE hShadowDB,
  275. HSHADOW hDir,
  276. HSHADOW hShadow,
  277. LPWIN32_FIND_DATAW lpFind32,
  278. unsigned long *lpuStatus
  279. )
  280. {
  281. int iRet;
  282. SHADOWINFO sSI;
  283. BOOL fDBOpened = FALSE;
  284. if (hShadowDB == INVALID_HANDLE_VALUE)
  285. {
  286. hShadowDB = OpenShadowDatabaseIO();
  287. if (hShadowDB == INVALID_HANDLE_VALUE)
  288. {
  289. return 0;
  290. }
  291. fDBOpened = TRUE;
  292. }
  293. memset(&sSI, 0, sizeof(SHADOWINFO));
  294. sSI.hDir = hDir;
  295. sSI.hShadow = hShadow;
  296. sSI.lpFind32 = lpFind32;
  297. iRet = DeviceIoControl(hShadowDB , IOCTL_SHADOW_GET_SHADOW_INFO
  298. ,(LPVOID)(&sSI), 0
  299. , NULL, 0
  300. , &DummyBytesReturned, NULL);
  301. *lpuStatus = sSI.uStatus;
  302. if (fDBOpened)
  303. {
  304. CloseShadowDatabaseIO(hShadowDB);
  305. }
  306. if (!iRet)
  307. {
  308. SetLastError(sSI.dwError);
  309. }
  310. return (iRet);
  311. }
  312. /*****************************************************************************
  313. * given an hDir and hShadow, get WIN32_FIND_DATAW about the file and the SHADOWINFO
  314. */
  315. int
  316. GetShadowInfoExW(
  317. HANDLE hShadowDB,
  318. HSHADOW hDir,
  319. HSHADOW hShadow,
  320. LPWIN32_FIND_DATAW lpFind32,
  321. LPSHADOWINFO lpSI
  322. )
  323. {
  324. int iRet;
  325. BOOL fDBOpened = FALSE;
  326. if (hShadowDB == INVALID_HANDLE_VALUE)
  327. {
  328. hShadowDB = OpenShadowDatabaseIO();
  329. if (hShadowDB == INVALID_HANDLE_VALUE)
  330. {
  331. return 0;
  332. }
  333. fDBOpened = TRUE;
  334. }
  335. memset(lpSI, 0, sizeof(SHADOWINFO));
  336. lpSI->hDir = hDir;
  337. lpSI->hShadow = hShadow;
  338. lpSI->lpFind32 = lpFind32;
  339. iRet = DeviceIoControl(hShadowDB , IOCTL_SHADOW_GET_SHADOW_INFO
  340. ,(LPVOID)(lpSI), 0
  341. , NULL, 0
  342. , &DummyBytesReturned, NULL);
  343. if (fDBOpened)
  344. {
  345. CloseShadowDatabaseIO(hShadowDB);
  346. }
  347. if (!iRet)
  348. {
  349. SetLastError(lpSI->dwError);
  350. }
  351. return (iRet);
  352. }
  353. /*****************************************************************************
  354. * given an hDir and hShadow, set WIN32_FIND_DATAW or uStatus about the file.
  355. * Operation depends on uOp given.
  356. */
  357. int
  358. SetShadowInfoW(
  359. HANDLE hShadowDB,
  360. HSHADOW hDir,
  361. HSHADOW hShadow,
  362. LPWIN32_FIND_DATAW lpFind32,
  363. unsigned long uStatus,
  364. unsigned long uOp
  365. )
  366. {
  367. SHADOWINFO sSI;
  368. int iRet;
  369. BOOL fDBOpened = FALSE;
  370. if (hShadowDB == INVALID_HANDLE_VALUE)
  371. {
  372. hShadowDB = OpenShadowDatabaseIO();
  373. if (hShadowDB == INVALID_HANDLE_VALUE)
  374. {
  375. return 0;
  376. }
  377. fDBOpened = TRUE;
  378. }
  379. memset(&sSI, 0, sizeof(SHADOWINFO));
  380. sSI.hDir = hDir;
  381. sSI.hShadow = hShadow;
  382. sSI.lpFind32 = lpFind32;
  383. sSI.uStatus = uStatus;
  384. sSI.uOp = uOp;
  385. iRet = DeviceIoControl(hShadowDB , IOCTL_SHADOW_SET_SHADOW_INFO
  386. ,(LPVOID)(&sSI), 0
  387. , NULL, 0
  388. , &DummyBytesReturned, NULL);
  389. if (fDBOpened)
  390. {
  391. CloseShadowDatabaseIO(hShadowDB);
  392. }
  393. if (!iRet)
  394. {
  395. SetLastError(sSI.dwError);
  396. }
  397. return (iRet);
  398. }
  399. /*****************************************************************************
  400. * Fills out a GLOBALSTATUS passed in.
  401. */
  402. int
  403. GetGlobalStatus(
  404. HANDLE hShadowDB,
  405. LPGLOBALSTATUS lpGS
  406. )
  407. {
  408. BOOL fDBOpened = FALSE;
  409. int iRet;
  410. if (hShadowDB == INVALID_HANDLE_VALUE)
  411. {
  412. hShadowDB = OpenShadowDatabaseIO();
  413. if (hShadowDB == INVALID_HANDLE_VALUE)
  414. {
  415. return 0;
  416. }
  417. fDBOpened = TRUE;
  418. }
  419. iRet = DeviceIoControl(hShadowDB , IOCTL_GETGLOBALSTATUS
  420. ,(LPVOID)(lpGS), 0
  421. , NULL, 0
  422. , &DummyBytesReturned, NULL);
  423. if (fDBOpened)
  424. {
  425. CloseShadowDatabaseIO(hShadowDB);
  426. }
  427. return (iRet);
  428. }
  429. /*****************************************************************************
  430. * given an hDir, enumerate the directory. A SHADOWINFO will be filled in.
  431. * You must pass in a LPWIN32_FIND_DATAW that has cFileName and fileAttributes
  432. * set properly. The cookie returned must be used in findNext calls.
  433. */
  434. int
  435. FindOpenShadowW(
  436. HANDLE hShadowDB,
  437. HSHADOW hDir,
  438. unsigned uOp,
  439. LPWIN32_FIND_DATAW lpFind32,
  440. LPSHADOWINFO lpSI
  441. )
  442. {
  443. BOOL retVal;
  444. BOOL fDBOpened = FALSE;
  445. if (hShadowDB == INVALID_HANDLE_VALUE)
  446. {
  447. hShadowDB = OpenShadowDatabaseIO();
  448. if (hShadowDB == INVALID_HANDLE_VALUE)
  449. {
  450. return 0;
  451. }
  452. fDBOpened = TRUE;
  453. }
  454. memset(lpSI, 0, sizeof(SHADOWINFO));
  455. lpSI->uOp = uOp;
  456. lpSI->hDir = hDir;
  457. lpSI->lpFind32 = lpFind32;
  458. retVal = DeviceIoControl(hShadowDB , IOCTL_FINDOPEN_SHADOW
  459. ,(LPVOID)(lpSI), 0
  460. , NULL, 0
  461. , &DummyBytesReturned, NULL);
  462. lpSI->lpFind32 = NULL;
  463. if(!retVal) {
  464. memset(lpSI, 0, sizeof(SHADOWINFO));
  465. }
  466. if (!retVal)
  467. {
  468. SetLastError(lpSI->dwError);
  469. }
  470. if (fDBOpened)
  471. {
  472. CloseShadowDatabaseIO(hShadowDB);
  473. }
  474. return retVal;
  475. }
  476. /*****************************************************************************
  477. * Continue enumeration based on handle returned above.
  478. */
  479. int
  480. FindNextShadowW(
  481. HANDLE hShadowDB,
  482. CSC_ENUMCOOKIE uEnumCookie,
  483. LPWIN32_FIND_DATAW lpFind32,
  484. LPSHADOWINFO lpSI
  485. )
  486. {
  487. BOOL retVal;
  488. BOOL fDBOpened = FALSE;
  489. if (hShadowDB == INVALID_HANDLE_VALUE)
  490. {
  491. hShadowDB = OpenShadowDatabaseIO();
  492. if (hShadowDB == INVALID_HANDLE_VALUE)
  493. {
  494. return 0;
  495. }
  496. fDBOpened = TRUE;
  497. }
  498. memset(lpSI, 0, sizeof(SHADOWINFO));
  499. lpSI->uEnumCookie = uEnumCookie;
  500. lpSI->lpFind32 = lpFind32;
  501. retVal = DeviceIoControl(hShadowDB , IOCTL_FINDNEXT_SHADOW
  502. ,(LPVOID)(lpSI), 0
  503. , NULL, 0
  504. , &DummyBytesReturned, NULL);
  505. if (fDBOpened)
  506. {
  507. CloseShadowDatabaseIO(hShadowDB);
  508. }
  509. return retVal;
  510. }
  511. /*****************************************************************************
  512. * Finished enumeration, return the handle.
  513. */
  514. int
  515. FindCloseShadow(
  516. HANDLE hShadowDB,
  517. CSC_ENUMCOOKIE uEnumCookie
  518. )
  519. {
  520. SHADOWINFO sSI;
  521. int iRet;
  522. BOOL fDBOpened = FALSE;
  523. if (hShadowDB == INVALID_HANDLE_VALUE)
  524. {
  525. hShadowDB = OpenShadowDatabaseIO();
  526. if (hShadowDB == INVALID_HANDLE_VALUE)
  527. {
  528. return 0;
  529. }
  530. fDBOpened = TRUE;
  531. }
  532. memset(&sSI, 0, sizeof(SHADOWINFO));
  533. sSI.uEnumCookie = uEnumCookie;
  534. iRet = DeviceIoControl(hShadowDB , IOCTL_FINDCLOSE_SHADOW
  535. ,(LPVOID)(&sSI), 0
  536. , NULL, 0
  537. , &DummyBytesReturned, NULL);
  538. if (fDBOpened)
  539. {
  540. CloseShadowDatabaseIO(hShadowDB);
  541. }
  542. return (iRet);
  543. }
  544. /*****************************************************************************
  545. * Call down to the VxD to add a hint of some sort to the database.
  546. * cFileName is the string to match against.
  547. * lphShadow is filled in with the new HSHADOW.
  548. * hDir = 0 means global hint. Otherwise, this is the root to take it from.
  549. */
  550. int
  551. AddHintW(
  552. HANDLE hShadowDB,
  553. HSHADOW hDir,
  554. TCHAR *cFileName,
  555. LPHSHADOW lphShadow,
  556. unsigned long ulHintFlags,
  557. unsigned long ulHintPri
  558. )
  559. {
  560. int iRet;
  561. SHADOWINFO sSI;
  562. WIN32_FIND_DATAW sFind32;
  563. BOOL fDBOpened = FALSE;
  564. if (hShadowDB == INVALID_HANDLE_VALUE)
  565. {
  566. hShadowDB = OpenShadowDatabaseIO();
  567. if (hShadowDB == INVALID_HANDLE_VALUE)
  568. {
  569. return 0;
  570. }
  571. fDBOpened = TRUE;
  572. }
  573. memset(&sSI, 0, sizeof(SHADOWINFO));
  574. wcsncpy(sFind32.cFileName, cFileName, MAX_PATH-1);
  575. sSI.hDir = hDir;
  576. sSI.lpFind32 = (LPFIND32)&sFind32;
  577. sSI.ulHintFlags = ulHintFlags;
  578. sSI.ulHintPri = ulHintPri;
  579. iRet = DeviceIoControl(hShadowDB
  580. , IOCTL_ADD_HINT
  581. ,(LPVOID)(&sSI), 0
  582. , NULL, 0
  583. , &DummyBytesReturned, NULL);
  584. if (iRet) {
  585. *lphShadow = sSI.hShadow;
  586. }
  587. if (fDBOpened)
  588. {
  589. CloseShadowDatabaseIO(hShadowDB);
  590. }
  591. return (iRet);
  592. }
  593. /*****************************************************************************
  594. * Call down to the VxD to delete a hint of some sort from the database.
  595. * cFileName is the string to match against.
  596. * hDir = 0 means global hint. Otherwise, this is the root to take it from.
  597. */
  598. int
  599. DeleteHintW(
  600. HANDLE hShadowDB,
  601. HSHADOW hDir,
  602. TCHAR *cFileName,
  603. BOOL fClearAll
  604. )
  605. {
  606. int iRet;
  607. SHADOWINFO sSI;
  608. WIN32_FIND_DATAW sFind32;
  609. BOOL fDBOpened = FALSE;
  610. if (hShadowDB == INVALID_HANDLE_VALUE)
  611. {
  612. hShadowDB = OpenShadowDatabaseIO();
  613. if (hShadowDB == INVALID_HANDLE_VALUE)
  614. {
  615. return 0;
  616. }
  617. fDBOpened = TRUE;
  618. }
  619. memset(&sSI, 0, sizeof(SHADOWINFO));
  620. wcsncpy(sFind32.cFileName, cFileName, MAX_PATH-1);
  621. sSI.hDir = hDir;
  622. sSI.lpFind32 = (LPFIND32)&sFind32;
  623. // nuke or just decrement?
  624. if (fClearAll)
  625. {
  626. sSI.ulHintPri = 0xffffffff;
  627. }
  628. iRet = DeviceIoControl(hShadowDB
  629. , IOCTL_DELETE_HINT
  630. ,(LPVOID)(&sSI), 0
  631. , NULL, 0
  632. , &DummyBytesReturned, NULL);
  633. if (fDBOpened)
  634. {
  635. CloseShadowDatabaseIO(hShadowDB);
  636. }
  637. return iRet;
  638. }
  639. /*****************************************************************************
  640. * given an hDir, enumerate the directory. A SHADOWINFO will be filled in.
  641. * You must pass in a LPWIN32_FIND_DATAW that has cFileName and fileAttributes
  642. * set properly. The cookie returned must be used in findNext calls.
  643. */
  644. int
  645. FindOpenHintW(
  646. HANDLE hShadowDB,
  647. HSHADOW hDir,
  648. LPWIN32_FIND_DATAW lpFind32,
  649. CSC_ENUMCOOKIE *lpuEnumCookie,
  650. HSHADOW *hShadow,
  651. unsigned long *lpulHintFlags,
  652. unsigned long *lpulHintPri
  653. )
  654. {
  655. SHADOWINFO sSI;
  656. BOOL retVal;
  657. memset(&sSI, 0, sizeof(SHADOWINFO));
  658. sSI.uOp = FINDOPEN_SHADOWINFO_ALL;
  659. sSI.hDir = hDir;
  660. // sSI.ulHintFlags = 0xF;
  661. sSI.ulHintFlags = HINT_TYPE_FOLDER;
  662. sSI.lpFind32 = lpFind32;
  663. retVal = DeviceIoControl(hShadowDB , IOCTL_FINDOPEN_HINT
  664. ,(LPVOID)(&sSI), 0
  665. , NULL, 0
  666. , &DummyBytesReturned, NULL);
  667. if(retVal) {
  668. *lpuEnumCookie = sSI.uEnumCookie;
  669. *hShadow = sSI.hShadow;
  670. *lpulHintFlags = sSI.ulHintFlags;
  671. *lpulHintPri = sSI.ulHintPri;
  672. } else {
  673. *lpuEnumCookie = 0;
  674. *hShadow = 0;
  675. }
  676. return retVal;
  677. }
  678. /*****************************************************************************
  679. * Continue enumeration based on handle returned above.
  680. */
  681. int
  682. FindNextHintW(
  683. HANDLE hShadowDB,
  684. CSC_ENUMCOOKIE uEnumCookie,
  685. LPWIN32_FIND_DATAW lpFind32,
  686. HSHADOW *hShadow,
  687. unsigned long *lpuHintFlags,
  688. unsigned long *lpuHintPri
  689. )
  690. {
  691. SHADOWINFO sSI;
  692. BOOL retVal;
  693. memset(&sSI, 0, sizeof(SHADOWINFO));
  694. sSI.uEnumCookie = uEnumCookie;
  695. sSI.lpFind32 = lpFind32;
  696. retVal = DeviceIoControl(hShadowDB , IOCTL_FINDNEXT_HINT
  697. ,(LPVOID)(&sSI), 0
  698. , NULL, 0
  699. , &DummyBytesReturned, NULL);
  700. *hShadow = sSI.hShadow;
  701. *lpuHintFlags = sSI.ulHintFlags;
  702. *lpuHintPri = sSI.ulHintPri;
  703. return retVal;
  704. }
  705. /*****************************************************************************
  706. * Finished enumeration, return the handle.
  707. */
  708. int
  709. FindCloseHint(
  710. HANDLE hShadowDB,
  711. CSC_ENUMCOOKIE uEnumCookie
  712. )
  713. {
  714. SHADOWINFO sSI;
  715. int iRet;
  716. memset(&sSI, 0, sizeof(SHADOWINFO));
  717. sSI.uEnumCookie = uEnumCookie;
  718. return(DeviceIoControl(hShadowDB , IOCTL_FINDCLOSE_HINT
  719. ,(LPVOID)(&sSI), 0
  720. , NULL, 0
  721. , &DummyBytesReturned, NULL));
  722. }
  723. /*****************************************************************************
  724. * Call down to the VxD to add a hint on the inode.
  725. * This ioctl does the right thing for user and system hints
  726. * If successful, there is an additional pincount on the inode entry
  727. * and the flags that are passed in are ORed with the original entry
  728. */
  729. int
  730. AddHintFromInode(
  731. HANDLE hShadowDB,
  732. HSHADOW hDir,
  733. HSHADOW hShadow,
  734. unsigned long *lpulPinCount,
  735. unsigned long *lpulHintFlags
  736. )
  737. {
  738. int iRet;
  739. SHADOWINFO sSI;
  740. BOOL fDBOpened = FALSE;
  741. if (hShadowDB == INVALID_HANDLE_VALUE)
  742. {
  743. hShadowDB = OpenShadowDatabaseIO();
  744. if (hShadowDB == INVALID_HANDLE_VALUE)
  745. {
  746. return 0;
  747. }
  748. fDBOpened = TRUE;
  749. }
  750. memset(&sSI, 0, sizeof(SHADOWINFO));
  751. sSI.hDir = hDir;
  752. sSI.hShadow = hShadow;
  753. sSI.ulHintFlags = *lpulHintFlags;
  754. sSI.uOp = SHADOW_ADDHINT_FROM_INODE;
  755. iRet = DeviceIoControl(hShadowDB
  756. , IOCTL_DO_SHADOW_MAINTENANCE
  757. ,(LPVOID)(&sSI), 0
  758. , NULL, 0
  759. , &DummyBytesReturned, NULL);
  760. if (fDBOpened)
  761. {
  762. CloseShadowDatabaseIO(hShadowDB);
  763. }
  764. if (!iRet)
  765. {
  766. SetLastError(sSI.dwError);
  767. }
  768. else
  769. {
  770. *lpulHintFlags = sSI.ulHintFlags;
  771. *lpulPinCount = sSI.ulHintPri;
  772. }
  773. return (iRet);
  774. }
  775. /*****************************************************************************
  776. * Call down to the VxD to add a hint on the inode.
  777. * This ioctl does the right thing for user and system hints
  778. * If successful, there is an one pincount less than the original
  779. * and the ~ of flags that are passed in are ANDed with the original entry
  780. */
  781. int
  782. DeleteHintFromInode(
  783. HANDLE hShadowDB,
  784. HSHADOW hDir,
  785. HSHADOW hShadow,
  786. unsigned long *lpulPinCount,
  787. unsigned long *lpulHintFlags
  788. )
  789. {
  790. int iRet;
  791. SHADOWINFO sSI;
  792. BOOL fDBOpened = FALSE;
  793. if (hShadowDB == INVALID_HANDLE_VALUE)
  794. {
  795. hShadowDB = OpenShadowDatabaseIO();
  796. if (hShadowDB == INVALID_HANDLE_VALUE)
  797. {
  798. return 0;
  799. }
  800. fDBOpened = TRUE;
  801. }
  802. memset(&sSI, 0, sizeof(SHADOWINFO));
  803. sSI.hDir = hDir;
  804. sSI.hShadow = hShadow;
  805. sSI.ulHintFlags = *lpulHintFlags;
  806. sSI.uOp = SHADOW_DELETEHINT_FROM_INODE;
  807. iRet = DeviceIoControl(hShadowDB
  808. , IOCTL_DO_SHADOW_MAINTENANCE
  809. ,(LPVOID)(&sSI), 0
  810. , NULL, 0
  811. , &DummyBytesReturned, NULL);
  812. if (fDBOpened)
  813. {
  814. CloseShadowDatabaseIO(hShadowDB);
  815. }
  816. if (!iRet)
  817. {
  818. SetLastError(sSI.dwError);
  819. }
  820. else
  821. {
  822. *lpulHintFlags = sSI.ulHintFlags;
  823. *lpulPinCount = sSI.ulHintPri;
  824. }
  825. return (iRet);
  826. }
  827. /******************************************************/
  828. /*****************************************************************************
  829. * Given an hDir and filename, find the hShadow, should it exist.
  830. */
  831. int
  832. GetShadowA(
  833. HANDLE hShadowDB,
  834. HSHADOW hDir,
  835. LPHSHADOW lphShadow,
  836. LPWIN32_FIND_DATAA lpFind32,
  837. unsigned long *lpuStatus
  838. )
  839. {
  840. int iRet;
  841. WIN32_FIND_DATAW sFind32, *lpFind32W = NULL;
  842. if (lpFind32)
  843. {
  844. lpFind32W = &sFind32;
  845. Find32AToFind32W(lpFind32, lpFind32W);
  846. }
  847. iRet = GetShadowW(hShadowDB, hDir, lphShadow, lpFind32W, lpuStatus);
  848. if (lpFind32)
  849. {
  850. Assert(lpFind32W);
  851. Find32WToFind32A(lpFind32W, lpFind32);
  852. }
  853. return (iRet);
  854. }
  855. /*****************************************************************************
  856. * Given an hDir and filename, get SHADOWINFO if it exists
  857. */
  858. int
  859. GetShadowExA(
  860. HANDLE hShadowDB,
  861. HSHADOW hDir,
  862. LPWIN32_FIND_DATAA lpFind32,
  863. LPSHADOWINFO lpSI
  864. )
  865. {
  866. int iRet;
  867. WIN32_FIND_DATAW sFind32, *lpFind32W = NULL;
  868. if (lpFind32)
  869. {
  870. lpFind32W = &sFind32;
  871. Find32AToFind32W(lpFind32, lpFind32W);
  872. }
  873. iRet = GetShadowExW(hShadowDB, hDir, lpFind32W, lpSI);
  874. if (lpFind32)
  875. {
  876. Assert(lpFind32W);
  877. Find32WToFind32A(lpFind32W, lpFind32);
  878. }
  879. return (iRet);
  880. }
  881. /*****************************************************************************
  882. * Call down to the VxD to add a file to the shadow.
  883. * lphShadow is filled in with the new HSHADOW.
  884. * Set uStatus as necessary (ie: SPARSE or whatever...)
  885. */
  886. int
  887. CreateShadowA(
  888. HANDLE hShadowDB,
  889. HSHADOW hDir,
  890. LPWIN32_FIND_DATAA lpFind32,
  891. unsigned long uStatus,
  892. LPHSHADOW lphShadow
  893. )
  894. {
  895. int iRet;
  896. WIN32_FIND_DATAW sFind32, *lpFind32W = NULL;
  897. if (lpFind32)
  898. {
  899. lpFind32W = &sFind32;
  900. Find32AToFind32W(lpFind32, lpFind32W);
  901. }
  902. iRet = CreateShadowW(hShadowDB, hDir, lpFind32W, uStatus, lphShadow);
  903. if (lpFind32)
  904. {
  905. Assert(lpFind32W);
  906. Find32WToFind32A(lpFind32W, lpFind32);
  907. }
  908. return (iRet);
  909. }
  910. /*****************************************************************************
  911. * given an hDir and hShadow, get WIN32_FIND_DATAA about the file.
  912. */
  913. int
  914. GetShadowInfoA(
  915. HANDLE hShadowDB,
  916. HSHADOW hDir,
  917. HSHADOW hShadow,
  918. LPWIN32_FIND_DATAA lpFind32,
  919. unsigned long *lpuStatus
  920. )
  921. {
  922. int iRet;
  923. WIN32_FIND_DATAW sFind32, *lpFind32W = NULL;
  924. if (lpFind32)
  925. {
  926. lpFind32W = &sFind32;
  927. }
  928. iRet = GetShadowInfoW(hShadowDB, hDir, hShadow, lpFind32W, lpuStatus);
  929. if (lpFind32)
  930. {
  931. Assert(lpFind32W);
  932. Find32WToFind32A(lpFind32W, lpFind32);
  933. }
  934. return (iRet);
  935. }
  936. /*****************************************************************************
  937. * given an hDir and hShadow, get WIN32_FIND_DATAA about the file and the SHADOWINFO
  938. */
  939. int
  940. GetShadowInfoExA(
  941. HANDLE hShadowDB,
  942. HSHADOW hDir,
  943. HSHADOW hShadow,
  944. LPWIN32_FIND_DATAA lpFind32,
  945. LPSHADOWINFO lpSI
  946. )
  947. {
  948. int iRet;
  949. WIN32_FIND_DATAW sFind32, *lpFind32W = NULL;
  950. if (lpFind32)
  951. {
  952. lpFind32W = &sFind32;
  953. }
  954. iRet = GetShadowInfoExW(hShadowDB, hDir, hShadow, lpFind32W, lpSI);
  955. if (lpFind32)
  956. {
  957. Assert(lpFind32W);
  958. Find32WToFind32A(lpFind32W, lpFind32);
  959. }
  960. return (iRet);
  961. }
  962. /*****************************************************************************
  963. * given an hDir and hShadow, set WIN32_FIND_DATAA or uStatus about the file.
  964. * Operation depends on uOp given.
  965. */
  966. int
  967. SetShadowInfoA(
  968. HANDLE hShadowDB,
  969. HSHADOW hDir,
  970. HSHADOW hShadow,
  971. LPWIN32_FIND_DATAA lpFind32,
  972. unsigned long uStatus,
  973. unsigned long uOp
  974. )
  975. {
  976. int iRet;
  977. WIN32_FIND_DATAW sFind32, *lpFind32W = NULL;
  978. if (lpFind32)
  979. {
  980. lpFind32W = &sFind32;
  981. Find32AToFind32W(lpFind32, lpFind32W);
  982. }
  983. iRet = SetShadowInfoW(hShadowDB, hDir, hShadow, lpFind32W, uStatus, uOp);
  984. if (lpFind32)
  985. {
  986. Assert(lpFind32W);
  987. Find32WToFind32A(lpFind32W, lpFind32);
  988. }
  989. return (iRet);
  990. }
  991. /*****************************************************************************
  992. * given an hDir, enumerate the directory. A SHADOWINFO will be filled in.
  993. * You must pass in a LPWIN32_FIND_DATAA that has cFileName and fileAttributes
  994. * set properly. The cookie returned must be used in findNext calls.
  995. */
  996. int
  997. FindOpenShadowA(
  998. HANDLE hShadowDB,
  999. HSHADOW hDir,
  1000. unsigned uOp,
  1001. LPWIN32_FIND_DATAA lpFind32,
  1002. LPSHADOWINFO lpSI
  1003. )
  1004. {
  1005. int iRet;
  1006. WIN32_FIND_DATAW sFind32, *lpFind32W = NULL;
  1007. if (lpFind32)
  1008. {
  1009. lpFind32W = &sFind32;
  1010. Find32AToFind32W(lpFind32, lpFind32W);
  1011. }
  1012. iRet = FindOpenShadowW(hShadowDB, hDir, uOp, lpFind32W, lpSI);
  1013. if (lpFind32)
  1014. {
  1015. Assert(lpFind32W);
  1016. Find32WToFind32A(lpFind32W, lpFind32);
  1017. }
  1018. return (iRet);
  1019. }
  1020. /*****************************************************************************
  1021. * Continue enumeration based on handle returned above.
  1022. */
  1023. int
  1024. FindNextShadowA(
  1025. HANDLE hShadowDB,
  1026. CSC_ENUMCOOKIE uEnumCookie,
  1027. LPWIN32_FIND_DATAA lpFind32,
  1028. LPSHADOWINFO lpSI
  1029. )
  1030. {
  1031. int iRet;
  1032. WIN32_FIND_DATAW sFind32, *lpFind32W = NULL;
  1033. if (lpFind32)
  1034. {
  1035. lpFind32W = &sFind32;
  1036. }
  1037. iRet = FindNextShadowW(hShadowDB, uEnumCookie, lpFind32W, lpSI);
  1038. if (lpFind32)
  1039. {
  1040. Assert(lpFind32W);
  1041. Find32WToFind32A(lpFind32W, lpFind32);
  1042. }
  1043. return (iRet);
  1044. }
  1045. /*****************************************************************************
  1046. * Call down to the VxD to add a hint of some sort to the database.
  1047. * cFileName is the string to match against.
  1048. * lphShadow is filled in with the new HSHADOW.
  1049. * hDir = 0 means global hint. Otherwise, this is the root to take it from.
  1050. */
  1051. int
  1052. AddHintA(
  1053. HANDLE hShadowDB,
  1054. HSHADOW hDir,
  1055. char *cFileName,
  1056. LPHSHADOW lphShadow,
  1057. unsigned long ulHintFlags,
  1058. unsigned long ulHintPri
  1059. )
  1060. {
  1061. int iRet = 0;
  1062. unsigned short wBuff[MAX_PATH];
  1063. if (MultiByteToWideChar(CP_ACP, 0, cFileName, strlen(cFileName), wBuff, sizeof(wBuff)/sizeof(WCHAR)))
  1064. {
  1065. iRet = AddHintW(hShadowDB, hDir, wBuff, lphShadow, ulHintFlags, ulHintPri);
  1066. }
  1067. else
  1068. {
  1069. SetLastError(ERROR_INVALID_PARAMETER);
  1070. }
  1071. return (iRet);
  1072. }
  1073. /*****************************************************************************
  1074. * Call down to the VxD to delete a hint of some sort from the database.
  1075. * cFileName is the string to match against.
  1076. * hDir = 0 means global hint. Otherwise, this is the root to take it from.
  1077. */
  1078. int
  1079. DeleteHintA(
  1080. HANDLE hShadowDB,
  1081. HSHADOW hDir,
  1082. char *cFileName,
  1083. BOOL fClearAll
  1084. )
  1085. {
  1086. int iRet = 0;
  1087. unsigned short wBuff[MAX_PATH];
  1088. if (MultiByteToWideChar(CP_ACP, 0, cFileName, strlen(cFileName), wBuff, sizeof(wBuff)/sizeof(WCHAR)))
  1089. {
  1090. iRet = DeleteHintW(hShadowDB, hDir, wBuff, fClearAll);
  1091. }
  1092. else
  1093. {
  1094. SetLastError(ERROR_INVALID_PARAMETER);
  1095. }
  1096. return (iRet);
  1097. }
  1098. /*****************************************************************************
  1099. * given an hDir, enumerate the directory. A SHADOWINFO will be filled in.
  1100. * You must pass in a LPWIN32_FIND_DATAA that has cFileName and fileAttributes
  1101. * set properly. The cookie returned must be used in findNext calls.
  1102. */
  1103. int
  1104. FindOpenHintA(
  1105. HANDLE hShadowDB,
  1106. HSHADOW hDir,
  1107. LPWIN32_FIND_DATAA lpFind32,
  1108. CSC_ENUMCOOKIE *lpuEnumCookie,
  1109. HSHADOW *lphShadow,
  1110. unsigned long *lpulHintFlags,
  1111. unsigned long *lpulHintPri
  1112. )
  1113. {
  1114. int iRet;
  1115. WIN32_FIND_DATAW sFind32, *lpFind32W = NULL;
  1116. if (lpFind32)
  1117. {
  1118. lpFind32W = &sFind32;
  1119. Find32AToFind32W(lpFind32, lpFind32W);
  1120. }
  1121. iRet = FindOpenHintW(hShadowDB, hDir, lpFind32W, lpuEnumCookie, lphShadow, lpulHintFlags, lpulHintPri);
  1122. if (lpFind32)
  1123. {
  1124. Assert(lpFind32W);
  1125. Find32WToFind32A(lpFind32W, lpFind32);
  1126. }
  1127. return (iRet);
  1128. }
  1129. /*****************************************************************************
  1130. * Continue enumeration based on handle returned above.
  1131. */
  1132. int
  1133. FindNextHintA(
  1134. HANDLE hShadowDB,
  1135. CSC_ENUMCOOKIE uEnumCookie,
  1136. LPWIN32_FIND_DATAA lpFind32,
  1137. HSHADOW *hShadow,
  1138. unsigned long *lpuHintFlags,
  1139. unsigned long *lpuHintPri
  1140. )
  1141. {
  1142. int iRet;
  1143. WIN32_FIND_DATAW sFind32, *lpFind32W = NULL;
  1144. if (lpFind32)
  1145. {
  1146. lpFind32W = &sFind32;
  1147. }
  1148. iRet = FindNextHintW(hShadowDB, uEnumCookie, lpFind32W, hShadow, lpuHintFlags, lpuHintPri);
  1149. if (lpFind32)
  1150. {
  1151. Assert(lpFind32W);
  1152. Find32WToFind32A(lpFind32W, lpFind32);
  1153. }
  1154. return (iRet);
  1155. }