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.

2263 lines
52 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include "lib3.h"
  4. #include "assert.h"
  5. //this variable is used as the receiver of the BytesReturned for DeviceIoControl Calls
  6. //the value is never actually used...it is declared in lib3.c
  7. extern ULONG DummyBytesReturned;
  8. /* assert/debug stuff */
  9. AssertData;
  10. AssertError;
  11. #define MAX_USERNAME 8 // this is not used any more
  12. // error codes on which we decide that we are in disconnected state
  13. static const DWORD rgdwErrorTab[] = {
  14. ERROR_BAD_NETPATH
  15. ,ERROR_NETWORK_BUSY
  16. ,ERROR_REM_NOT_LIST
  17. ,ERROR_DEV_NOT_EXIST
  18. ,ERROR_ADAP_HDW_ERR
  19. ,ERROR_BAD_NET_RESP
  20. ,ERROR_UNEXP_NET_ERR
  21. ,ERROR_BAD_REM_ADAP
  22. ,ERROR_BAD_NET_NAME
  23. ,ERROR_TOO_MANY_NAMES
  24. ,ERROR_TOO_MANY_SESS
  25. ,ERROR_NO_NET_OR_BAD_PATH
  26. ,ERROR_NETNAME_DELETED
  27. ,ERROR_NETWORK_UNREACHABLE
  28. };
  29. typedef struct tagREINT_IO
  30. {
  31. HANDLE hShadowDBAsync;
  32. OVERLAPPED sOverlapped;
  33. }
  34. REINT_IO, *LPREINT_IO;
  35. /*--------------------------- Widecharacter APIs ----------------------------------------*/
  36. /*****************************************************************************
  37. * GetUNCPath(). Pass in hShare, hDir, hShadow and get a LPCOPYPARAMS
  38. * filled out fully.
  39. */
  40. int
  41. GetUNCPathW(
  42. HANDLE hShadowDB,
  43. HSHARE hShare,
  44. HSHADOW hDir,
  45. HSHADOW hShadow,
  46. LPCOPYPARAMSW lpCP
  47. )
  48. {
  49. int iRet;
  50. BOOL fDBOpened = FALSE;
  51. if (hShadowDB == INVALID_HANDLE_VALUE)
  52. {
  53. hShadowDB = OpenShadowDatabaseIO();
  54. if (hShadowDB == INVALID_HANDLE_VALUE)
  55. {
  56. return 0;
  57. }
  58. fDBOpened = TRUE;
  59. }
  60. lpCP->uOp = 0; // this means we are looking for a local path of the driveletter kind
  61. // ie. c:\winnt\csc\80000002. That is the only kind that any
  62. // usermode code should want
  63. // on nt it can be \dosdevice\harddisk0\winnt\csc\80000002
  64. lpCP->hShare = hShare;
  65. lpCP->hDir = hDir;
  66. lpCP->hShadow = hShadow;
  67. iRet = DeviceIoControl( hShadowDB,
  68. IOCTL_SHADOW_GET_UNC_PATH,
  69. (LPVOID)(lpCP),
  70. 0,
  71. NULL,
  72. 0,
  73. &DummyBytesReturned,
  74. NULL);
  75. if (fDBOpened)
  76. {
  77. CloseShadowDatabaseIO(hShadowDB);
  78. }
  79. if (!iRet)
  80. {
  81. SetLastError(lpCP->dwError);
  82. }
  83. return (iRet);
  84. }
  85. /*****************************************************************************
  86. */
  87. int
  88. ChkUpdtStatusW(
  89. HANDLE hShadowDB,
  90. unsigned long hDir,
  91. unsigned long hShadow,
  92. LPWIN32_FIND_DATAW lpFind32,
  93. unsigned long *lpulShadowStatus
  94. )
  95. {
  96. SHADOWINFO sSI;
  97. int iRet;
  98. BOOL fDBOpened = FALSE;
  99. if (hShadowDB == INVALID_HANDLE_VALUE)
  100. {
  101. hShadowDB = OpenShadowDatabaseIO();
  102. if (hShadowDB == INVALID_HANDLE_VALUE)
  103. {
  104. return 0;
  105. }
  106. fDBOpened = TRUE;
  107. }
  108. memset(&sSI, 0, sizeof(SHADOWINFO));
  109. sSI.hShadow = hShadow;
  110. sSI.lpFind32 = lpFind32;
  111. if(DeviceIoControl(hShadowDB , IOCTL_SHADOW_CHK_UPDT_STATUS
  112. ,(LPVOID)(&sSI), 0
  113. , NULL, 0
  114. , &DummyBytesReturned, NULL))
  115. {
  116. *lpulShadowStatus = sSI.uStatus;
  117. iRet = 1;
  118. } else {
  119. *lpulShadowStatus = 0;
  120. iRet = 0;
  121. }
  122. if (fDBOpened)
  123. {
  124. CloseShadowDatabaseIO(hShadowDB);
  125. }
  126. if (!iRet)
  127. {
  128. SetLastError(sSI.dwError);
  129. }
  130. return (iRet);
  131. }
  132. int
  133. GetShareInfoW(
  134. HANDLE hShadowDB,
  135. HSHARE hShare,
  136. LPSHAREINFOW lpSVRI,
  137. unsigned long *lpulStatus
  138. )
  139. {
  140. SHADOWINFO sSI;
  141. int iRet;
  142. BOOL fDBOpened = FALSE;
  143. if (hShadowDB == INVALID_HANDLE_VALUE)
  144. {
  145. hShadowDB = OpenShadowDatabaseIO();
  146. if (hShadowDB == INVALID_HANDLE_VALUE)
  147. {
  148. return 0;
  149. }
  150. fDBOpened = TRUE;
  151. }
  152. memset(&sSI, 0, sizeof(SHADOWINFO));
  153. sSI.hShare = hShare;
  154. sSI.lpFind32 = (WIN32_FIND_DATAW *)lpSVRI;
  155. iRet = DeviceIoControl(hShadowDB , IOCTL_GET_SHARE_STATUS
  156. ,(LPVOID)(&sSI), 0
  157. , NULL, 0
  158. , &DummyBytesReturned, NULL);
  159. if(iRet)
  160. *lpulStatus = sSI.uStatus;
  161. else
  162. *lpulStatus = 0;
  163. if (fDBOpened)
  164. {
  165. CloseShadowDatabaseIO(hShadowDB);
  166. }
  167. if (!iRet)
  168. {
  169. SetLastError(sSI.dwError);
  170. }
  171. return iRet;
  172. }
  173. BOOL
  174. CopyShadowA(
  175. HANDLE hShadowDB,
  176. HSHADOW hDir,
  177. HSHADOW hShadow,
  178. LPSTR lpszFileName
  179. )
  180. {
  181. SHADOWINFO sSI;
  182. int iRet, len;
  183. BOOL fDBOpened = FALSE;
  184. WIN32_FIND_DATAA sFind32;
  185. if (hShadowDB == INVALID_HANDLE_VALUE)
  186. {
  187. hShadowDB = OpenShadowDatabaseIO();
  188. if (hShadowDB == INVALID_HANDLE_VALUE)
  189. {
  190. return 0;
  191. }
  192. fDBOpened = TRUE;
  193. }
  194. memset(sFind32.cFileName, 0, sizeof(sFind32.cFileName));
  195. len = min(sizeof(sFind32.cFileName)-1,strlen(lpszFileName));
  196. strncpy(sFind32.cFileName, lpszFileName, len);
  197. sFind32.dwFileAttributes = FILE_ATTRIBUTE_SYSTEM; // to make it explicit
  198. sSI.hDir = hDir;
  199. sSI.hShadow = hShadow;
  200. sSI.uOp = SHADOW_COPY_INODE_FILE;
  201. sSI.lpFind32 = (WIN32_FIND_DATAW *)&sFind32;
  202. iRet = DeviceIoControl(hShadowDB, IOCTL_DO_SHADOW_MAINTENANCE, (LPVOID)&(sSI), 0, NULL, 0, &DummyBytesReturned, NULL);
  203. if (fDBOpened)
  204. {
  205. CloseShadowDatabaseIO(hShadowDB);
  206. }
  207. if (iRet)
  208. {
  209. iRet = SetFileAttributesA(lpszFileName, 0);
  210. }
  211. if (!iRet)
  212. {
  213. DeleteFileA(lpszFileName);
  214. SetLastError(sSI.dwError);
  215. }
  216. return (iRet);
  217. }
  218. /*****************************************************************************
  219. * GetUNCPath(). Pass in hShare, hDir, hShadow and get a LPCOPYPARAMS
  220. * filled out fully.
  221. */
  222. int
  223. GetUNCPathA(
  224. HANDLE hShadowDB,
  225. HSHARE hShare,
  226. HSHADOW hDir,
  227. HSHADOW hShadow,
  228. LPCOPYPARAMSA lpCP
  229. )
  230. {
  231. int iRet = 0;
  232. LPCOPYPARAMSW lpCPW;
  233. if (lpCPW = LpAllocCopyParamsW())
  234. {
  235. iRet = GetUNCPathW(hShadowDB, hShare, hDir, hShadow, lpCPW);
  236. if (iRet == 1)
  237. {
  238. ConvertCopyParamsFromUnicodeToAnsi(lpCPW, lpCP);
  239. }
  240. FreeCopyParamsW(lpCPW);
  241. }
  242. return (iRet);
  243. }
  244. /*****************************************************************************
  245. */
  246. int
  247. ChkUpdtStatusA(
  248. HANDLE hShadowDB,
  249. unsigned long hDir,
  250. unsigned long hShadow,
  251. LPWIN32_FIND_DATAA lpFind32,
  252. unsigned long *lpulShadowStatus
  253. )
  254. {
  255. WIN32_FIND_DATAW sFind32W;
  256. int iRet;
  257. iRet = ChkUpdtStatusW(hShadowDB, hDir, hShadow, (lpFind32)?&sFind32W:NULL, lpulShadowStatus);
  258. if ((iRet == 1) && lpFind32)
  259. {
  260. Find32WToFind32A(&sFind32W, lpFind32);
  261. }
  262. return (iRet);
  263. }
  264. int
  265. GetShareInfoA(
  266. HANDLE hShadowDB,
  267. HSHARE hShare,
  268. LPSHAREINFOA lpSVRI,
  269. unsigned long *lpulStatus
  270. )
  271. {
  272. int iRet;
  273. SHAREINFOW sShareInfoW;
  274. iRet = GetShareInfoW(hShadowDB, hShare, (lpSVRI)?&sShareInfoW:NULL, lpulStatus);
  275. if ((iRet==1) && lpSVRI)
  276. {
  277. ShareInfoWToShareInfoA(&sShareInfoW, lpSVRI);
  278. }
  279. return iRet;
  280. }
  281. BOOL
  282. CopyShadowW(
  283. HANDLE hShadowDB,
  284. HSHADOW hDir,
  285. HSHADOW hShadow,
  286. LPWSTR lpwFileName
  287. )
  288. {
  289. char chBuff[MAX_PATH];
  290. memset(chBuff, 0, sizeof(chBuff));
  291. WideCharToMultiByte(CP_ACP, 0, lpwFileName, wcslen(lpwFileName), chBuff, MAX_PATH, NULL, NULL);
  292. return (CopyShadowA(INVALID_HANDLE_VALUE, hDir, hShadow, chBuff));
  293. }
  294. /*****************************************************************************
  295. * Cache maintenance ioctl
  296. */
  297. int
  298. DoShadowMaintenance(
  299. HANDLE hShadowDB,
  300. unsigned long uOp
  301. )
  302. {
  303. SHADOWINFO sSI;
  304. int iRet;
  305. BOOL fDBOpened = FALSE;
  306. if (hShadowDB == INVALID_HANDLE_VALUE)
  307. {
  308. hShadowDB = OpenShadowDatabaseIO();
  309. if (hShadowDB == INVALID_HANDLE_VALUE)
  310. {
  311. return 0;
  312. }
  313. fDBOpened = TRUE;
  314. }
  315. sSI.uOp = uOp;
  316. iRet = DeviceIoControl(hShadowDB, IOCTL_DO_SHADOW_MAINTENANCE, (LPVOID)&(sSI), 0, NULL, 0, &DummyBytesReturned, NULL);
  317. if (fDBOpened)
  318. {
  319. CloseShadowDatabaseIO(hShadowDB);
  320. }
  321. if (!iRet)
  322. {
  323. SetLastError(sSI.dwError);
  324. }
  325. return (iRet);
  326. }
  327. int
  328. SetMaxShadowSpace(
  329. HANDLE hShadowDB,
  330. long nFileSizeHigh,
  331. long nFileSizeLow
  332. )
  333. {
  334. SHADOWINFO sSI;
  335. WIN32_FIND_DATAW sFind32;
  336. int iRet;
  337. BOOL fDBOpened = FALSE;
  338. if (hShadowDB == INVALID_HANDLE_VALUE)
  339. {
  340. hShadowDB = OpenShadowDatabaseIO();
  341. if (hShadowDB == INVALID_HANDLE_VALUE)
  342. {
  343. return 0;
  344. }
  345. fDBOpened = TRUE;
  346. }
  347. memset(&sFind32, 0, sizeof(WIN32_FIND_DATAW));
  348. memset(&sSI, 0, sizeof(SHADOWINFO));
  349. sFind32.nFileSizeHigh = nFileSizeHigh;
  350. sFind32.nFileSizeLow = nFileSizeLow;
  351. sSI.lpFind32 = &sFind32;
  352. sSI.uOp = SHADOW_SET_MAX_SPACE;
  353. iRet = DeviceIoControl(hShadowDB , IOCTL_DO_SHADOW_MAINTENANCE
  354. ,(LPVOID)(&sSI), 0
  355. , NULL, 0
  356. , &DummyBytesReturned, NULL);
  357. if (fDBOpened)
  358. {
  359. CloseShadowDatabaseIO(hShadowDB);
  360. }
  361. if (!iRet)
  362. {
  363. SetLastError(sSI.dwError);
  364. }
  365. return (iRet);
  366. }
  367. BOOL
  368. PurgeUnpinnedFiles(
  369. HANDLE hShadowDB,
  370. LONG Timeout,
  371. PULONG pnFiles,
  372. PULONG pnYoungFiles)
  373. {
  374. SHADOWINFO sSI;
  375. WIN32_FIND_DATAW sFind32;
  376. BOOL fDBOpened = FALSE;
  377. BOOL bRet;
  378. if (hShadowDB == INVALID_HANDLE_VALUE) {
  379. hShadowDB = OpenShadowDatabaseIO();
  380. if (hShadowDB == INVALID_HANDLE_VALUE) {
  381. return 0;
  382. }
  383. fDBOpened = TRUE;
  384. }
  385. memset(&sFind32, 0, sizeof(WIN32_FIND_DATAW));
  386. memset(&sSI, 0, sizeof(SHADOWINFO));
  387. sFind32.nFileSizeHigh = Timeout;
  388. sSI.lpFind32 = &sFind32;
  389. sSI.uOp = SHADOW_PURGE_UNPINNED_FILES;
  390. bRet = DeviceIoControl(
  391. hShadowDB,
  392. IOCTL_DO_SHADOW_MAINTENANCE,
  393. (LPVOID)(&sSI),
  394. 0,
  395. NULL,
  396. 0,
  397. &DummyBytesReturned,
  398. NULL);
  399. if (fDBOpened)
  400. CloseShadowDatabaseIO(hShadowDB);
  401. if (bRet == TRUE) {
  402. *pnFiles = sFind32.nFileSizeHigh;
  403. *pnYoungFiles = sFind32.nFileSizeLow;
  404. }
  405. return (bRet);
  406. }
  407. BOOL
  408. ShareIdToShareName(
  409. HANDLE hShadowDB,
  410. ULONG ShareId,
  411. PBYTE Buffer,
  412. LPDWORD pBufSize)
  413. {
  414. SHADOWINFO sSI;
  415. int iRet;
  416. BOOL fDBOpened = FALSE;
  417. if (hShadowDB == INVALID_HANDLE_VALUE) {
  418. hShadowDB = OpenShadowDatabaseIO();
  419. if (hShadowDB == INVALID_HANDLE_VALUE)
  420. return 0;
  421. fDBOpened = TRUE;
  422. }
  423. memset(&sSI, 0, sizeof(SHADOWINFO));
  424. sSI.hShare = ShareId;
  425. sSI.lpBuffer = (LPVOID)(Buffer);
  426. sSI.cbBufferSize = *pBufSize;
  427. iRet = DeviceIoControl(
  428. hShadowDB,
  429. IOCTL_SHAREID_TO_SHARENAME,
  430. (LPVOID)(&sSI), 0,
  431. NULL, 0,
  432. &DummyBytesReturned, NULL);
  433. if (fDBOpened)
  434. CloseShadowDatabaseIO(hShadowDB);
  435. if (!iRet) {
  436. *pBufSize = sSI.cbBufferSize;
  437. SetLastError(sSI.dwError);
  438. }
  439. return (iRet);
  440. }
  441. /*****************************************************************************
  442. * Priority queue enumerators
  443. */
  444. int
  445. BeginPQEnum(
  446. HANDLE hShadowDB,
  447. LPPQPARAMS lpPQP
  448. )
  449. {
  450. return DeviceIoControl(hShadowDB, IOCTL_SHADOW_BEGIN_PQ_ENUM
  451. ,(LPVOID)(lpPQP), 0, NULL, 0, &DummyBytesReturned, NULL);
  452. }
  453. int
  454. NextPriShadow(
  455. HANDLE hShadowDB,
  456. LPPQPARAMS lpPQP
  457. )
  458. {
  459. return DeviceIoControl(hShadowDB, IOCTL_SHADOW_NEXT_PRI_SHADOW
  460. ,(LPVOID)(lpPQP), 0, NULL, 0, &DummyBytesReturned, NULL);
  461. }
  462. int
  463. PrevPriShadow(
  464. HANDLE hShadowDB,
  465. LPPQPARAMS lpPQP
  466. )
  467. {
  468. return DeviceIoControl(hShadowDB, IOCTL_SHADOW_PREV_PRI_SHADOW
  469. ,(LPVOID)(lpPQP), 0, NULL, 0, &DummyBytesReturned, NULL);
  470. }
  471. int
  472. EndPQEnum(
  473. HANDLE hShadowDB,
  474. LPPQPARAMS lpPQP
  475. )
  476. {
  477. return DeviceIoControl(hShadowDB, IOCTL_SHADOW_END_PQ_ENUM
  478. ,(LPVOID)(lpPQP), 0, NULL, 0, &DummyBytesReturned, NULL);
  479. }
  480. /*****************************************************************************
  481. * FreeShadowSpace(). Pass in lpFind32 with filesize stuff filled out?.
  482. * tHACK: not a very elegant interface.
  483. */
  484. int
  485. FreeShadowSpace(
  486. HANDLE hShadowDB,
  487. long nFileSizeHigh,
  488. long nFileSizeLow,
  489. BOOL fClearAll
  490. )
  491. {
  492. SHADOWINFO sSI;
  493. int iRet;
  494. BOOL fDBOpened = FALSE;
  495. WIN32_FIND_DATAW sFind32;
  496. if (hShadowDB == INVALID_HANDLE_VALUE)
  497. {
  498. hShadowDB = OpenShadowDatabaseIO();
  499. if (hShadowDB == INVALID_HANDLE_VALUE)
  500. {
  501. return 0;
  502. }
  503. fDBOpened = TRUE;
  504. }
  505. memset(&sSI, 0, sizeof(SHADOWINFO));
  506. memset(&sFind32, 0, sizeof(sFind32));
  507. sFind32.nFileSizeHigh = nFileSizeHigh;
  508. sFind32.nFileSizeLow = nFileSizeLow;
  509. sSI.lpFind32 = (LPWIN32_FIND_DATAW)&sFind32;
  510. sSI.uOp = SHADOW_MAKE_SPACE;
  511. if (fClearAll)
  512. {
  513. sSI.ulHintPri = 0xffffffff;
  514. }
  515. iRet = DeviceIoControl(hShadowDB , IOCTL_DO_SHADOW_MAINTENANCE
  516. ,(LPVOID)(&sSI), 0
  517. , NULL, 0
  518. , &DummyBytesReturned, NULL);
  519. if (fDBOpened)
  520. {
  521. CloseShadowDatabaseIO(hShadowDB);
  522. }
  523. if (!iRet)
  524. {
  525. SetLastError(sSI.dwError);
  526. }
  527. return (iRet);
  528. }
  529. int
  530. GetSpaceStats(
  531. HANDLE hShadowDB,
  532. SHADOWSTORE *lpsST
  533. )
  534. {
  535. SHADOWINFO sSI;
  536. int iRet;
  537. BOOL fDBOpened = FALSE;
  538. SHADOWSTORE sST;
  539. if (hShadowDB == INVALID_HANDLE_VALUE)
  540. {
  541. hShadowDB = OpenShadowDatabaseIO();
  542. if (hShadowDB == INVALID_HANDLE_VALUE)
  543. {
  544. return 0;
  545. }
  546. fDBOpened = TRUE;
  547. }
  548. memset(&sSI, 0, sizeof(SHADOWINFO));
  549. memset(&sST, 0, sizeof(sST));
  550. sSI.lpBuffer = (LPVOID)&sST;
  551. sSI.cbBufferSize = sizeof(sST);
  552. sSI.uOp = SHADOW_GET_SPACE_STATS;
  553. iRet = DeviceIoControl(hShadowDB , IOCTL_DO_SHADOW_MAINTENANCE
  554. ,(LPVOID)(&sSI), 0
  555. , NULL, 0
  556. , &DummyBytesReturned, NULL);
  557. if (fDBOpened)
  558. {
  559. CloseShadowDatabaseIO(hShadowDB);
  560. }
  561. *lpsST = sST;
  562. return (iRet);
  563. }
  564. /*****************************************************************************
  565. */
  566. #ifndef NT
  567. int CopyChunk(
  568. HANDLE hShadowDB,
  569. LPSHADOWINFO lpSI,
  570. struct tagCOPYCHUNKCONTEXT FAR *CopyChunkContext
  571. )
  572. {
  573. int iRet;
  574. BOOL fDBOpened = FALSE;
  575. if (hShadowDB == INVALID_HANDLE_VALUE)
  576. {
  577. hShadowDB = OpenShadowDatabaseIO();
  578. if (hShadowDB == INVALID_HANDLE_VALUE)
  579. {
  580. return 0;
  581. }
  582. fDBOpened = TRUE;
  583. }
  584. iRet = DeviceIoControl(hShadowDB , IOCTL_SHADOW_COPYCHUNK
  585. ,(LPVOID)(lpSI), 0
  586. , (LPVOID)CopyChunkContext, 0
  587. , &DummyBytesReturned, NULL);
  588. if (fDBOpened)
  589. {
  590. CloseShadowDatabaseIO(hShadowDB);
  591. }
  592. return (iRet);
  593. }
  594. #else
  595. int CopyChunk(
  596. HANDLE hShadowDB,
  597. LPSHADOWINFO lpSI,
  598. struct tagCOPYCHUNKCONTEXT FAR *CopyChunkContext
  599. )
  600. {
  601. BOOL Success;
  602. BOOL fDBOpened = FALSE;
  603. if (hShadowDB == INVALID_HANDLE_VALUE)
  604. {
  605. hShadowDB = OpenShadowDatabaseIO();
  606. if (hShadowDB == INVALID_HANDLE_VALUE)
  607. {
  608. return 0;
  609. }
  610. fDBOpened = TRUE;
  611. }
  612. CopyChunkContext->LastAmountRead = 0;
  613. Success = DeviceIoControl(hShadowDB , IOCTL_SHADOW_COPYCHUNK
  614. , (LPVOID)(lpSI), 0
  615. , (LPVOID)CopyChunkContext, sizeof(*CopyChunkContext)
  616. , &DummyBytesReturned, NULL);
  617. if (fDBOpened)
  618. {
  619. CloseShadowDatabaseIO(hShadowDB);
  620. }
  621. return(Success);
  622. }
  623. int CloseFileWithCopyChunkIntent(
  624. HANDLE hShadowDB,
  625. struct tagCOPYCHUNKCONTEXT FAR *CopyChunkContext
  626. )
  627. {
  628. BOOL Success;
  629. BOOL fDBOpened = FALSE;
  630. if (hShadowDB == INVALID_HANDLE_VALUE)
  631. {
  632. hShadowDB = OpenShadowDatabaseIO();
  633. if (hShadowDB == INVALID_HANDLE_VALUE)
  634. {
  635. return 0;
  636. }
  637. fDBOpened = TRUE;
  638. }
  639. Success = DeviceIoControl(hShadowDB , IOCTL_CLOSEFORCOPYCHUNK
  640. , NULL, 0
  641. , (LPVOID)CopyChunkContext, sizeof(*CopyChunkContext)
  642. , &DummyBytesReturned, NULL);
  643. if (fDBOpened)
  644. {
  645. CloseShadowDatabaseIO(hShadowDB);
  646. }
  647. return(Success);
  648. }
  649. int OpenFileWithCopyChunkIntent(
  650. HANDLE hShadowDB,
  651. LPCWSTR lpFileName,
  652. struct tagCOPYCHUNKCONTEXT FAR *CopyChunkContext,
  653. int ChunkSize
  654. )
  655. {
  656. BOOL Success;
  657. int FileNameLength;
  658. BOOL fDBOpened = FALSE;
  659. if (hShadowDB == INVALID_HANDLE_VALUE)
  660. {
  661. hShadowDB = OpenShadowDatabaseIO();
  662. if (hShadowDB == INVALID_HANDLE_VALUE)
  663. {
  664. return 0;
  665. }
  666. fDBOpened = TRUE;
  667. }
  668. FileNameLength = wcslen(lpFileName) * sizeof(USHORT);
  669. CopyChunkContext->ChunkSize = ChunkSize;
  670. Success = DeviceIoControl(hShadowDB , IOCTL_OPENFORCOPYCHUNK
  671. , (LPVOID)lpFileName, FileNameLength
  672. , (LPVOID)CopyChunkContext, sizeof(*CopyChunkContext)
  673. , &DummyBytesReturned, NULL);
  674. if (fDBOpened)
  675. {
  676. CloseShadowDatabaseIO(hShadowDB);
  677. }
  678. return(Success);
  679. }
  680. #endif
  681. int
  682. BeginReint(
  683. HSHARE hShare,
  684. BOOL fBlockingReint,
  685. LPREINT_IO *lplpReintIO
  686. )
  687. {
  688. SHADOWINFO sSI;
  689. LPREINT_IO lpReintIO = NULL;
  690. BOOL fSuccess = FALSE;
  691. memset(&sSI, 0, sizeof(SHADOWINFO));
  692. sSI.hShare = hShare;
  693. lpReintIO = LocalAlloc(LPTR, sizeof(REINT_IO));
  694. if (!lpReintIO)
  695. {
  696. return 0;
  697. }
  698. // don't create hevent in the overlapped structure because we are not going to do any read write
  699. // on this
  700. if (!fBlockingReint)
  701. {
  702. sSI.uOp = 1;
  703. }
  704. // create an async handle
  705. lpReintIO->hShadowDBAsync = OpenShadowDatabaseIOex(1, FILE_FLAG_OVERLAPPED);
  706. if (lpReintIO->hShadowDBAsync == INVALID_HANDLE_VALUE)
  707. {
  708. goto bailout;
  709. }
  710. *lplpReintIO = lpReintIO;
  711. // issue an overlapped I/O request
  712. // This creates an IRP which is cancelled when the thread that is merging
  713. // dies in the middle of a merge
  714. fSuccess = DeviceIoControl(lpReintIO->hShadowDBAsync , IOCTL_SHADOW_BEGIN_REINT
  715. ,(LPVOID)(&sSI), 0
  716. , NULL, 0
  717. , &DummyBytesReturned, &(lpReintIO->sOverlapped));
  718. bailout:
  719. if (!fSuccess)
  720. {
  721. DWORD dwError;
  722. dwError = GetLastError();
  723. if (dwError != ERROR_IO_PENDING)
  724. {
  725. if (lpReintIO->hShadowDBAsync != INVALID_HANDLE_VALUE)
  726. {
  727. CloseHandle(lpReintIO->hShadowDBAsync);
  728. }
  729. LocalFree(lpReintIO);
  730. SetLastError(dwError);
  731. *lplpReintIO = NULL;
  732. }
  733. else
  734. {
  735. fSuccess = TRUE;
  736. }
  737. }
  738. return fSuccess;
  739. }
  740. int
  741. EndReint(
  742. HSHARE hShare,
  743. LPREINT_IO lpReintIO
  744. )
  745. {
  746. SHADOWINFO sSI;
  747. BOOL fSuccess;
  748. DWORD dwError = NO_ERROR;
  749. memset(&sSI, 0, sizeof(SHADOWINFO));
  750. sSI.hShare = hShare;
  751. fSuccess = DeviceIoControl(lpReintIO->hShadowDBAsync , IOCTL_SHADOW_END_REINT
  752. ,(LPVOID)(&sSI), 0
  753. , NULL, 0
  754. , &DummyBytesReturned, NULL);
  755. if (!fSuccess)
  756. {
  757. dwError = GetLastError();
  758. }
  759. CloseHandle(lpReintIO->hShadowDBAsync);
  760. LocalFree(lpReintIO);
  761. if (!fSuccess)
  762. {
  763. SetLastError(dwError);
  764. }
  765. return fSuccess;
  766. }
  767. int
  768. SetShareStatus(
  769. HANDLE hShadowDB,
  770. HSHARE hShare,
  771. unsigned long uStatus,
  772. unsigned long uOp
  773. )
  774. {
  775. SHADOWINFO sSI;
  776. int iRet;
  777. BOOL fDBOpened = FALSE;
  778. if (hShadowDB == INVALID_HANDLE_VALUE)
  779. {
  780. hShadowDB = OpenShadowDatabaseIO();
  781. if (hShadowDB == INVALID_HANDLE_VALUE)
  782. {
  783. return 0;
  784. }
  785. fDBOpened = TRUE;
  786. }
  787. memset(&sSI, 0, sizeof(SHADOWINFO));
  788. sSI.hShare = hShare;
  789. sSI.uStatus = uStatus;
  790. sSI.uOp = uOp;
  791. iRet = DeviceIoControl(hShadowDB , IOCTL_SET_SHARE_STATUS
  792. ,(LPVOID)(&sSI), 0
  793. , NULL, 0
  794. , &DummyBytesReturned, NULL);
  795. if (fDBOpened)
  796. {
  797. CloseShadowDatabaseIO(hShadowDB);
  798. }
  799. if (!iRet)
  800. {
  801. SetLastError(sSI.dwError);
  802. }
  803. return (iRet);
  804. }
  805. int
  806. GetShareStatus(
  807. HANDLE hShadowDB,
  808. HSHARE hShare,
  809. unsigned long *lpulStatus
  810. )
  811. {
  812. SHADOWINFO sSI;
  813. int iRet;
  814. BOOL fDBOpened = FALSE;
  815. if (hShadowDB == INVALID_HANDLE_VALUE)
  816. {
  817. hShadowDB = OpenShadowDatabaseIO();
  818. if (hShadowDB == INVALID_HANDLE_VALUE)
  819. {
  820. return 0;
  821. }
  822. fDBOpened = TRUE;
  823. }
  824. memset(&sSI, 0, sizeof(SHADOWINFO));
  825. sSI.hShare = hShare;
  826. iRet = DeviceIoControl(hShadowDB , IOCTL_GET_SHARE_STATUS
  827. ,(LPVOID)(&sSI), 0
  828. , NULL, 0
  829. , &DummyBytesReturned, NULL);
  830. if(iRet)
  831. {
  832. *lpulStatus = sSI.uStatus;
  833. }
  834. else
  835. {
  836. *lpulStatus = 0;
  837. }
  838. if (fDBOpened)
  839. {
  840. CloseShadowDatabaseIO(hShadowDB);
  841. }
  842. if (!iRet)
  843. {
  844. SetLastError(sSI.dwError);
  845. }
  846. return iRet;
  847. }
  848. int ShadowSwitches(
  849. HANDLE hShadowDB,
  850. unsigned long *lpuSwitches,
  851. unsigned long uOp
  852. )
  853. {
  854. SHADOWINFO sSI;
  855. int iRet;
  856. BOOL fDBOpened = FALSE;
  857. if (hShadowDB == INVALID_HANDLE_VALUE)
  858. {
  859. hShadowDB = OpenShadowDatabaseIO();
  860. if (hShadowDB == INVALID_HANDLE_VALUE)
  861. {
  862. return 0;
  863. }
  864. fDBOpened = TRUE;
  865. }
  866. memset(&sSI, 0, sizeof(SHADOWINFO));
  867. sSI.uStatus = *lpuSwitches;
  868. sSI.uOp = uOp;
  869. iRet = DeviceIoControl(hShadowDB , IOCTL_SWITCHES
  870. ,(LPVOID)(&sSI), 0
  871. , NULL, 0
  872. , &DummyBytesReturned, NULL);
  873. *lpuSwitches = sSI.uStatus;
  874. if (fDBOpened)
  875. {
  876. CloseShadowDatabaseIO(hShadowDB);
  877. }
  878. if (!iRet)
  879. {
  880. SetLastError(sSI.dwError);
  881. }
  882. return (iRet);
  883. }
  884. int GetShadowDatabaseLocationW(
  885. HANDLE hShadowDB,
  886. WIN32_FIND_DATAW *lpFind32W
  887. )
  888. {
  889. SHADOWINFO sSI;
  890. int iRet;
  891. BOOL fDBOpened = FALSE;
  892. if (hShadowDB == INVALID_HANDLE_VALUE)
  893. {
  894. hShadowDB = OpenShadowDatabaseIO();
  895. if (hShadowDB == INVALID_HANDLE_VALUE)
  896. {
  897. return 0;
  898. }
  899. fDBOpened = TRUE;
  900. }
  901. memset(&sSI, 0, sizeof(SHADOWINFO));
  902. sSI.uStatus = SHADOW_SWITCH_SHADOWING;
  903. sSI.uOp = SHADOW_SWITCH_GET_STATE;
  904. sSI.lpFind32 = lpFind32W;
  905. iRet = DeviceIoControl(hShadowDB , IOCTL_SWITCHES
  906. ,(LPVOID)(&sSI), 0
  907. , NULL, 0
  908. , &DummyBytesReturned, NULL);
  909. if (fDBOpened)
  910. {
  911. CloseShadowDatabaseIO(hShadowDB);
  912. }
  913. if (!iRet)
  914. {
  915. SetLastError(sSI.dwError);
  916. }
  917. return (iRet);
  918. }
  919. int EnableShadowing(
  920. HANDLE hShadowDB,
  921. LPCSTR lpszDatabaseLocation, // location of the shadowing directory
  922. LPCSTR lpszUserName, // name of the user
  923. DWORD dwDefDataSizeHigh, // cache size if being created for the first time
  924. DWORD dwDefDataSizeLow,
  925. DWORD dwClusterSize,
  926. BOOL fReformat
  927. )
  928. {
  929. SHADOWINFO sSI;
  930. WIN32_FIND_DATAA sFind32;
  931. int iRet;
  932. BOOL fDBOpened = FALSE;
  933. if (hShadowDB == INVALID_HANDLE_VALUE)
  934. {
  935. hShadowDB = OpenShadowDatabaseIO();
  936. if (hShadowDB == INVALID_HANDLE_VALUE)
  937. {
  938. return 0;
  939. }
  940. fDBOpened = TRUE;
  941. }
  942. memset(&sSI, 0, sizeof(SHADOWINFO));
  943. memset(&sFind32, 0, sizeof(WIN32_FIND_DATAA));
  944. sFind32.nFileSizeHigh = dwDefDataSizeHigh;
  945. sFind32.nFileSizeLow = dwDefDataSizeLow;
  946. sFind32.dwReserved1 = dwClusterSize;
  947. if (lpszDatabaseLocation)
  948. {
  949. if (strlen(lpszDatabaseLocation) > sizeof(sFind32.cFileName))
  950. {
  951. SetLastError(ERROR_INVALID_PARAMETER);
  952. return 0;
  953. }
  954. strcpy(sFind32.cFileName, lpszDatabaseLocation);
  955. }
  956. if (lpszUserName)
  957. {
  958. strncpy(sFind32.cAlternateFileName, lpszUserName, MAX_USERNAME);
  959. }
  960. sSI.uStatus = SHADOW_SWITCH_SHADOWING;
  961. sSI.uOp = SHADOW_SWITCH_ON;
  962. sSI.ulRefPri = fReformat;
  963. sSI.lpFind32 = (WIN32_FIND_DATAW *)&sFind32;
  964. iRet = DeviceIoControl(hShadowDB , IOCTL_SWITCHES
  965. ,(LPVOID)(&sSI), 0
  966. , NULL, 0
  967. , &DummyBytesReturned, NULL);
  968. if (fDBOpened)
  969. {
  970. CloseShadowDatabaseIO(hShadowDB);
  971. }
  972. if (!iRet)
  973. {
  974. SetLastError(sSI.dwError);
  975. }
  976. return (iRet);
  977. }
  978. int
  979. RegisterAgent(
  980. HANDLE hShadowDB,
  981. HWND hwndAgent,
  982. HANDLE hEvent
  983. )
  984. {
  985. SHADOWINFO sSI;
  986. int iRet;
  987. BOOL fDBOpened = FALSE;
  988. if (hShadowDB == INVALID_HANDLE_VALUE)
  989. {
  990. hShadowDB = __OpenShadowDatabaseIO(1);
  991. if (hShadowDB == INVALID_HANDLE_VALUE)
  992. {
  993. return 0;
  994. }
  995. fDBOpened = TRUE;
  996. }
  997. memset(&sSI, 0, sizeof(sSI));
  998. sSI.hShare = HandleToUlong(hwndAgent);
  999. sSI.hDir = HandleToUlong(hEvent);
  1000. //
  1001. // Ensure that we're dealing with truncatable handles here
  1002. //
  1003. Assert( (HANDLE)sSI.hShare == hwndAgent );
  1004. Assert( (HANDLE)sSI.hDir == hEvent );
  1005. iRet = DeviceIoControl(hShadowDB, IOCTL_SHADOW_REGISTER_AGENT,
  1006. (LPVOID)&sSI, 0,
  1007. NULL, 0,
  1008. &DummyBytesReturned, NULL);
  1009. if (fDBOpened)
  1010. {
  1011. CloseShadowDatabaseIO(hShadowDB);
  1012. }
  1013. if (!iRet)
  1014. {
  1015. SetLastError(sSI.dwError);
  1016. }
  1017. return (iRet);
  1018. }
  1019. int
  1020. UnregisterAgent(
  1021. HANDLE hShadowDB,
  1022. HWND hwndAgent
  1023. )
  1024. {
  1025. int iRet;
  1026. BOOL fDBOpened = FALSE;
  1027. if (hShadowDB == INVALID_HANDLE_VALUE)
  1028. {
  1029. hShadowDB = OpenShadowDatabaseIO();
  1030. if (hShadowDB == INVALID_HANDLE_VALUE)
  1031. {
  1032. return 0;
  1033. }
  1034. fDBOpened = TRUE;
  1035. }
  1036. iRet = DeviceIoControl(hShadowDB, IOCTL_SHADOW_UNREGISTER_AGENT,
  1037. (LPVOID)hwndAgent, 0,
  1038. NULL, 0,
  1039. &DummyBytesReturned, NULL);
  1040. if (fDBOpened)
  1041. {
  1042. CloseShadowDatabaseIO(hShadowDB);
  1043. }
  1044. return (iRet);
  1045. }
  1046. int
  1047. DisableShadowingForThisThread(
  1048. HANDLE hShadowDB
  1049. )
  1050. {
  1051. int iRet;
  1052. BOOL fDBOpened = FALSE;
  1053. if (hShadowDB == INVALID_HANDLE_VALUE)
  1054. {
  1055. hShadowDB = OpenShadowDatabaseIO();
  1056. if (hShadowDB == INVALID_HANDLE_VALUE)
  1057. {
  1058. return 0;
  1059. }
  1060. fDBOpened = TRUE;
  1061. }
  1062. iRet = DoShadowMaintenance(hShadowDB, SHADOW_PER_THREAD_DISABLE);
  1063. if (fDBOpened)
  1064. {
  1065. CloseShadowDatabaseIO(hShadowDB);
  1066. }
  1067. return (iRet);
  1068. }
  1069. int
  1070. EnableShadowingForThisThread(
  1071. HANDLE hShadowDB
  1072. )
  1073. {
  1074. int iRet;
  1075. BOOL fDBOpened = FALSE;
  1076. if (hShadowDB == INVALID_HANDLE_VALUE)
  1077. {
  1078. hShadowDB = OpenShadowDatabaseIO();
  1079. if (hShadowDB == INVALID_HANDLE_VALUE)
  1080. {
  1081. return 0;
  1082. }
  1083. fDBOpened = TRUE;
  1084. }
  1085. iRet = DoShadowMaintenance(hShadowDB, SHADOW_PER_THREAD_ENABLE);
  1086. if (fDBOpened)
  1087. {
  1088. CloseShadowDatabaseIO(hShadowDB);
  1089. }
  1090. return (iRet);
  1091. }
  1092. int
  1093. ReinitShadowDatabase(
  1094. HANDLE hShadowDB,
  1095. LPCSTR lpszDatabaseLocation, // location of the shadowing directory
  1096. LPCSTR lpszUserName, // name of the user
  1097. DWORD dwDefDataSizeHigh, // cache size if being created for the first time
  1098. DWORD dwDefDataSizeLow,
  1099. DWORD dwClusterSize
  1100. )
  1101. {
  1102. SHADOWINFO sSI;
  1103. WIN32_FIND_DATAA sFind32;
  1104. int iRet;
  1105. BOOL fDBOpened = FALSE;
  1106. if (hShadowDB == INVALID_HANDLE_VALUE)
  1107. {
  1108. hShadowDB = OpenShadowDatabaseIO();
  1109. if (hShadowDB == INVALID_HANDLE_VALUE)
  1110. {
  1111. return 0;
  1112. }
  1113. fDBOpened = TRUE;
  1114. }
  1115. memset(&sSI, 0, sizeof(SHADOWINFO));
  1116. memset(&sFind32, 0, sizeof(WIN32_FIND_DATAA));
  1117. sFind32.nFileSizeHigh = dwDefDataSizeHigh;
  1118. sFind32.nFileSizeLow = dwDefDataSizeLow;
  1119. sFind32.dwReserved1 = dwClusterSize;
  1120. if (lpszDatabaseLocation)
  1121. {
  1122. if (strlen(lpszDatabaseLocation) > sizeof(sFind32.cFileName))
  1123. {
  1124. SetLastError(ERROR_INVALID_PARAMETER);
  1125. return 0;
  1126. }
  1127. strcpy(sFind32.cFileName, lpszDatabaseLocation);
  1128. }
  1129. if (lpszUserName)
  1130. {
  1131. strncpy(sFind32.cAlternateFileName, lpszUserName, MAX_USERNAME);
  1132. }
  1133. sSI.uOp = SHADOW_REINIT_DATABASE;
  1134. sSI.lpFind32 = (WIN32_FIND_DATAW *)&sFind32;
  1135. iRet = DeviceIoControl(hShadowDB , IOCTL_DO_SHADOW_MAINTENANCE
  1136. ,(LPVOID)(&sSI), 0
  1137. , NULL, 0
  1138. , &DummyBytesReturned, NULL);
  1139. if (fDBOpened)
  1140. {
  1141. CloseShadowDatabaseIO(hShadowDB);
  1142. }
  1143. if (!iRet)
  1144. {
  1145. SetLastError(sSI.dwError);
  1146. }
  1147. return (iRet);
  1148. }
  1149. BOOL
  1150. IsNetDisconnected(
  1151. DWORD dwErrorCode
  1152. )
  1153. {
  1154. int i;
  1155. if (dwErrorCode != NO_ERROR)
  1156. {
  1157. for (i=0; i< (sizeof(rgdwErrorTab)/sizeof(DWORD)); ++i)
  1158. {
  1159. if (rgdwErrorTab[i] == dwErrorCode)
  1160. {
  1161. // DEBUG_PRINT(("lib3: IsNetDisconnected on %d\r\n", dwErrorCode));
  1162. return TRUE;
  1163. }
  1164. }
  1165. }
  1166. return FALSE;
  1167. }
  1168. int
  1169. FindCreatePrincipalIDFromSID(
  1170. HANDLE hShadowDB,
  1171. LPVOID lpSidBuffer,
  1172. ULONG cbSidLength,
  1173. ULONG *lpuPrincipalID,
  1174. BOOL fCreate
  1175. )
  1176. {
  1177. SHADOWINFO sSI;
  1178. int iRet;
  1179. BOOL fDBOpened = FALSE;
  1180. if (hShadowDB == INVALID_HANDLE_VALUE)
  1181. {
  1182. hShadowDB = OpenShadowDatabaseIO();
  1183. if (hShadowDB == INVALID_HANDLE_VALUE)
  1184. {
  1185. return 0;
  1186. }
  1187. fDBOpened = TRUE;
  1188. }
  1189. memset(&sSI, 0, sizeof(SHADOWINFO));
  1190. sSI.uSubOperation = SHADOW_FIND_CREATE_PRINCIPAL_ID;
  1191. sSI.lpBuffer = lpSidBuffer;
  1192. sSI.cbBufferSize = cbSidLength;
  1193. sSI.uStatus = fCreate;
  1194. iRet = DeviceIoControl(hShadowDB , IOCTL_DO_SHADOW_MAINTENANCE
  1195. ,(LPVOID)(&sSI), 0
  1196. , NULL, 0
  1197. , &DummyBytesReturned, NULL);
  1198. if (fDBOpened)
  1199. {
  1200. CloseShadowDatabaseIO(hShadowDB);
  1201. }
  1202. if (iRet)
  1203. {
  1204. *lpuPrincipalID = sSI.ulPrincipalID;
  1205. }
  1206. else
  1207. {
  1208. SetLastError(sSI.dwError);
  1209. }
  1210. return (iRet);
  1211. }
  1212. int
  1213. GetSecurityInfoForCSC(
  1214. HANDLE hShadowDB,
  1215. HSHADOW hDir,
  1216. HSHADOW hShadow,
  1217. LPSECURITYINFO lpSecurityInfo,
  1218. DWORD *lpdwBufferSize
  1219. )
  1220. {
  1221. SHADOWINFO sSI;
  1222. int iRet;
  1223. BOOL fDBOpened = FALSE;
  1224. if (hShadowDB == INVALID_HANDLE_VALUE)
  1225. {
  1226. hShadowDB = OpenShadowDatabaseIO();
  1227. if (hShadowDB == INVALID_HANDLE_VALUE)
  1228. {
  1229. return 0;
  1230. }
  1231. fDBOpened = TRUE;
  1232. }
  1233. memset(&sSI, 0, sizeof(SHADOWINFO));
  1234. sSI.uSubOperation = SHADOW_GET_SECURITY_INFO;
  1235. sSI.lpBuffer = lpSecurityInfo;
  1236. sSI.cbBufferSize = *lpdwBufferSize;
  1237. sSI.hDir = hDir;
  1238. sSI.hShadow = hShadow;
  1239. iRet = DeviceIoControl(hShadowDB , IOCTL_DO_SHADOW_MAINTENANCE
  1240. ,(LPVOID)(&sSI), 0
  1241. , NULL, 0
  1242. , &DummyBytesReturned, NULL);
  1243. if (fDBOpened)
  1244. {
  1245. CloseShadowDatabaseIO(hShadowDB);
  1246. }
  1247. if (iRet)
  1248. {
  1249. *lpdwBufferSize = sSI.cbBufferSize;
  1250. }
  1251. else
  1252. {
  1253. SetLastError(sSI.dwError);
  1254. }
  1255. return (iRet);
  1256. }
  1257. BOOL
  1258. SetExclusionList(
  1259. HANDLE hShadowDB,
  1260. LPWSTR lpwList,
  1261. DWORD cbSize
  1262. )
  1263. {
  1264. SHADOWINFO sSI;
  1265. int iRet;
  1266. BOOL fDBOpened = FALSE;
  1267. if (hShadowDB == INVALID_HANDLE_VALUE)
  1268. {
  1269. hShadowDB = OpenShadowDatabaseIO();
  1270. if (hShadowDB == INVALID_HANDLE_VALUE)
  1271. {
  1272. return 0;
  1273. }
  1274. fDBOpened = TRUE;
  1275. }
  1276. memset(&sSI, 0, sizeof(SHADOWINFO));
  1277. sSI.uSubOperation = SHADOW_SET_EXCLUSION_LIST;
  1278. sSI.lpBuffer = lpwList;
  1279. sSI.cbBufferSize = cbSize;
  1280. iRet = DeviceIoControl(hShadowDB , IOCTL_DO_SHADOW_MAINTENANCE
  1281. ,(LPVOID)(&sSI), 0
  1282. , NULL, 0
  1283. , &DummyBytesReturned, NULL);
  1284. if (fDBOpened)
  1285. {
  1286. CloseShadowDatabaseIO(hShadowDB);
  1287. }
  1288. if (!iRet)
  1289. {
  1290. SetLastError(sSI.dwError);
  1291. }
  1292. return (iRet);
  1293. }
  1294. BOOL
  1295. SetBandwidthConservationList(
  1296. HANDLE hShadowDB,
  1297. LPWSTR lpwList,
  1298. DWORD cbSize
  1299. )
  1300. {
  1301. SHADOWINFO sSI;
  1302. int iRet;
  1303. BOOL fDBOpened = FALSE;
  1304. if (hShadowDB == INVALID_HANDLE_VALUE)
  1305. {
  1306. hShadowDB = OpenShadowDatabaseIO();
  1307. if (hShadowDB == INVALID_HANDLE_VALUE)
  1308. {
  1309. return 0;
  1310. }
  1311. fDBOpened = TRUE;
  1312. }
  1313. memset(&sSI, 0, sizeof(SHADOWINFO));
  1314. sSI.uSubOperation = SHADOW_SET_BW_CONSERVE_LIST;
  1315. sSI.lpBuffer = lpwList;
  1316. sSI.cbBufferSize = cbSize;
  1317. iRet = DeviceIoControl(hShadowDB , IOCTL_DO_SHADOW_MAINTENANCE
  1318. ,(LPVOID)(&sSI), 0
  1319. , NULL, 0
  1320. , &DummyBytesReturned, NULL);
  1321. if (fDBOpened)
  1322. {
  1323. CloseShadowDatabaseIO(hShadowDB);
  1324. }
  1325. if (!iRet)
  1326. {
  1327. SetLastError(sSI.dwError);
  1328. }
  1329. return (iRet);
  1330. }
  1331. BOOL
  1332. TransitionShareInternal(
  1333. HANDLE hShadowDB,
  1334. HSHARE hShare,
  1335. BOOL fTrue,
  1336. BOOL fOnlineToOffline
  1337. )
  1338. {
  1339. SHADOWINFO sSI;
  1340. int iRet;
  1341. BOOL fDBOpened = FALSE;
  1342. if (hShadowDB == INVALID_HANDLE_VALUE)
  1343. {
  1344. hShadowDB = OpenShadowDatabaseIO();
  1345. if (hShadowDB == INVALID_HANDLE_VALUE)
  1346. {
  1347. return 0;
  1348. }
  1349. fDBOpened = TRUE;
  1350. }
  1351. memset(&sSI, 0, sizeof(SHADOWINFO));
  1352. sSI.hShare = hShare;
  1353. sSI.uStatus = fTrue;
  1354. iRet = DeviceIoControl(
  1355. hShadowDB,
  1356. (fOnlineToOffline)?IOCTL_TRANSITION_SERVER_TO_OFFLINE:IOCTL_TRANSITION_SERVER_TO_ONLINE
  1357. ,(LPVOID)(&sSI), 0
  1358. , NULL, 0
  1359. , &DummyBytesReturned, NULL);
  1360. if (fDBOpened)
  1361. {
  1362. CloseShadowDatabaseIO(hShadowDB);
  1363. }
  1364. return (iRet);
  1365. }
  1366. BOOL
  1367. TransitionShareToOffline(
  1368. HANDLE hShadowDB,
  1369. HSHARE hShare,
  1370. BOOL fTrue
  1371. )
  1372. {
  1373. return TransitionShareInternal(
  1374. hShadowDB,
  1375. hShare, // which share
  1376. fTrue, // transtion or not
  1377. TRUE); // online to offline
  1378. }
  1379. BOOL
  1380. TransitionShareToOnline(
  1381. HANDLE hShadowDB,
  1382. HSHARE hShare
  1383. )
  1384. {
  1385. return TransitionShareInternal(
  1386. hShadowDB,
  1387. hShare, // which share
  1388. TRUE, // really a don't care
  1389. FALSE); // offlinetoonline
  1390. }
  1391. BOOL
  1392. IsServerOfflineW(
  1393. HANDLE hShadowDB,
  1394. LPCWSTR lptzShare,
  1395. BOOL *lpfIsOffline
  1396. )
  1397. {
  1398. SHADOWINFO sSI;
  1399. int iRet;
  1400. BOOL fDBOpened = FALSE;
  1401. if (hShadowDB == INVALID_HANDLE_VALUE)
  1402. {
  1403. hShadowDB = OpenShadowDatabaseIO();
  1404. if (hShadowDB == INVALID_HANDLE_VALUE)
  1405. {
  1406. return 0;
  1407. }
  1408. fDBOpened = TRUE;
  1409. }
  1410. memset(&sSI, 0, sizeof(SHADOWINFO));
  1411. if (lptzShare)
  1412. {
  1413. sSI.lpBuffer = (LPVOID)(lptzShare);
  1414. sSI.cbBufferSize = sizeof(WORD) * (lstrlenW(lptzShare)+1);
  1415. }
  1416. iRet = DeviceIoControl(
  1417. hShadowDB,
  1418. IOCTL_IS_SERVER_OFFLINE
  1419. ,(LPVOID)(&sSI), 0
  1420. , NULL, 0
  1421. , &DummyBytesReturned, NULL);
  1422. if (fDBOpened)
  1423. {
  1424. CloseShadowDatabaseIO(hShadowDB);
  1425. }
  1426. if (iRet)
  1427. {
  1428. *lpfIsOffline = sSI.uStatus;
  1429. }
  1430. return (iRet);
  1431. }
  1432. BOOL
  1433. IsServerOfflineA(
  1434. HANDLE hShadowDB,
  1435. LPCSTR lptzShare,
  1436. BOOL *lpfIsOffline
  1437. )
  1438. {
  1439. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  1440. return FALSE;
  1441. }
  1442. int GetShadowDatabaseLocationA(
  1443. HANDLE hShadowDB,
  1444. WIN32_FIND_DATAA *lpFind32A
  1445. )
  1446. {
  1447. int iRet = 0;
  1448. WIN32_FIND_DATAW sFind32W;
  1449. if (GetShadowDatabaseLocationW(hShadowDB, &sFind32W))
  1450. {
  1451. memset(lpFind32A, 0, sizeof(*lpFind32A));
  1452. iRet = WideCharToMultiByte(CP_ACP, 0, sFind32W.cFileName, wcslen(sFind32W.cFileName), lpFind32A->cFileName, sizeof(lpFind32A->cFileName), NULL, NULL);
  1453. }
  1454. return (iRet);
  1455. }
  1456. BOOL
  1457. GetNameOfServerGoingOfflineW(
  1458. HANDLE hShadowDB,
  1459. LPBYTE lpBuffer,
  1460. LPDWORD lpdwSize
  1461. )
  1462. {
  1463. SHADOWINFO sSI;
  1464. int iRet;
  1465. BOOL fDBOpened = FALSE;
  1466. if (hShadowDB == INVALID_HANDLE_VALUE)
  1467. {
  1468. hShadowDB = OpenShadowDatabaseIO();
  1469. if (hShadowDB == INVALID_HANDLE_VALUE)
  1470. {
  1471. return 0;
  1472. }
  1473. fDBOpened = TRUE;
  1474. }
  1475. memset(&sSI, 0, sizeof(SHADOWINFO));
  1476. sSI.lpBuffer = (LPVOID)(lpBuffer);
  1477. sSI.cbBufferSize = *lpdwSize;
  1478. iRet = DeviceIoControl(
  1479. hShadowDB,
  1480. IOCTL_NAME_OF_SERVER_GOING_OFFLINE
  1481. ,(LPVOID)(&sSI), 0
  1482. , NULL, 0
  1483. , &DummyBytesReturned, NULL);
  1484. if (fDBOpened)
  1485. {
  1486. CloseShadowDatabaseIO(hShadowDB);
  1487. }
  1488. if (!iRet)
  1489. {
  1490. *lpdwSize = sSI.cbBufferSize;
  1491. }
  1492. return (iRet);
  1493. }
  1494. BOOL
  1495. RenameShadow(
  1496. HANDLE hShadowDB,
  1497. HSHADOW hDirFrom,
  1498. HSHADOW hShadowFrom,
  1499. HSHADOW hDirTo,
  1500. LPWIN32_FIND_DATAW lpFind32,
  1501. BOOL fReplaceFile,
  1502. HSHADOW *lphShadowTo
  1503. )
  1504. {
  1505. SHADOWINFO sSI;
  1506. int iRet;
  1507. BOOL fDBOpened = FALSE;
  1508. if (hShadowDB == INVALID_HANDLE_VALUE)
  1509. {
  1510. hShadowDB = OpenShadowDatabaseIO();
  1511. if (hShadowDB == INVALID_HANDLE_VALUE)
  1512. {
  1513. return 0;
  1514. }
  1515. fDBOpened = TRUE;
  1516. }
  1517. memset(&sSI, 0, sizeof(SHADOWINFO));
  1518. sSI.hDir = hDirFrom;
  1519. sSI.hShadow = hShadowFrom;
  1520. sSI.hDirTo = hDirTo;
  1521. sSI.uSubOperation = SHADOW_RENAME;
  1522. sSI.uStatus = fReplaceFile;
  1523. sSI.lpFind32 = lpFind32;
  1524. iRet = DeviceIoControl(
  1525. hShadowDB
  1526. ,IOCTL_DO_SHADOW_MAINTENANCE
  1527. ,(LPVOID)(&sSI), 0
  1528. , NULL, 0
  1529. , &DummyBytesReturned, NULL);
  1530. if (fDBOpened)
  1531. {
  1532. CloseShadowDatabaseIO(hShadowDB);
  1533. }
  1534. if (!iRet)
  1535. {
  1536. SetLastError(sSI.dwError);
  1537. }
  1538. else
  1539. {
  1540. if (lphShadowTo)
  1541. {
  1542. *lphShadowTo = sSI.hShadow;
  1543. }
  1544. }
  1545. return (iRet);
  1546. }
  1547. BOOL
  1548. GetSparseStaleDetectionCounter(
  1549. HANDLE hShadowDB,
  1550. LPDWORD lpdwCounter
  1551. )
  1552. {
  1553. SHADOWINFO sSI;
  1554. int iRet;
  1555. BOOL fDBOpened = FALSE;
  1556. if (hShadowDB == INVALID_HANDLE_VALUE)
  1557. {
  1558. hShadowDB = OpenShadowDatabaseIO();
  1559. if (hShadowDB == INVALID_HANDLE_VALUE)
  1560. {
  1561. return 0;
  1562. }
  1563. fDBOpened = TRUE;
  1564. }
  1565. memset(&sSI, 0, sizeof(SHADOWINFO));
  1566. sSI.uSubOperation = SHADOW_SPARSE_STALE_DETECTION_COUNTER;
  1567. iRet = DeviceIoControl(
  1568. hShadowDB
  1569. ,IOCTL_DO_SHADOW_MAINTENANCE
  1570. ,(LPVOID)(&sSI), 0
  1571. , NULL, 0
  1572. , &DummyBytesReturned, NULL);
  1573. if (fDBOpened)
  1574. {
  1575. CloseShadowDatabaseIO(hShadowDB);
  1576. }
  1577. if (!iRet)
  1578. {
  1579. SetLastError(sSI.dwError);
  1580. }
  1581. else
  1582. {
  1583. *lpdwCounter = sSI.dwError;
  1584. }
  1585. return (iRet);
  1586. }
  1587. BOOL
  1588. GetManualFileDetectionCounter(
  1589. HANDLE hShadowDB,
  1590. LPDWORD lpdwCounter
  1591. )
  1592. {
  1593. SHADOWINFO sSI;
  1594. int iRet;
  1595. BOOL fDBOpened = FALSE;
  1596. if (hShadowDB == INVALID_HANDLE_VALUE)
  1597. {
  1598. hShadowDB = OpenShadowDatabaseIO();
  1599. if (hShadowDB == INVALID_HANDLE_VALUE)
  1600. {
  1601. return 0;
  1602. }
  1603. fDBOpened = TRUE;
  1604. }
  1605. memset(&sSI, 0, sizeof(SHADOWINFO));
  1606. sSI.uSubOperation = SHADOW_MANUAL_FILE_DETECTION_COUNTER;
  1607. iRet = DeviceIoControl(
  1608. hShadowDB
  1609. ,IOCTL_DO_SHADOW_MAINTENANCE
  1610. ,(LPVOID)(&sSI), 0
  1611. , NULL, 0
  1612. , &DummyBytesReturned, NULL);
  1613. if (fDBOpened)
  1614. {
  1615. CloseShadowDatabaseIO(hShadowDB);
  1616. }
  1617. if (!iRet)
  1618. {
  1619. SetLastError(sSI.dwError);
  1620. }
  1621. else
  1622. {
  1623. *lpdwCounter = sSI.dwError;
  1624. }
  1625. return (iRet);
  1626. }
  1627. int EnableShadowingForUser(
  1628. HANDLE hShadowDB,
  1629. LPCSTR lpszDatabaseLocation, // location of the shadowing directory
  1630. LPCSTR lpszUserName, // name of the user
  1631. DWORD dwDefDataSizeHigh, // cache size if being created for the first time
  1632. DWORD dwDefDataSizeLow,
  1633. DWORD dwClusterSize,
  1634. BOOL fFormat
  1635. )
  1636. {
  1637. SHADOWINFO sSI;
  1638. WIN32_FIND_DATAA sFind32;
  1639. int iRet;
  1640. BOOL fDBOpened = FALSE;
  1641. if (hShadowDB == INVALID_HANDLE_VALUE)
  1642. {
  1643. hShadowDB = OpenShadowDatabaseIO();
  1644. if (hShadowDB == INVALID_HANDLE_VALUE)
  1645. {
  1646. return 0;
  1647. }
  1648. fDBOpened = TRUE;
  1649. }
  1650. memset(&sSI, 0, sizeof(SHADOWINFO));
  1651. memset(&sFind32, 0, sizeof(WIN32_FIND_DATAA));
  1652. sFind32.nFileSizeHigh = dwDefDataSizeHigh;
  1653. sFind32.nFileSizeLow = dwDefDataSizeLow;
  1654. sFind32.dwReserved1 = dwClusterSize;
  1655. if (lpszDatabaseLocation)
  1656. {
  1657. if (strlen(lpszDatabaseLocation) > sizeof(sFind32.cFileName))
  1658. {
  1659. SetLastError(ERROR_INVALID_PARAMETER);
  1660. return 0;
  1661. }
  1662. strcpy(sFind32.cFileName, lpszDatabaseLocation);
  1663. }
  1664. if (lpszUserName)
  1665. {
  1666. strncpy(sFind32.cAlternateFileName, lpszUserName, MAX_USERNAME);
  1667. }
  1668. sSI.lpFind32 = (WIN32_FIND_DATAW *)&sFind32;
  1669. sSI.uSubOperation = SHADOW_ENABLE_CSC_FOR_USER;
  1670. sSI.ulRefPri = fFormat;
  1671. iRet = DeviceIoControl(hShadowDB
  1672. ,IOCTL_DO_SHADOW_MAINTENANCE,(LPVOID)(&sSI), 0
  1673. , NULL, 0
  1674. , &DummyBytesReturned, NULL);
  1675. if (fDBOpened)
  1676. {
  1677. CloseShadowDatabaseIO(hShadowDB);
  1678. }
  1679. if (!iRet)
  1680. {
  1681. SetLastError(sSI.dwError);
  1682. }
  1683. return (iRet);
  1684. }
  1685. int DisableShadowingForUser(
  1686. HANDLE hShadowDB
  1687. )
  1688. {
  1689. SHADOWINFO sSI;
  1690. WIN32_FIND_DATAA sFind32;
  1691. int iRet;
  1692. BOOL fDBOpened = FALSE;
  1693. if (hShadowDB == INVALID_HANDLE_VALUE)
  1694. {
  1695. hShadowDB = OpenShadowDatabaseIO();
  1696. if (hShadowDB == INVALID_HANDLE_VALUE)
  1697. {
  1698. return 0;
  1699. }
  1700. fDBOpened = TRUE;
  1701. }
  1702. memset(&sSI, 0, sizeof(SHADOWINFO));
  1703. sSI.uSubOperation = SHADOW_DISABLE_CSC_FOR_USER;
  1704. iRet = DeviceIoControl(hShadowDB
  1705. ,IOCTL_DO_SHADOW_MAINTENANCE,(LPVOID)(&sSI), 0
  1706. , NULL, 0
  1707. , &DummyBytesReturned, NULL);
  1708. if (fDBOpened)
  1709. {
  1710. CloseShadowDatabaseIO(hShadowDB);
  1711. }
  1712. if (!iRet)
  1713. {
  1714. SetLastError(sSI.dwError);
  1715. }
  1716. return (iRet);
  1717. }
  1718. LPCOPYPARAMSW LpAllocCopyParamsW(
  1719. VOID
  1720. )
  1721. {
  1722. LPCOPYPARAMSW lpCPW = NULL;
  1723. DWORD dwMinSize = (sizeof(COPYPARAMSW) + MAX_PATH+MAX_PATH+MAX_SERVER_SHARE_NAME_FOR_CSC)*sizeof(unsigned short);
  1724. lpCPW = (LPCOPYPARAMSW)LocalAlloc(LPTR, dwMinSize);
  1725. if (lpCPW)
  1726. {
  1727. lpCPW->lpLocalPath = (LPWSTR)((LPBYTE)lpCPW+sizeof(COPYPARAMSW));
  1728. lpCPW->lpRemotePath = (lpCPW->lpLocalPath + MAX_PATH);
  1729. lpCPW->lpSharePath = (lpCPW->lpRemotePath + MAX_PATH);
  1730. }
  1731. return (lpCPW);
  1732. }
  1733. VOID
  1734. FreeCopyParamsW(
  1735. IN LPCOPYPARAMSW lpCPW
  1736. )
  1737. {
  1738. LocalFree(lpCPW);
  1739. }
  1740. LPCOPYPARAMSA LpAllocCopyParamsA(
  1741. VOID
  1742. )
  1743. {
  1744. LPCOPYPARAMSA lpCPA = NULL;
  1745. DWORD dwMinSize = (sizeof(COPYPARAMSA) + MAX_PATH+MAX_PATH+MAX_SERVER_SHARE_NAME_FOR_CSC);
  1746. lpCPA = (LPCOPYPARAMSA)LocalAlloc(LPTR, dwMinSize);
  1747. if (lpCPA)
  1748. {
  1749. lpCPA->lpLocalPath = (LPSTR)((LPBYTE)lpCPA+sizeof(COPYPARAMSA));
  1750. lpCPA->lpRemotePath = (lpCPA->lpLocalPath + MAX_PATH);
  1751. lpCPA->lpSharePath = (lpCPA->lpRemotePath + MAX_PATH);
  1752. }
  1753. return (lpCPA);
  1754. }
  1755. VOID
  1756. FreeCopyParamsA(
  1757. IN LPCOPYPARAMSA lpCPA
  1758. )
  1759. {
  1760. LocalFree(lpCPA);
  1761. }
  1762. BOOL
  1763. ConvertCopyParamsFromUnicodeToAnsi(
  1764. LPCOPYPARAMSW lpCPUni,
  1765. LPCOPYPARAMSA lpCP
  1766. )
  1767. {
  1768. memset(lpCP->lpLocalPath, 0, MAX_PATH);
  1769. memset(lpCP->lpRemotePath, 0, MAX_PATH);
  1770. memset(lpCP->lpSharePath, 0, MAX_SERVER_SHARE_NAME_FOR_CSC);
  1771. WideCharToMultiByte(CP_ACP, 0, lpCPUni->lpLocalPath, wcslen(lpCPUni->lpLocalPath), lpCP->lpLocalPath, MAX_PATH, NULL, NULL);
  1772. WideCharToMultiByte(CP_ACP, 0, lpCPUni->lpRemotePath, wcslen(lpCPUni->lpRemotePath), lpCP->lpRemotePath, MAX_PATH, NULL, NULL);
  1773. WideCharToMultiByte(CP_ACP, 0, lpCPUni->lpSharePath, wcslen(lpCPUni->lpSharePath), lpCP->lpSharePath, MAX_SERVER_SHARE_NAME_FOR_CSC, NULL, NULL);
  1774. return TRUE;
  1775. }
  1776. BOOL
  1777. Find32WToFind32A(
  1778. WIN32_FIND_DATAW *lpFind32W,
  1779. WIN32_FIND_DATAA *lpFind32A
  1780. )
  1781. {
  1782. memset(lpFind32A, 0, sizeof(WIN32_FIND_DATAA));
  1783. memcpy(lpFind32A, lpFind32W, sizeof(WIN32_FIND_DATAA)-sizeof(lpFind32A->cFileName)-sizeof(lpFind32A->cAlternateFileName));
  1784. if ( WideCharToMultiByte(CP_ACP, 0, lpFind32W->cFileName, wcslen(lpFind32W->cFileName), lpFind32A->cFileName, sizeof(lpFind32A->cFileName), NULL, NULL)
  1785. && WideCharToMultiByte(CP_OEMCP, 0, lpFind32W->cAlternateFileName, wcslen(lpFind32W->cAlternateFileName), lpFind32A->cAlternateFileName, sizeof(lpFind32A->cAlternateFileName), NULL, NULL))
  1786. {
  1787. return TRUE;
  1788. }
  1789. return FALSE;
  1790. }
  1791. BOOL
  1792. Find32AToFind32W(
  1793. WIN32_FIND_DATAA *lpFind32A,
  1794. WIN32_FIND_DATAW *lpFind32W
  1795. )
  1796. {
  1797. memset(lpFind32W, 0, sizeof(WIN32_FIND_DATAW));
  1798. memcpy(lpFind32W, lpFind32A, sizeof(WIN32_FIND_DATAW)-sizeof(lpFind32W->cFileName)-sizeof(lpFind32W->cAlternateFileName));
  1799. if ( MultiByteToWideChar(CP_ACP, 0, lpFind32A->cFileName, strlen(lpFind32A->cFileName), lpFind32W->cFileName, sizeof(lpFind32W->cFileName)/sizeof(WCHAR))
  1800. && MultiByteToWideChar(CP_OEMCP, 0, lpFind32A->cAlternateFileName, strlen(lpFind32A->cAlternateFileName), lpFind32W->cAlternateFileName, sizeof(lpFind32W->cAlternateFileName)/sizeof(WCHAR)))
  1801. {
  1802. return TRUE;
  1803. }
  1804. return FALSE;
  1805. }
  1806. BOOL
  1807. ShareInfoWToShareInfoA(
  1808. LPSHAREINFOW lpShareInfoW,
  1809. LPSHAREINFOA lpShareInfoA
  1810. )
  1811. {
  1812. memset(lpShareInfoA, 0, sizeof(*lpShareInfoA));
  1813. lpShareInfoA->hShare = lpShareInfoW->hShare;
  1814. lpShareInfoA->usCaps = lpShareInfoW->usCaps;
  1815. lpShareInfoA->usState = lpShareInfoW->usState;
  1816. WideCharToMultiByte( CP_ACP, 0,
  1817. lpShareInfoW->rgSharePath,
  1818. wcslen(lpShareInfoW->rgSharePath),
  1819. lpShareInfoA->rgSharePath,
  1820. sizeof(lpShareInfoA->rgSharePath), NULL, NULL);
  1821. WideCharToMultiByte( CP_ACP, 0,
  1822. lpShareInfoW->rgFileSystem,
  1823. wcslen(lpShareInfoW->rgFileSystem),
  1824. lpShareInfoA->rgFileSystem,
  1825. sizeof(lpShareInfoA->rgFileSystem), NULL, NULL);
  1826. return TRUE;
  1827. }
  1828. BOOL
  1829. RecreateShadow(
  1830. HANDLE hShadowDB,
  1831. HSHADOW hDir,
  1832. HSHADOW hShadow,
  1833. ULONG ulAttrib
  1834. )
  1835. {
  1836. SHADOWINFO sSI;
  1837. int iRet;
  1838. BOOL fDBOpened = FALSE;
  1839. if (hShadowDB == INVALID_HANDLE_VALUE)
  1840. {
  1841. hShadowDB = OpenShadowDatabaseIO();
  1842. if (hShadowDB == INVALID_HANDLE_VALUE)
  1843. {
  1844. return 0;
  1845. }
  1846. fDBOpened = TRUE;
  1847. }
  1848. memset(&sSI, 0, sizeof(SHADOWINFO));
  1849. sSI.hDir = hDir;
  1850. sSI.hShadow = hShadow;
  1851. sSI.uStatus = ulAttrib;
  1852. sSI.uSubOperation = SHADOW_RECREATE;
  1853. iRet = DeviceIoControl(
  1854. hShadowDB
  1855. ,IOCTL_DO_SHADOW_MAINTENANCE
  1856. ,(LPVOID)(&sSI), 0
  1857. , NULL, 0
  1858. , &DummyBytesReturned, NULL);
  1859. if (fDBOpened)
  1860. {
  1861. CloseShadowDatabaseIO(hShadowDB);
  1862. }
  1863. if (!iRet)
  1864. {
  1865. SetLastError(sSI.dwError);
  1866. }
  1867. return (iRet);
  1868. }
  1869. BOOL
  1870. SetDatabaseStatus(
  1871. HANDLE hShadowDB,
  1872. ULONG ulStatus,
  1873. ULONG uMask
  1874. )
  1875. {
  1876. SHADOWINFO sSI;
  1877. int iRet;
  1878. BOOL fDBOpened = FALSE;
  1879. if (hShadowDB == INVALID_HANDLE_VALUE)
  1880. {
  1881. hShadowDB = OpenShadowDatabaseIO();
  1882. if (hShadowDB == INVALID_HANDLE_VALUE)
  1883. {
  1884. return 0;
  1885. }
  1886. fDBOpened = TRUE;
  1887. }
  1888. memset(&sSI, 0, sizeof(SHADOWINFO));
  1889. sSI.uStatus = ulStatus;
  1890. sSI.uSubOperation = SHADOW_SET_DATABASE_STATUS;
  1891. sSI.ulHintFlags = uMask;
  1892. iRet = DeviceIoControl(
  1893. hShadowDB
  1894. ,IOCTL_DO_SHADOW_MAINTENANCE
  1895. ,(LPVOID)(&sSI), 0
  1896. , NULL, 0
  1897. , &DummyBytesReturned, NULL);
  1898. if (fDBOpened)
  1899. {
  1900. CloseShadowDatabaseIO(hShadowDB);
  1901. }
  1902. if (!iRet)
  1903. {
  1904. SetLastError(sSI.dwError);
  1905. }
  1906. return (iRet);
  1907. }