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.

4439 lines
105 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. Ioctl.c
  5. Abstract:
  6. This file implements the ioctl interface to Client Side Caching facility. The interface
  7. is used by a) the agent b) the CSC apis and c) remote boot. The interface allows the
  8. callers to initialize/reinitialize the csc database, enumerate the hierarchy at any level,
  9. get the status of any file/directory in the hierarchy, pin/unpin files directories etc.
  10. There are a few ioctls which are used only by the agent. These include, enumerating the
  11. priority q, doing space scavenging, initiating and terminating reintegration on a share etc.
  12. Author:
  13. Shishir Pardikar [Shishirp] 01-jan-1995
  14. Revision History:
  15. Joe Linn [JoeLinn] 23-jan-97 Ported for use on NT
  16. --*/
  17. #include "precomp.h"
  18. #pragma hdrstop
  19. #pragma code_seg("PAGE")
  20. #ifndef CSC_RECORDMANAGER_WINNT
  21. #define WIN32_APIS
  22. #include "cshadow.h"
  23. #include "record.h"
  24. #endif //ifndef CSC_RECORDMANAGER_WINNT
  25. #include <stdlib.h>
  26. #include <ctype.h>
  27. #include <string.h>
  28. // #include "error.h"
  29. #include "shell.h"
  30. #include "vxdwraps.h"
  31. #include "clregs.h"
  32. #define LM_3
  33. #include "netcons.h"
  34. #include "use.h"
  35. #include "neterr.h"
  36. #pragma intrinsic (memcmp, memcpy, memset, strcat, strcmp, strcpy, strlen)
  37. #ifdef CSC_RECORDMANAGER_WINNT
  38. #define CSC_ENABLED (fShadow && MRxSmbIsCscEnabled)
  39. #define OK_TO_ENABLE_CSC (MRxSmbIsCscEnabled)
  40. #else
  41. #define CSC_ENABLED (fShadow)
  42. #define OK_TO_ENABLE_CSC (TRUE)
  43. #endif
  44. //
  45. // From cscapi.h
  46. //
  47. #define FLAG_CSC_SHARE_STATUS_MANUAL_REINT 0x0000
  48. #define FLAG_CSC_SHARE_STATUS_AUTO_REINT 0x0040
  49. #define FLAG_CSC_SHARE_STATUS_VDO 0x0080
  50. #define FLAG_CSC_SHARE_STATUS_NO_CACHING 0x00c0
  51. #define FLAG_CSC_SHARE_STATUS_CACHING_MASK 0x00c0
  52. #define COPY_STRUCTFILETIME_TO_LARGEINTEGER(dest,src) {\
  53. (dest).LowPart = (src).dwLowDateTime; \
  54. (dest).HighPart = (src).dwHighDateTime; \
  55. }
  56. //
  57. // prototypes
  58. //
  59. int
  60. HintobjMMProc(
  61. LPFIND32,
  62. HSHADOW,
  63. HSHADOW,
  64. ULONG,
  65. LPOTHERINFO,
  66. LPFINDSHADOW);
  67. LPFINDSHADOW
  68. LpCreateFindShadow(
  69. HSHADOW,
  70. ULONG,
  71. ULONG,
  72. USHORT *,
  73. METAMATCHPROC);
  74. int
  75. DeleteCallbackForFind(
  76. HSHADOW hDir,
  77. HSHADOW hShadow
  78. );
  79. int
  80. IoctlRenameShadow(
  81. LPSHADOWINFO lpSI
  82. );
  83. int IoctlEnableCSCForUser(
  84. LPSHADOWINFO lpSI
  85. );
  86. int
  87. IoctlDisableCSCForUser(
  88. LPSHADOWINFO lpSI
  89. );
  90. VOID
  91. MRxSmbCscGenerate83NameAsNeeded(
  92. IN HSHADOW hDir,
  93. PWCHAR FileName,
  94. PWCHAR SFN
  95. );
  96. VOID
  97. MRxSmbCscFlushFdb(
  98. IN PFDB Fdb
  99. );
  100. #ifdef MAYBE
  101. int RecalcIHPri(HSHADOW, HSHADOW, LPFIND32, LPOTHERINFO);
  102. #endif //MAYBE
  103. BOOL RegisterTempAgent(VOID);
  104. BOOL UnregisterTempAgent(VOID);
  105. int PUBLIC MakeSpace(long, long, BOOL);
  106. int PUBLIC ReduceRefPri(VOID);
  107. int
  108. IoctlAddDeleteHintFromInode(
  109. LPSHADOWINFO lpSI,
  110. BOOL fAdd
  111. );
  112. LONG
  113. PurgeUnpinnedFiles(
  114. ULONG Timeout,
  115. PULONG pnFiles,
  116. PULONG pnYoungFiles);
  117. BOOL HaveSpace(
  118. long nFileSizeHigh,
  119. long nFileSizeLow
  120. );
  121. int SetResourceFlags(
  122. HSHARE hShare,
  123. ULONG uStatus,
  124. ULONG uOp
  125. );
  126. int DestroyFindShadow(
  127. LPFINDSHADOW lpFSH
  128. );
  129. int
  130. CloseDatabase(
  131. VOID
  132. );
  133. int
  134. IoctlCopyShadow(
  135. LPSHADOWINFO lpSI
  136. );
  137. int IoctlGetSecurityInfo(
  138. LPSHADOWINFO lpShadowInfo
  139. );
  140. int
  141. IoctlTransitionShareToOffline(
  142. LPSHADOWINFO lpSI
  143. );
  144. IoctlChangeHandleCachingState(
  145. LPSHADOWINFO lpSI
  146. );
  147. BOOLEAN
  148. CscCheckForNullA(
  149. PUCHAR pBuf,
  150. ULONG Count);
  151. BOOLEAN
  152. CscCheckForNullW(
  153. PWCHAR pBuf,
  154. ULONG Count);
  155. int
  156. PUBLIC TraversePQToCheckDirtyBits(
  157. HSHARE hShare,
  158. DWORD *lpcntDirty
  159. );
  160. #ifndef CSC_RECORDMANAGER_WINNT
  161. int ReportCreateDelete( HSHADOW hShadow, BOOL fCreate);
  162. #else
  163. //BUGBUG.win9xonly this comes from hook.c on win95
  164. #define ReportCreateDelete(a,b) {NOTHING;}
  165. #endif //ifndef CSC_RECORDMANAGER_WINNT
  166. BOOL
  167. FailModificationsToShare(
  168. LPSHADOWINFO lpSI
  169. );
  170. extern ULONG hthreadReint;
  171. extern ULONG hwndReint;
  172. extern PFILEINFO pFileInfoAgent;
  173. extern HSHARE hShareReint; // Share that is currently being reintegrated
  174. extern BOOL vfBlockingReint;
  175. extern DWORD vdwActivityCount;
  176. extern int fShadow, fLog, fNoShadow, /*fShadowFind,*/ fSpeadOpt;
  177. extern WIN32_FIND_DATA vsFind32;
  178. extern int cMacPro;
  179. extern NETPRO rgNetPro[];
  180. extern VMM_SEMAPHORE semHook;
  181. extern GLOBALSTATUS sGS;
  182. extern ULONG proidShadow;
  183. extern ULONG heventReint;
  184. #if defined(REMOTE_BOOT)
  185. BOOLEAN fIsRemoteBootSystem=FALSE;
  186. #endif // defined(REMOTE_BOOT)
  187. // List of ongoing IOCTL finds
  188. LPFINDSHADOW vlpFindShadowList = NULL;
  189. // Count of # entries on vlpFindShadowList
  190. LONG vuFindShadowListCount = 0;
  191. int iPQEnumCount = 0;
  192. CSC_ENUMCOOKIE hPQEnumCookieForIoctls = NULL;
  193. AssertData;
  194. AssertError;
  195. #ifdef CSC_RECORDMANAGER_WINNT
  196. //BUGBUG.win9xonly this stuff comes from shadow.asm on win95......
  197. //this is a synchronization primitive used to unblock guys waiting on a server
  198. //not yet implemented
  199. #define _SignalID(a) {ASSERT(FALSE);}
  200. #define IFSMgr_UseAdd(a, b, c) (-1)
  201. #define IFSMgr_UseDel(a, b, c) (-1)
  202. #endif //ifdef CSC_RECORDMANAGER_WINNT
  203. int IoctlRegisterAgent(
  204. LPSHADOWINFO lpSI
  205. )
  206. /*++
  207. Routine Description:
  208. WIN9x specific This is the way, we tell the shadwo VxD that this thread is the
  209. agent thread and to bypass CSC whenever this thread comes down to make
  210. calls.
  211. Parameters:
  212. Return Value:
  213. Notes:
  214. --*/
  215. {
  216. if (hthreadReint)
  217. {
  218. KdPrint(("Agent Already registered Unregistering!!!!!\r\n"));
  219. #ifndef CSC_RECORDMANAGER_WINNT
  220. // should never happen on win9x
  221. Assert(FALSE);
  222. // cleanup the
  223. if (heventReint)
  224. {
  225. // close the event handle
  226. CloseVxDHandle(heventReint);
  227. }
  228. #endif
  229. }
  230. hthreadReint = GetCurThreadHandle();
  231. hwndReint = lpSI->hShare & 0xffff; // windows handle for messages
  232. heventReint = lpSI->hDir; // event handle for reporting interesting events
  233. #if defined(REMOTE_BOOT)
  234. // if CSC is ON even before the agent was registered, we must be on an RB machine.
  235. fIsRemoteBootSystem = fShadow;
  236. #endif // defined(REMOTE_BOOT)
  237. return 1;
  238. }
  239. int IoctlUnRegisterAgent(
  240. ULONG uHwnd
  241. )
  242. /*++
  243. Routine Description:
  244. WIN9x specific
  245. Parameters:
  246. Return Value:
  247. Notes:
  248. --*/
  249. {
  250. ULONG hthread;
  251. hthread = GetCurThreadHandle();
  252. if (hthreadReint != hthread)
  253. {
  254. KdPrint(("Shadow:Someother thread Unregitsering!!!!\r\n"));
  255. }
  256. hthreadReint = 0;
  257. hwndReint = 0;
  258. if (heventReint)
  259. {
  260. #ifndef CSC_RECORDMANAGER_WINNT
  261. // close the event handle
  262. CloseVxDHandle(heventReint);
  263. heventReint = 0;
  264. #endif
  265. }
  266. return 1;
  267. }
  268. int IoctlGetUNCPath(
  269. LPCOPYPARAMSW lpCopyParams
  270. )
  271. /*++
  272. Routine Description:
  273. Given an hDir and an hShadow, this routine returns the complete UNC path for it.
  274. It returns it in the COPYPARAMS structure which has three embedded pointers for
  275. a) \\server\share b) Remote path relative to the root of the share and c) Path in
  276. the local database.
  277. Parameters:
  278. Return Value:
  279. Notes:
  280. --*/
  281. {
  282. PFDB pFdb;
  283. HSHADOW hDir;
  284. HSHARE hShare;
  285. SHAREINFOW sSRI;
  286. int iRet = -1;
  287. DWORD dwSize;
  288. if (!CSC_ENABLED)
  289. {
  290. lpCopyParams->dwError = ERROR_SERVICE_NOT_ACTIVE;
  291. return -1;
  292. }
  293. EnterShadowCrit();
  294. hDir = 0; hShare = 0;
  295. if (lpCopyParams->lpRemotePath || lpCopyParams->lpSharePath)
  296. {
  297. if (GetAncestorsHSHADOW(lpCopyParams->hShadow, &hDir, &hShare) < SRET_OK)
  298. {
  299. goto bailout;
  300. }
  301. if (lpCopyParams->lpRemotePath)
  302. {
  303. if(PathFromHShadow(hDir, lpCopyParams->hShadow, lpCopyParams->lpRemotePath, MAX_PATH)<SRET_OK)
  304. {
  305. goto bailout;
  306. }
  307. }
  308. if (lpCopyParams->lpSharePath)
  309. {
  310. if (GetShareInfo(hShare, &sSRI, NULL) < SRET_OK)
  311. {
  312. goto bailout;
  313. }
  314. memcpy(lpCopyParams->lpSharePath, sSRI.rgSharePath, sizeof(sSRI.rgSharePath));
  315. }
  316. }
  317. dwSize = MAX_PATH * sizeof(USHORT);
  318. GetWideCharLocalNameHSHADOW(lpCopyParams->hShadow, lpCopyParams->lpLocalPath, &dwSize, (lpCopyParams->uOp==0));
  319. iRet = 1;
  320. bailout:
  321. IF_CSC_RECORDMANAGER_WINNT {
  322. if (iRet!=1) {
  323. #if 0
  324. DbgPrint("Failure on nonfailable routine.....\n");
  325. DbgPrint("----> hShadow %08lx\n",lpCopyParams->hShadow);
  326. DbgPrint("----> hDir hSrv %08lx %08lx\n",hDir,hShare);
  327. DbgPrint("----> SrvPath %08lx\n",lpCopyParams->lpSharePath);
  328. DbgPrint("----> RemotePath %08lx\n",lpCopyParams->lpRemotePath);
  329. DbgBreakPoint();
  330. #endif
  331. }
  332. }
  333. if (iRet < SRET_OK)
  334. {
  335. lpCopyParams->dwError = GetLastErrorLocal();
  336. }
  337. LeaveShadowCrit();
  338. return(iRet);
  339. }
  340. int IoctlBeginPQEnum(
  341. LPPQPARAMS lpPQPar
  342. )
  343. /*++
  344. Routine Description:
  345. Priority queue enumeration begins. Typically used by agent thread to do background
  346. filling
  347. Parameters:
  348. Return Value:
  349. Notes:
  350. --*/
  351. {
  352. int iRet = -1;
  353. if (!CSC_ENABLED)
  354. {
  355. lpPQPar->dwError = ERROR_SERVICE_NOT_ACTIVE;
  356. return -1;
  357. }
  358. EnterShadowCrit();
  359. #ifdef CSC_RECORDMANAGER_WINNT
  360. EventLogForOpenFailure = 1;
  361. #endif //ifdef CSC_RECORDMANAGER_WINNT
  362. if (hPQEnumCookieForIoctls==NULL)
  363. {
  364. hPQEnumCookieForIoctls = HBeginPQEnum();
  365. }
  366. if (hPQEnumCookieForIoctls != NULL)
  367. {
  368. iRet = 1;
  369. }
  370. else
  371. {
  372. lpPQPar->dwError = GetLastErrorLocal();
  373. }
  374. #ifdef CSC_RECORDMANAGER_WINNT
  375. EventLogForOpenFailure = 0;
  376. #endif //ifdef CSC_RECORDMANAGER_WINNT
  377. LeaveShadowCrit();
  378. return iRet;
  379. }
  380. int IoctlEndPQEnum(
  381. LPPQPARAMS lpPQPar
  382. )
  383. /*++
  384. Routine Description:
  385. End priority queue enumeration
  386. Parameters:
  387. Return Value:
  388. Notes:
  389. --*/
  390. {
  391. return 1;
  392. }
  393. int IoctlNextPriShadow(
  394. LPPQPARAMS lpPQPar
  395. )
  396. /*++
  397. Routine Description:
  398. Parameters:
  399. Return Value:
  400. Notes:
  401. --*/
  402. {
  403. PQPARAMS sPQP;
  404. int iRet=-1;
  405. EnterShadowCrit();
  406. if (hPQEnumCookieForIoctls==NULL) {
  407. lpPQPar->dwError = ERROR_INVALID_PARAMETER;
  408. goto bailout;
  409. }
  410. sPQP = *lpPQPar;
  411. sPQP.uEnumCookie = hPQEnumCookieForIoctls;
  412. iRet = NextPriSHADOW(&sPQP);
  413. if (iRet >= SRET_OK)
  414. {
  415. *lpPQPar = sPQP;
  416. if (!iRet)
  417. lpPQPar->hShadow = 0;
  418. iRet = 1;
  419. }
  420. else
  421. {
  422. lpPQPar->dwError = GetLastErrorLocal();
  423. iRet = -1;
  424. EndPQEnum(hPQEnumCookieForIoctls);
  425. hPQEnumCookieForIoctls = NULL;
  426. }
  427. lpPQPar->uEnumCookie = NULL;
  428. bailout:
  429. LeaveShadowCrit();
  430. return (iRet);
  431. }
  432. int IoctlPrevPriShadow(
  433. LPPQPARAMS lpPQPar
  434. )
  435. /*++
  436. Routine Description:
  437. Parameters:
  438. Return Value:
  439. Notes:
  440. --*/
  441. {
  442. PQPARAMS sPQP;
  443. int iRet=-1;
  444. EnterShadowCrit();
  445. if (hPQEnumCookieForIoctls==NULL) {
  446. lpPQPar->dwError = ERROR_INVALID_PARAMETER;
  447. goto bailout;
  448. }
  449. sPQP = *lpPQPar;
  450. sPQP.uEnumCookie = hPQEnumCookieForIoctls;
  451. iRet = PrevPriSHADOW(&sPQP);
  452. if (iRet >= SRET_OK)
  453. {
  454. *lpPQPar = sPQP;
  455. if (!iRet)
  456. lpPQPar->hShadow = 0;
  457. iRet = 1;
  458. }
  459. else
  460. {
  461. lpPQPar->dwError = GetLastErrorLocal();
  462. iRet = -1;
  463. EndPQEnum(hPQEnumCookieForIoctls);
  464. hPQEnumCookieForIoctls = NULL;
  465. }
  466. lpPQPar->uEnumCookie = NULL;
  467. bailout:
  468. LeaveShadowCrit();
  469. return (iRet);
  470. }
  471. int
  472. IoctlGetShadowInfoInternal(
  473. LPSHADOWINFO lpShadowInfo,
  474. LPFIND32 lpFind32,
  475. LPSECURITYINFO lpSecurityInfos,
  476. LPDWORD lpcbBufferSize
  477. )
  478. /*++
  479. Routine Description:
  480. Given an hDir and an hShadow, return all the possible info for the Inode
  481. Parameters:
  482. Return Value:
  483. Notes:
  484. --*/
  485. {
  486. ULONG uStatus;
  487. HSHADOW hDir, hShare;
  488. PFDB pFdb=NULL;
  489. PRESOURCE pResource=NULL;
  490. int iRet = -1;
  491. OTHERINFO sOI;
  492. DWORD dwSecurityBlobSize;
  493. ACCESS_RIGHTS rgsAccessRights[CSC_MAXIMUM_NUMBER_OF_CACHED_SID_INDEXES];
  494. DeclareFindFromShadowOnNtVars()
  495. if (!CSC_ENABLED)
  496. {
  497. lpShadowInfo->dwError = ERROR_SERVICE_NOT_ACTIVE;
  498. return -1;
  499. }
  500. EnterShadowCrit();
  501. UseGlobalFind32();
  502. if (!(hDir = lpShadowInfo->hDir))
  503. {
  504. if (GetAncestorsHSHADOW(lpShadowInfo->hShadow, &hDir, &hShare) < 0)
  505. goto bailout;
  506. lpShadowInfo->hDir = hDir;
  507. lpShadowInfo->hShare = hShare;
  508. }
  509. dwSecurityBlobSize = sizeof(rgsAccessRights);
  510. if(GetShadowInfoEx( hDir,
  511. lpShadowInfo->hShadow,
  512. &vsFind32,
  513. &uStatus,
  514. &sOI,
  515. rgsAccessRights,
  516. &dwSecurityBlobSize) < SRET_OK)
  517. goto bailout;
  518. // not a root
  519. if (hDir)
  520. {
  521. if (!(vsFind32.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  522. {
  523. // is a file
  524. uStatus |= SHADOW_IS_FILE;
  525. if(pFdb = PFindFdbFromHShadow(lpShadowInfo->hShadow))
  526. {
  527. uStatus |= (pFdb->usFlags | SHADOW_FILE_IS_OPEN);
  528. }
  529. }
  530. }
  531. else
  532. {
  533. pResource = PFindResourceFromRoot(lpShadowInfo->hShadow, 0xffff, 0);
  534. if (pResource)
  535. {
  536. IFNOT_CSC_RECORDMANAGER_WINNT
  537. {
  538. uStatus |= (
  539. (pResource->usLocalFlags|SHARE_CONNECTED)|
  540. ((pResource->pheadFdb)?SHARE_FILES_OPEN:0) |
  541. ((pResource->pheadFindInfo) ?SHARE_FINDS_IN_PROGRESS:0));
  542. lpShadowInfo->uOp = pResource->uDriveMap;
  543. }
  544. else
  545. {
  546. uStatus |= MRxSmbCscGetSavedResourceStatus();
  547. lpShadowInfo->uOp = MRxSmbCscGetSavedResourceDriveMap();
  548. }
  549. }
  550. // UI expects to know whether a server is offline
  551. // even when a share may not be offline. So we do the following drill anyways
  552. {
  553. #ifdef CSC_RECORDMANAGER_WINNT
  554. BOOL fShareOnline = FALSE;
  555. BOOL fPinnedOffline = FALSE;
  556. // Leave Crit sec coz MRxSmbCscServerStateFromCompleteUNCPath may acquire SmbCeResource
  557. LeaveShadowCrit();
  558. if (MRxSmbCscServerStateFromCompleteUNCPath(
  559. vsFind32.cFileName,
  560. &fShareOnline,
  561. &fPinnedOffline)==STATUS_SUCCESS) {
  562. if (!fShareOnline)
  563. uStatus |= SHARE_DISCONNECTED_OP;
  564. if (fPinnedOffline)
  565. uStatus |= SHARE_PINNED_OFFLINE;
  566. }
  567. EnterShadowCrit();
  568. #endif
  569. }
  570. }
  571. lpShadowInfo->uStatus = uStatus;
  572. CopyOtherInfoToShadowInfo(&sOI, lpShadowInfo);
  573. if (hShareReint && (lpShadowInfo->hShare == hShareReint))
  574. {
  575. lpShadowInfo->uStatus |= SHARE_MERGING;
  576. }
  577. if (lpFind32)
  578. {
  579. *(lpFind32) = vsFind32;
  580. }
  581. if (lpSecurityInfos)
  582. {
  583. Assert(lpcbBufferSize);
  584. iRet = GetSecurityInfosFromBlob(
  585. rgsAccessRights,
  586. dwSecurityBlobSize,
  587. lpSecurityInfos,
  588. lpcbBufferSize);
  589. Assert(iRet >= 0);
  590. }
  591. iRet = 1;
  592. bailout:
  593. if (iRet < 0)
  594. {
  595. lpShadowInfo->dwError = GetLastErrorLocal();
  596. }
  597. LeaveShadowCrit();
  598. return (iRet);
  599. }
  600. int IoctlGetSecurityInfo(
  601. LPSHADOWINFO lpShadowInfo
  602. )
  603. /*++
  604. Routine Description:
  605. Parameters:
  606. Return Value:
  607. Notes:
  608. --*/
  609. {
  610. return IoctlGetShadowInfoInternal(lpShadowInfo, NULL, (LPSECURITYINFO)(lpShadowInfo->lpBuffer), &(lpShadowInfo->cbBufferSize));
  611. }
  612. int IoctlGetShadowInfo(
  613. LPSHADOWINFO lpShadowInfo
  614. )
  615. /*++
  616. Routine Description:
  617. Parameters:
  618. Return Value:
  619. Notes:
  620. --*/
  621. {
  622. return IoctlGetShadowInfoInternal(lpShadowInfo, lpShadowInfo->lpFind32, NULL, NULL);
  623. }
  624. int IoctlSetShadowInfo(
  625. LPSHADOWINFO lpShadowInfo
  626. )
  627. /*++
  628. Routine Description:
  629. Parameters:
  630. Return Value:
  631. Notes:
  632. --*/
  633. {
  634. HSHADOW hDir;
  635. PFDB pFdb;
  636. ULONG uOp = lpShadowInfo->uOp, uStatus;
  637. int iRet = -1;
  638. LPFIND32 lpFind32=NULL;
  639. if (!CSC_ENABLED)
  640. {
  641. lpShadowInfo->dwError = ERROR_SERVICE_NOT_ACTIVE;
  642. return -1;
  643. }
  644. EnterShadowCrit();
  645. UseGlobalFind32();
  646. if (FailModificationsToShare(lpShadowInfo))
  647. {
  648. goto bailout;
  649. }
  650. hDir = lpShadowInfo->hDir;
  651. pFdb = PFindFdbFromHShadow(lpShadowInfo->hShadow);
  652. if (!hDir)
  653. {
  654. if (GetAncestorsHSHADOW(lpShadowInfo->hShadow, &hDir, NULL) < 0)
  655. goto bailout;
  656. lpShadowInfo->hDir = hDir;
  657. }
  658. if (mTruncateDataCommand(uOp))
  659. {
  660. if (pFdb)
  661. {
  662. goto bailout;
  663. }
  664. if (GetShadowInfo(hDir, lpShadowInfo->hShadow, &vsFind32, &uStatus, NULL) < 0)
  665. {
  666. goto bailout;
  667. }
  668. if (uStatus & SHADOW_LOCALLY_CREATED)
  669. {
  670. goto bailout;
  671. }
  672. if (IsFile(vsFind32.dwFileAttributes))
  673. {
  674. if (TruncateDataHSHADOW(hDir, lpShadowInfo->hShadow) < SRET_OK)
  675. {
  676. goto bailout;
  677. }
  678. }
  679. // if we are truncating data, then the only thing possible
  680. // is to set all the flags to 0 and mark it as sparse
  681. lpShadowInfo->uStatus = SHADOW_SPARSE;
  682. uOp = lpShadowInfo->uOp = (SHADOW_FLAGS_ASSIGN | SHADOW_FLAGS_TRUNCATE_DATA);
  683. }
  684. if (lpShadowInfo->lpFind32)
  685. {
  686. lpFind32 = &vsFind32;
  687. *lpFind32 = *(lpShadowInfo->lpFind32);
  688. // Find32FromFind32A(lpFind32 = &vsFind32, (LPFIND32A)(lpShadowInfo->lpFind32), BCS_WANSI);
  689. #ifndef CSC_RECORDMANAGER_WINNT
  690. // ensure that on win9x we set only the FAT like attributes
  691. lpFind32->dwFileAttributes &= FILE_ATTRIBUTE_EVERYTHING;
  692. #endif
  693. }
  694. // strip out the ored flags
  695. lpShadowInfo->uStatus &= ~(SHARE_MERGING);
  696. if(SetShadowInfo(hDir, lpShadowInfo->hShadow
  697. , lpFind32
  698. , lpShadowInfo->uStatus
  699. , lpShadowInfo->uOp) < SRET_OK)
  700. {
  701. goto bailout;
  702. }
  703. // if this is a file and it is open, then
  704. // update the in memory structures
  705. if (pFdb)
  706. {
  707. USHORT usFlags = (USHORT)(lpShadowInfo->uStatus);
  708. USHORT usOldFlags, *pusLocalFlags = NULL;
  709. // we can't be truncating when a file is open
  710. Assert(!mTruncateDataCommand(uOp));
  711. usOldFlags = usFlags;
  712. pusLocalFlags = PLocalFlagsFromPFdb(pFdb);
  713. Assert(pusLocalFlags);
  714. if (mAndShadowFlags(uOp))
  715. {
  716. pFdb->usFlags = pFdb->usFlags & usFlags;
  717. }
  718. else if (mOrShadowFlags(uOp))
  719. {
  720. pFdb->usFlags = pFdb->usFlags | usFlags;
  721. }
  722. else
  723. {
  724. pFdb->usFlags = pFdb->usFlags | usFlags;
  725. }
  726. // if we are about to clear the reint bits
  727. // then also clear the snapshot bit
  728. // If the file has been modified after the snapshot was taken,
  729. // then the modified bit will have been set again
  730. if ((usOldFlags & SHADOW_DIRTY) && !(usFlags & SHADOW_DIRTY))
  731. {
  732. *pusLocalFlags &= ~FLAG_FDB_SHADOW_SNAPSHOTTED;
  733. }
  734. }
  735. iRet = 1;
  736. bailout:
  737. if (iRet < 0)
  738. {
  739. lpShadowInfo->dwError = GetLastErrorLocal();
  740. }
  741. LeaveShadowCrit();
  742. return (iRet);
  743. }
  744. int IoctlChkUpdtStatus(
  745. LPSHADOWINFO lpShadowInfo
  746. )
  747. /*++
  748. Routine Description:
  749. Check if the File represneted by the inode is out of date by and mark it as stale
  750. if so
  751. Parameters:
  752. Return Value:
  753. Notes:
  754. --*/
  755. {
  756. HSHADOW hDir;
  757. PFDB pFdb;
  758. int iRet = -1;
  759. if (!CSC_ENABLED)
  760. {
  761. lpShadowInfo->dwError = ERROR_SERVICE_NOT_ACTIVE;
  762. return -1;
  763. }
  764. EnterShadowCrit();
  765. if (!(hDir = lpShadowInfo->hDir))
  766. {
  767. if (GetAncestorsHSHADOW(lpShadowInfo->hShadow, &hDir, NULL) < 0)
  768. goto bailout;
  769. lpShadowInfo->hDir = hDir;
  770. }
  771. if(ChkUpdtStatusHSHADOW(hDir, lpShadowInfo->hShadow
  772. , lpShadowInfo->lpFind32
  773. , &(lpShadowInfo->uStatus)
  774. ) < SRET_OK)
  775. goto bailout;
  776. if(pFdb = PFindFdbFromHShadow(lpShadowInfo->hShadow))
  777. {
  778. // Update the staleness indicator in pFdb (why?)
  779. pFdb->usFlags ^= (lpShadowInfo->uStatus & SHADOW_STALE);
  780. // OR any flags such as DIRTY and SUSPECT that might
  781. // have occurred
  782. lpShadowInfo->uStatus |= pFdb->usFlags;
  783. }
  784. if (!(lpShadowInfo->lpFind32->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  785. {
  786. // is a file
  787. lpShadowInfo->uStatus |= SHADOW_IS_FILE;
  788. }
  789. iRet = 1;
  790. bailout:
  791. if (iRet < 0)
  792. {
  793. lpShadowInfo->dwError = GetLastErrorLocal();
  794. }
  795. LeaveShadowCrit();
  796. return (iRet);
  797. }
  798. int IoctlDoShadowMaintenance(
  799. LPSHADOWINFO lpSI
  800. )
  801. /*++
  802. Routine Description:
  803. Catchall routine which takes a minor_number to do interesting things.
  804. It used to be used for maitenance purposes, but has become a funnelling
  805. point for many helper ioctls
  806. Parameters:
  807. Return Value:
  808. Notes:
  809. --*/
  810. {
  811. int iRet = 1;
  812. OTHERINFO sOI;
  813. ULONG nFiles = 0;
  814. ULONG nYoungFiles = 0;
  815. if (lpSI->uOp == SHADOW_REINIT_DATABASE)
  816. {
  817. if (fShadow)
  818. {
  819. lpSI->dwError = ERROR_SERVICE_NOT_ACTIVE;
  820. return -1;
  821. }
  822. //
  823. // Check that cFileName and cAlternateFileName contain a NULL
  824. //
  825. if (CscCheckForNullA(((LPFIND32A)(lpSI->lpFind32))->cFileName, MAX_PATH) == FALSE) {
  826. lpSI->dwError = ERROR_INVALID_PARAMETER;
  827. return -1;
  828. }
  829. if (CscCheckForNullA(((LPFIND32A)(lpSI->lpFind32))->cAlternateFileName, 14) == FALSE) {
  830. lpSI->dwError = ERROR_INVALID_PARAMETER;
  831. return -1;
  832. }
  833. EnterShadowCrit();
  834. iRet = ReinitializeDatabase(
  835. ((LPFIND32A)(lpSI->lpFind32))->cFileName,
  836. ((LPFIND32A)(lpSI->lpFind32))->cAlternateFileName,
  837. ((LPFIND32A)(lpSI->lpFind32))->nFileSizeHigh,
  838. ((LPFIND32A)(lpSI->lpFind32))->nFileSizeLow,
  839. ((LPFIND32A)(lpSI->lpFind32))->dwReserved1
  840. );
  841. LeaveShadowCrit();
  842. if (iRet < 0) {
  843. lpSI->dwError = GetLastErrorLocal();
  844. }
  845. return (iRet);
  846. }
  847. else if (lpSI->uOp == SHADOW_ENABLE_CSC_FOR_USER)
  848. {
  849. CscInitializeSecurityDescriptor();
  850. if (CscAmIAdmin()) {
  851. if(IoctlEnableCSCForUser(lpSI) < 0) {
  852. lpSI->dwError = GetLastErrorLocal();
  853. return -1;
  854. } else {
  855. return 1;
  856. }
  857. } else {
  858. lpSI->dwError = ERROR_ACCESS_DENIED;
  859. return -1;
  860. }
  861. }
  862. if (!CSC_ENABLED) {
  863. lpSI->dwError = ERROR_SERVICE_NOT_ACTIVE;
  864. return -1;
  865. }
  866. EnterShadowCrit();
  867. UseGlobalFind32();
  868. switch(lpSI->uOp)
  869. {
  870. case SHADOW_MAKE_SPACE:
  871. // Assert(lpSI->lpFind32);
  872. if (lpSI->lpFind32 == NULL) {
  873. lpSI->dwError = ERROR_INVALID_PARAMETER;
  874. LeaveShadowCrit();
  875. return -1;
  876. }
  877. MakeSpace( lpSI->lpFind32->nFileSizeHigh,
  878. lpSI->lpFind32->nFileSizeLow,
  879. (lpSI->ulHintPri == 0xffffffff));
  880. break;
  881. case SHADOW_REDUCE_REFPRI:
  882. ReduceRefPri();
  883. break;
  884. case SHADOW_ADD_SPACE:
  885. // Assert(lpSI->lpFind32);
  886. if (lpSI->lpFind32 == NULL) {
  887. lpSI->dwError = ERROR_INVALID_PARAMETER;
  888. LeaveShadowCrit();
  889. return -1;
  890. }
  891. AllocShadowSpace(lpSI->lpFind32->nFileSizeHigh, lpSI->lpFind32->nFileSizeLow, TRUE);
  892. break;
  893. case SHADOW_FREE_SPACE:
  894. // Assert(lpSI->lpFind32);
  895. if (lpSI->lpFind32 == NULL) {
  896. lpSI->dwError = ERROR_INVALID_PARAMETER;
  897. LeaveShadowCrit();
  898. return -1;
  899. }
  900. FreeShadowSpace(lpSI->lpFind32->nFileSizeHigh, lpSI->lpFind32->nFileSizeLow, TRUE);
  901. break;
  902. case SHADOW_GET_SPACE_STATS:
  903. // Assert(lpSI->lpBuffer);
  904. // Assert(lpSI->cbBufferSize >= sizeof(SHADOWSTORE));
  905. if (lpSI->lpBuffer == NULL || lpSI->cbBufferSize < sizeof(SHADOWSTORE)) {
  906. lpSI->dwError = ERROR_INVALID_PARAMETER;
  907. LeaveShadowCrit();
  908. return -1;
  909. }
  910. if(GetShadowSpaceInfo((SHADOWSTORE *)(lpSI->lpBuffer)) >= SRET_OK) {
  911. iRet = 1;
  912. } else {
  913. iRet = -1;
  914. }
  915. break;
  916. case SHADOW_SET_MAX_SPACE:
  917. // Assert(lpSI->lpFind32);
  918. if (lpSI->lpFind32 == NULL) {
  919. lpSI->dwError = ERROR_INVALID_PARAMETER;
  920. LeaveShadowCrit();
  921. return -1;
  922. }
  923. SetMaxShadowSpace(lpSI->lpFind32->nFileSizeHigh, lpSI->lpFind32->nFileSizeLow);
  924. break;
  925. case SHADOW_PER_THREAD_DISABLE:
  926. if(!RegisterTempAgent()) {
  927. iRet = -1;
  928. }
  929. break;
  930. case SHADOW_PER_THREAD_ENABLE:
  931. if(!UnregisterTempAgent()) {
  932. iRet = -1;
  933. }
  934. break;
  935. case SHADOW_ADDHINT_FROM_INODE:
  936. iRet = IoctlAddDeleteHintFromInode(lpSI, TRUE);
  937. break;
  938. case SHADOW_DELETEHINT_FROM_INODE:
  939. iRet = IoctlAddDeleteHintFromInode(lpSI, FALSE);
  940. break;
  941. case SHADOW_COPY_INODE_FILE:
  942. iRet = IoctlCopyShadow(lpSI);
  943. break;
  944. case SHADOW_BEGIN_INODE_TRANSACTION:
  945. iRet = BeginInodeTransactionHSHADOW();
  946. break;
  947. case SHADOW_END_INODE_TRANSACTION:
  948. iRet = EndInodeTransactionHSHADOW();
  949. break;
  950. case SHADOW_FIND_CREATE_PRINCIPAL_ID:
  951. {
  952. DWORD dwError = ERROR_SUCCESS;
  953. CSC_SID_INDEX indx;
  954. if (CscCheckForNullA(lpSI->lpBuffer, lpSI->cbBufferSize) == FALSE) {
  955. lpSI->dwError = ERROR_INVALID_PARAMETER;
  956. LeaveShadowCrit();
  957. return -1;
  958. }
  959. if (lpSI->uStatus) {
  960. dwError = CscAddSidToDatabase(lpSI->lpBuffer, lpSI->cbBufferSize, &indx);
  961. } else {
  962. indx = CscMapSidToIndex(lpSI->lpBuffer, lpSI->cbBufferSize);
  963. if (indx == CSC_INVALID_PRINCIPAL_ID) {
  964. dwError = ERROR_NO_SUCH_USER;
  965. }
  966. }
  967. if (dwError != ERROR_SUCCESS) {
  968. iRet = -1;
  969. lpSI->dwError = dwError;
  970. } else {
  971. lpSI->ulPrincipalID = (ULONG)indx;
  972. }
  973. }
  974. break;
  975. case SHADOW_GET_SECURITY_INFO:
  976. LeaveShadowCrit();
  977. iRet = IoctlGetSecurityInfo(lpSI);
  978. return iRet;
  979. case SHADOW_SET_EXCLUSION_LIST:
  980. if (CscCheckForNullW(lpSI->lpBuffer, lpSI->cbBufferSize/sizeof(WCHAR)) == FALSE) {
  981. lpSI->dwError = ERROR_INVALID_PARAMETER;
  982. LeaveShadowCrit();
  983. return -1;
  984. }
  985. iRet = SetList(lpSI->lpBuffer, lpSI->cbBufferSize, CSHADOW_LIST_TYPE_EXCLUDE);
  986. break;
  987. case SHADOW_SET_BW_CONSERVE_LIST:
  988. if (CscCheckForNullW(lpSI->lpBuffer, lpSI->cbBufferSize/sizeof(WCHAR)) == FALSE) {
  989. lpSI->dwError = ERROR_INVALID_PARAMETER;
  990. LeaveShadowCrit();
  991. return -1;
  992. }
  993. iRet = SetList(lpSI->lpBuffer, lpSI->cbBufferSize, CSHADOW_LIST_TYPE_CONSERVE_BW);
  994. break;
  995. #ifdef CSC_RECORDMANAGER_WINNT
  996. case IOCTL_TRANSITION_SERVER_TO_OFFLINE:
  997. iRet = IoctlTransitionShareToOffline(lpSI);
  998. break;
  999. #endif
  1000. case SHADOW_CHANGE_HANDLE_CACHING_STATE:
  1001. iRet = IoctlChangeHandleCachingState(lpSI);
  1002. break;
  1003. case SHADOW_RECREATE:
  1004. if (!PFindFdbFromHShadow(lpSI->hShadow)) {
  1005. if(RecreateHSHADOW(lpSI->hDir, lpSI->hShadow, lpSI->uStatus) < 0) {
  1006. iRet = -1;
  1007. }
  1008. } else {
  1009. iRet = -1;
  1010. SetLastErrorLocal(ERROR_SHARING_VIOLATION);
  1011. }
  1012. break;
  1013. case SHADOW_SET_DATABASE_STATUS:
  1014. if (CscAmIAdmin()) {
  1015. if(SetDatabaseStatus(lpSI->uStatus, lpSI->ulHintFlags) < 0) {
  1016. iRet = -1;
  1017. }
  1018. } else {
  1019. iRet = -1;
  1020. SetLastErrorLocal(ERROR_ACCESS_DENIED);
  1021. }
  1022. break;
  1023. case SHADOW_RENAME:
  1024. iRet = IoctlRenameShadow(lpSI);
  1025. break;
  1026. case SHADOW_SPARSE_STALE_DETECTION_COUNTER:
  1027. QuerySparseStaleDetectionCount(&(lpSI->dwError));
  1028. iRet = 1;
  1029. break;
  1030. case SHADOW_MANUAL_FILE_DETECTION_COUNTER:
  1031. QueryManualFileDetectionCount(&(lpSI->dwError));
  1032. iRet = 1;
  1033. break;
  1034. case SHADOW_DISABLE_CSC_FOR_USER:
  1035. if (CscAmIAdmin()) {
  1036. iRet = IoctlDisableCSCForUser(lpSI);
  1037. } else {
  1038. iRet = -1;
  1039. SetLastErrorLocal(ERROR_ACCESS_DENIED);
  1040. }
  1041. break;
  1042. case SHADOW_PURGE_UNPINNED_FILES:
  1043. // Assert(lpSI->lpFind32);
  1044. if (lpSI->lpFind32 == NULL) {
  1045. lpSI->dwError = ERROR_INVALID_PARAMETER;
  1046. LeaveShadowCrit();
  1047. return -1;
  1048. }
  1049. iRet = PurgeUnpinnedFiles(
  1050. lpSI->lpFind32->nFileSizeHigh,
  1051. &nFiles,
  1052. &nYoungFiles);
  1053. if (iRet >= SRET_OK) {
  1054. iRet = 1; // Copy output params
  1055. lpSI->lpFind32->nFileSizeHigh = nFiles;
  1056. lpSI->lpFind32->nFileSizeLow = nYoungFiles;
  1057. // DbgPrint("IoctlDoShadowMaintenance: iRet=%d, nFiles=%d, nYoungFiles=%d\n",
  1058. // iRet,
  1059. // nFiles,
  1060. // nYoungFiles);
  1061. } else {
  1062. iRet = -1;
  1063. }
  1064. break;
  1065. }
  1066. if (iRet < 0) {
  1067. lpSI->dwError = GetLastErrorLocal();
  1068. }
  1069. LeaveShadowCrit();
  1070. return (iRet);
  1071. }
  1072. #ifndef CSC_RECORDMANAGER_WINNT
  1073. //the implementation on NT is completely different
  1074. int IoctlCopyChunk(
  1075. LPSHADOWINFO lpSI,
  1076. COPYCHUNKCONTEXT *lpCCC
  1077. )
  1078. /*++
  1079. Routine Description:
  1080. Parameters:
  1081. Return Value:
  1082. Notes:
  1083. --*/
  1084. {
  1085. PFILEINFO pFileInfo;
  1086. int iRet = -1;
  1087. if (!CSC_ENABLED)
  1088. {
  1089. return -1;
  1090. }
  1091. EnterHookCrit();
  1092. if (pFileInfo = PFileInfoAgent())
  1093. {
  1094. EnterShadowCrit();
  1095. iRet = CopyChunk(lpSI->hDir, lpSI->hShadow, pFileInfo, lpCCC);
  1096. LeaveShadowCrit();
  1097. }
  1098. LeaveHookCrit();
  1099. return (iRet);
  1100. }
  1101. #endif //ifndef CSC_RECORDMANAGER_WINNT
  1102. int IoctlBeginReint(
  1103. LPSHADOWINFO lpShadowInfo
  1104. )
  1105. /*++
  1106. Routine Description:
  1107. Puts a share in reintegration mode. The effect of this is that, all filesystem
  1108. open calls to the share fail with ACCESS_DENIED if they come to CSC.
  1109. Parameters:
  1110. lpShadowInfo The significant entry is hShare, which represents the share being
  1111. put in disconnected state
  1112. Return Value:
  1113. Notes:
  1114. CODE.IMPROVEMENT.ASHAMED This scheme assumes that only one share is reintegrated
  1115. at one time. So if the multiple guys call IoctlBeginReint, then they will tromp on
  1116. each other. We have taken care of it in the agent code which does merging. We allow
  1117. only one guy to merge at any time by taking a global critical section.
  1118. --*/
  1119. {
  1120. PPRESOURCE ppResource;
  1121. int i;
  1122. if (!CSC_ENABLED)
  1123. {
  1124. lpShadowInfo->dwError = ERROR_INVALID_FUNCTION;
  1125. return -1;
  1126. }
  1127. if (hShareReint)
  1128. {
  1129. lpShadowInfo->dwError = ERROR_BUSY;
  1130. return -1;
  1131. }
  1132. if (lpShadowInfo->hShare == 0)
  1133. {
  1134. lpShadowInfo->dwError = ERROR_INVALID_PARAMETER;
  1135. return -1;
  1136. }
  1137. // BUGBUG-win9xonly needs checking
  1138. #ifndef CSC_RECORDMANAGER_WINNT
  1139. EnterHookCrit();
  1140. #endif
  1141. #ifdef CSC_RECORDMANAGER_WINNT
  1142. EnterShadowCrit();
  1143. hShareReint = lpShadowInfo->hShare;
  1144. vdwActivityCount = 0;
  1145. // if uOp is non-zero then this is a reint that should abort if the activytcount
  1146. // is non-zero
  1147. vfBlockingReint = (lpShadowInfo->uOp == 0);
  1148. LeaveShadowCrit();
  1149. return(1);
  1150. #else
  1151. for (i=0;i<cMacPro;++i)
  1152. {
  1153. for(ppResource = &(rgNetPro[i].pheadResource); *ppResource; ppResource = &((*ppResource)->pnextResource))
  1154. {
  1155. if ((*ppResource)->hShare == lpShadowInfo->hShare)
  1156. {
  1157. if ((*ppResource)->pheadFileInfo || (*ppResource)->pheadFindInfo)
  1158. {
  1159. LeaveHookCrit();
  1160. return(-1);
  1161. }
  1162. }
  1163. }
  1164. }
  1165. #endif //ifdef CSC_RECORDMANAGER_WINNT
  1166. hShareReint = lpShadowInfo->hShare;
  1167. LeaveHookCrit();
  1168. return (1);
  1169. }
  1170. int IoctlEndReint(
  1171. LPSHADOWINFO lpShadowInfo
  1172. )
  1173. /*++
  1174. Routine Description:
  1175. Parameters:
  1176. Return Value:
  1177. Notes:
  1178. --*/
  1179. {
  1180. int iRet = -1;
  1181. EnterShadowCrit();
  1182. if (lpShadowInfo->hShare == hShareReint)
  1183. {
  1184. hShareReint = 0;
  1185. #ifndef CSC_RECORDMANAGER_WINNT
  1186. _SignalID(lpShadowInfo->hShare);
  1187. #endif
  1188. iRet = 1;
  1189. }
  1190. else
  1191. {
  1192. lpShadowInfo->dwError = ERROR_INVALID_PARAMETER;
  1193. }
  1194. LeaveShadowCrit();
  1195. return iRet;
  1196. }
  1197. int IoctlCreateShadow(
  1198. LPSHADOWINFO lpSI
  1199. )
  1200. /*++
  1201. Routine Description:
  1202. Parameters:
  1203. Return Value:
  1204. Notes:
  1205. --*/
  1206. {
  1207. int iRet= SRET_ERROR;
  1208. SHAREINFO sSRI;
  1209. LPFIND32 lpFind32 = lpSI->lpFind32;
  1210. BOOL fCreated = FALSE;
  1211. BOOL fIsLoopBack = FALSE;
  1212. if (!CSC_ENABLED)
  1213. {
  1214. lpSI->dwError = ERROR_SERVICE_NOT_ACTIVE;
  1215. return -1;
  1216. }
  1217. EnterShadowCrit();
  1218. UseGlobalFind32();
  1219. vsFind32 = *(lpSI->lpFind32);
  1220. if (MRxSmbCscIsLoopbackServer(lpSI->lpFind32->cFileName, &fIsLoopBack)==STATUS_SUCCESS) {
  1221. if (fIsLoopBack){
  1222. iRet = -1;
  1223. SetLastErrorLocal(ERROR_INVALID_NAME);
  1224. goto bailout;
  1225. }
  1226. }
  1227. // Find32FromFind32A(&vsFind32, (LPFIND32A)(lpSI->lpFind32), BCS_WANSI);
  1228. if (!lpSI->hDir)
  1229. {
  1230. iRet = FindCreateShare(vsFind32.cFileName, TRUE, lpSI, &fCreated);
  1231. }
  1232. else
  1233. {
  1234. iRet = 0;
  1235. if (IsFile(vsFind32.dwFileAttributes))
  1236. {
  1237. if (ExcludeFromCreateShadow(vsFind32.cFileName, wstrlen(vsFind32.cFileName), TRUE))
  1238. {
  1239. iRet = -1;
  1240. SetLastErrorLocal(ERROR_INVALID_NAME);
  1241. }
  1242. }
  1243. if (iRet == 0)
  1244. {
  1245. iRet = CreateShadow(lpSI->hDir, &vsFind32, lpSI->uStatus, &(lpSI->hShadow), &fCreated);
  1246. }
  1247. }
  1248. bailout:
  1249. if (iRet < SRET_OK)
  1250. {
  1251. lpSI->dwError = GetLastErrorLocal();
  1252. }
  1253. LeaveShadowCrit();
  1254. iRet = (iRet>=SRET_OK)?1:-1;
  1255. if ((iRet==1) && fCreated)
  1256. {
  1257. ReportCreateDelete(lpSI->hShadow, TRUE);
  1258. }
  1259. lpSI->lpFind32 = lpFind32;
  1260. return (iRet);
  1261. }
  1262. int IoctlDeleteShadow(
  1263. LPSHADOWINFO lpSI
  1264. )
  1265. /*++
  1266. Routine Description:
  1267. Parameters:
  1268. Return Value:
  1269. Notes:
  1270. --*/
  1271. {
  1272. int iRet=SRET_ERROR;
  1273. BOOL fDoit = TRUE;
  1274. PFDB pFdb;
  1275. DeclareFindFromShadowOnNtVars()
  1276. if (!CSC_ENABLED)
  1277. {
  1278. lpSI->dwError = ERROR_SERVICE_NOT_ACTIVE;
  1279. return -1;
  1280. }
  1281. EnterShadowCrit();
  1282. if (FailModificationsToShare(lpSI))
  1283. {
  1284. goto bailout;
  1285. }
  1286. if (!lpSI->hDir)
  1287. {
  1288. if (PFindResourceFromRoot(lpSI->hShadow, 0xffff, 0))
  1289. {
  1290. fDoit = FALSE;
  1291. }
  1292. }
  1293. else if (pFdb = PFindFdbFromHShadow(lpSI->hShadow))
  1294. {
  1295. // Issue a flush to see if the file is in delayclose list
  1296. MRxSmbCscFlushFdb(pFdb);
  1297. if (PFindFdbFromHShadow(lpSI->hShadow))
  1298. {
  1299. fDoit = FALSE;
  1300. }
  1301. }
  1302. else if (PFindFindInfoFromHShadow(lpSI->hShadow))
  1303. {
  1304. fDoit = FALSE;
  1305. }
  1306. else
  1307. {
  1308. // DbgPrint("%x has an FCB\n", lpSI->hShadow);
  1309. // Assert(FALSE);
  1310. }
  1311. // if the shadow is not busy in some transaction, delete it
  1312. if (fDoit)
  1313. {
  1314. iRet = DeleteShadow(lpSI->hDir, lpSI->hShadow);
  1315. if (iRet>=SRET_OK)
  1316. {
  1317. ReportCreateDelete(lpSI->hShadow, FALSE);
  1318. }
  1319. else
  1320. {
  1321. // DbgPrint("%x is open on the disk\n", lpSI->hShadow);
  1322. // Assert(FALSE);
  1323. }
  1324. }
  1325. bailout:
  1326. if (iRet < SRET_OK)
  1327. {
  1328. lpSI->dwError = GetLastErrorLocal();
  1329. }
  1330. LeaveShadowCrit();
  1331. return ((iRet >=SRET_OK)?1:-1);
  1332. }
  1333. int IoctlGetShareStatus(
  1334. LPSHADOWINFO lpSI
  1335. )
  1336. /*++
  1337. Routine Description:
  1338. Parameters:
  1339. Return Value:
  1340. Notes:
  1341. --*/
  1342. {
  1343. int iRet;
  1344. PRESOURCE pResource;
  1345. SHAREINFOW *lpShareInfo = (SHAREINFOW *)(lpSI->lpFind32); // save it because, getserverinfo destory's it
  1346. DeclareFindFromShadowOnNtVars()
  1347. if (!CSC_ENABLED)
  1348. {
  1349. lpSI->dwError = ERROR_SERVICE_NOT_ACTIVE;
  1350. return -1;
  1351. }
  1352. EnterShadowCrit();
  1353. UseGlobalFind32();
  1354. Assert(sizeof(SHAREINFOW) <= sizeof(WIN32_FIND_DATA));
  1355. iRet = GetShareInfo(lpSI->hShare, (LPSHAREINFOW)(&vsFind32), lpSI);
  1356. if (iRet >= SRET_OK)
  1357. {
  1358. if (lpShareInfo)
  1359. {
  1360. *lpShareInfo = *(LPSHAREINFOW)(&vsFind32);
  1361. }
  1362. if (pResource = PFindResourceFromHShare(lpSI->hShare, 0xffff, 0))
  1363. {
  1364. IFNOT_CSC_RECORDMANAGER_WINNT
  1365. {
  1366. lpSI->uStatus |= ((pResource->usLocalFlags|SHARE_CONNECTED)|
  1367. ((pResource->pheadFdb)?SHARE_FILES_OPEN:0) |
  1368. ((pResource->pheadFindInfo) ?SHARE_FINDS_IN_PROGRESS:0));
  1369. }
  1370. else
  1371. {
  1372. lpSI->uStatus |= MRxSmbCscGetSavedResourceStatus();
  1373. }
  1374. }
  1375. // UI expects to know whether a server is offline
  1376. // even when a share may not be offline. So we do the following drill anyways
  1377. {
  1378. #ifdef CSC_RECORDMANAGER_WINNT
  1379. BOOL fShareOnline = FALSE;
  1380. BOOL fPinnedOffline = FALSE;
  1381. // Leave Crit sec coz MRxSmbCscServerStateFromCompleteUNCPath may acquire SmbCeResource
  1382. LeaveShadowCrit();
  1383. if (MRxSmbCscServerStateFromCompleteUNCPath(
  1384. ((LPSHAREINFOW)(&vsFind32))->rgSharePath,
  1385. &fShareOnline,
  1386. &fPinnedOffline)==STATUS_SUCCESS) {
  1387. if (!fShareOnline)
  1388. lpSI->uStatus |= SHARE_DISCONNECTED_OP;
  1389. if (fPinnedOffline)
  1390. lpSI->uStatus |= SHARE_PINNED_OFFLINE;
  1391. }
  1392. EnterShadowCrit();
  1393. #endif
  1394. }
  1395. }
  1396. if (iRet < SRET_OK)
  1397. {
  1398. lpSI->dwError = GetLastErrorLocal();
  1399. }
  1400. LeaveShadowCrit();
  1401. return ((iRet >=SRET_OK)?1:-1);
  1402. }
  1403. int IoctlSetShareStatus(
  1404. LPSHADOWINFO lpSI
  1405. )
  1406. /*++
  1407. Routine Description:
  1408. Parameters:
  1409. Return Value:
  1410. Notes:
  1411. --*/
  1412. {
  1413. int iRet=SRET_ERROR;
  1414. HSHARE hShare = lpSI->hShare;
  1415. ULONG uStatus = lpSI->uStatus, uOp = lpSI->uOp;
  1416. DWORD cntDirty = 0;
  1417. if (!CSC_ENABLED)
  1418. {
  1419. lpSI->dwError = ERROR_SERVICE_NOT_ACTIVE;
  1420. return -1;
  1421. }
  1422. EnterShadowCrit();
  1423. if (!FailModificationsToShare(lpSI))
  1424. {
  1425. iRet = SRET_OK;
  1426. if (((uOp == SHADOW_FLAGS_ASSIGN)||(uOp == SHADOW_FLAGS_AND))&&!(uStatus & SHARE_REINT))
  1427. {
  1428. iRet = GetShareInfo(hShare, NULL, lpSI);
  1429. if (iRet >= SRET_OK)
  1430. {
  1431. if (lpSI->uStatus & SHARE_REINT)
  1432. {
  1433. iRet = TraversePQToCheckDirtyBits(hShare, &cntDirty);
  1434. // if the traversal failed, or there are some dirty entries
  1435. // then putback the dirty bit
  1436. if ((iRet==SRET_ERROR) || cntDirty)
  1437. {
  1438. uStatus |= SHARE_REINT;
  1439. }
  1440. }
  1441. }
  1442. }
  1443. if (iRet >= SRET_OK)
  1444. {
  1445. SetResourceFlags(hShare, uStatus, uOp);
  1446. iRet = SetShareStatus(hShare, uStatus, uOp);
  1447. }
  1448. }
  1449. if (iRet < SRET_OK)
  1450. {
  1451. lpSI->dwError = GetLastErrorLocal();
  1452. }
  1453. LeaveShadowCrit();
  1454. return ((iRet >=SRET_OK)?1:-1);
  1455. }
  1456. #ifndef CSC_RECORDMANAGER_WINNT
  1457. int IoctlAddUse(
  1458. LPCOPYPARAMSA lpCPA
  1459. )
  1460. /*++
  1461. Routine Description:
  1462. Parameters:
  1463. Return Value:
  1464. Notes:
  1465. --*/
  1466. {
  1467. struct netuse_info nu;
  1468. struct use_info_2 ui;
  1469. int iRet=-1;
  1470. PRESOURCE pResource=NULL;
  1471. HSHADOW hRoot;
  1472. ULONG uShareStatus;
  1473. BOOL fAlloced = FALSE, fOfflinePath=FALSE;
  1474. path_t ppath;
  1475. HSHARE hShare;
  1476. #ifdef DEBUG
  1477. int indx = 0;
  1478. #endif //DEBUG
  1479. #ifdef MAYBE
  1480. if (!CSC_ENABLED)
  1481. {
  1482. return -1;
  1483. }
  1484. // Don't add shadow use for the agent
  1485. if (IsSpecialApp())
  1486. {
  1487. lpCPA->hDir = lpCPA->dwError = ERROR_BAD_NETPATH;
  1488. return (-1);
  1489. }
  1490. #endif
  1491. memset(&ui, 0, sizeof(ui));
  1492. if (lpCPA->lpLocalPath)
  1493. {
  1494. strcpy(ui.ui2_local, lpCPA->lpLocalPath);
  1495. #ifdef DEBUG
  1496. indx = GetDriveIndex(lpCPA->lpLocalPath);
  1497. #endif //DEBUG
  1498. }
  1499. if (ppath = (path_t)AllocMem((strlen(lpCPA->lpRemotePath)+4)*sizeof(USHORT)))
  1500. {
  1501. MakePPath(ppath, lpCPA->lpRemotePath);
  1502. if (fOfflinePath = IsOfflinePE(ppath->pp_elements))
  1503. {
  1504. OfflineToOnlinePath(ppath);
  1505. }
  1506. EnterShadowCrit();
  1507. UseGlobalFind32();
  1508. hShare = HShareFromPath(NULL, ppath->pp_elements, 0, &vsFind32, &hRoot, &uShareStatus);
  1509. LeaveShadowCrit();
  1510. if (fOfflinePath)
  1511. {
  1512. OnlineToOfflinePath(ppath);
  1513. }
  1514. // Has connect succeeded with this server in the past?
  1515. if (hShare)
  1516. {
  1517. // Any resource allocated by shadow NP?
  1518. pResource = PFindResource(ppath->pp_elements
  1519. , RH_DISCONNECTED
  1520. , ANY_FHID
  1521. , FLAG_RESOURCE_SHADOWNP
  1522. , NULL);
  1523. if (!pResource)
  1524. {
  1525. pResource = PCreateResource(ppath->pp_elements);
  1526. if (pResource)
  1527. {
  1528. fAlloced = TRUE;
  1529. DisconnectAllByName(pResource->pp_elements);
  1530. pResource->usLocalFlags |=
  1531. (FLAG_RESOURCE_SHADOW_CONNECT_PENDING
  1532. | ((fOfflinePath)?FLAG_RESOURCE_OFFLINE_CONNECTION:0));
  1533. LinkResource(pResource, &rgNetPro[0]);
  1534. KdPrint(("shadow:Created pending resource %x \r\n", pResource));
  1535. }
  1536. }
  1537. }
  1538. FreeMem(ppath);
  1539. }
  1540. if (pResource)
  1541. {
  1542. // need to tell IFS about the use
  1543. ui.ui2_remote = lpCPA->lpRemotePath;
  1544. ui.ui2_password="";
  1545. ui.ui2_asg_type = USE_DISKDEV;
  1546. ui.ui2_res_type = USE_RES_UNC;
  1547. nu.nu_data = &ui;
  1548. nu.nu_flags = FSD_NETAPI_USEOEM;
  1549. nu.nu_info = (int)(pResource);
  1550. iRet = IFSMgr_UseAdd(NULL, proidShadow, &nu);
  1551. if (iRet)
  1552. {
  1553. lpCPA->hDir = (ULONG)iRet;
  1554. KdPrint(("SHADOW::IoctlAddUse: error %x \r\n", iRet));
  1555. if (fAlloced)
  1556. {
  1557. PUnlinkResource(pResource, &rgNetPro[0]);
  1558. DestroyResource(pResource);
  1559. }
  1560. iRet = -1;
  1561. }
  1562. else
  1563. {
  1564. // AddUse succeeded
  1565. lpCPA->hDir = 0;
  1566. iRet = 1;
  1567. }
  1568. }
  1569. bailout:
  1570. return (iRet);
  1571. }
  1572. int IoctlDelUse(
  1573. LPCOPYPARAMSA lpCPA
  1574. )
  1575. /*++
  1576. Routine Description:
  1577. Parameters:
  1578. Return Value:
  1579. Notes:
  1580. --*/
  1581. {
  1582. int indx, iRet=-1;
  1583. PRESOURCE pResource;
  1584. struct netuse_info nu;
  1585. struct use_info_2 ui;
  1586. BOOL fDoit = FALSE;
  1587. if (!CSC_ENABLED)
  1588. {
  1589. return -1;
  1590. }
  1591. if (*(lpCPA->lpRemotePath+1)==':')
  1592. {
  1593. indx = GetDriveIndex(lpCPA->lpRemotePath);
  1594. if (indx && PFindShadowResourceFromDriveMap(indx))
  1595. {
  1596. fDoit = TRUE;
  1597. }
  1598. }
  1599. else
  1600. {
  1601. EnterShadowCrit();
  1602. UseGlobalFind32();
  1603. if (strlen(lpCPA->lpRemotePath) < (sizeof(vsFind32.cFileName)/2-2))
  1604. {
  1605. MakePPath((path_t)(vsFind32.cFileName), lpCPA->lpRemotePath);
  1606. if (PFindResource(((path_t)(vsFind32.cFileName))->pp_elements, 0, ANY_FHID, FLAG_RESOURCE_DISCONNECTED, NULL))
  1607. {
  1608. fDoit = TRUE;
  1609. }
  1610. }
  1611. LeaveShadowCrit();
  1612. }
  1613. if (fDoit)
  1614. {
  1615. memset (&ui, 0, sizeof(ui));
  1616. strcpy (ui.ui2_local, lpCPA->lpRemotePath);
  1617. nu.nu_data = &ui.ui2_local;
  1618. nu.nu_flags = FSD_NETAPI_USEOEM;
  1619. nu.nu_info = (lpCPA->hShadow)?3:0;
  1620. if(!(lpCPA->hDir = IFSMgr_UseDel(0, proidShadow, &nu)))
  1621. {
  1622. iRet = 1;
  1623. }
  1624. }
  1625. else
  1626. {
  1627. lpCPA->hDir = ERROR_BAD_NETPATH;
  1628. }
  1629. return (iRet);
  1630. }
  1631. int IoctlGetUse(
  1632. LPCOPYPARAMSA lpCPA
  1633. )
  1634. /*++
  1635. Routine Description:
  1636. Parameters:
  1637. Return Value:
  1638. Notes:
  1639. --*/
  1640. {
  1641. int indx;
  1642. PRESOURCE pResource;
  1643. if (!CSC_ENABLED)
  1644. {
  1645. return -1;
  1646. }
  1647. indx = GetDriveIndex(lpCPA->lpLocalPath);
  1648. if (!indx)
  1649. return (-1);
  1650. if (pResource = PFindShadowResourceFromDriveMap(indx))
  1651. {
  1652. if (PpeToSvr(pResource->pp_elements, lpCPA->lpRemotePath, lpCPA->hShadow, 0))
  1653. {
  1654. return (1);
  1655. }
  1656. }
  1657. return (-1);
  1658. }
  1659. #endif //ifndef CSC_RECORDMANAGER_WINNT
  1660. int IoctlSwitches(
  1661. LPSHADOWINFO lpSI
  1662. )
  1663. /*++
  1664. Routine Description:
  1665. Parameters:
  1666. Return Value:
  1667. Notes:
  1668. --*/
  1669. {
  1670. BOOL fRet = 1;
  1671. switch (lpSI->uOp)
  1672. {
  1673. case SHADOW_SWITCH_GET_STATE:
  1674. {
  1675. lpSI->uStatus = ((fShadow)?SHADOW_SWITCH_SHADOWING:0)
  1676. |((fLog)?SHADOW_SWITCH_LOGGING:0)
  1677. /*|((fShadowFind)?SHADOW_SWITCH_SHADOWFIND:0)*/
  1678. |((fSpeadOpt)?SHADOW_SWITCH_SPEAD_OPTIMIZE:0)
  1679. #if defined(REMOTE_BOOT)
  1680. | ((fIsRemoteBootSystem)?SHADOW_SWITCH_REMOTE_BOOT:0)
  1681. #endif // defined(REMOTE_BOOT)
  1682. ;
  1683. if (lpSI->lpFind32)
  1684. {
  1685. if (fShadow)
  1686. {
  1687. EnterShadowCrit();
  1688. UseGlobalFind32();
  1689. fRet = GetDatabaseLocation((LPSTR)(vsFind32.cFileName));
  1690. Assert(fRet >= 0);
  1691. fRet = BCSToUni( lpSI->lpFind32->cFileName,
  1692. (LPSTR)(vsFind32.cFileName),
  1693. MAX_PATH,
  1694. BCS_WANSI);
  1695. Assert(fRet > 0);
  1696. fRet = 1;
  1697. LeaveShadowCrit();
  1698. }
  1699. else
  1700. {
  1701. fRet = -1;
  1702. lpSI->dwError = ERROR_INVALID_ACCESS;
  1703. }
  1704. }
  1705. break;
  1706. }
  1707. case SHADOW_SWITCH_OFF:
  1708. {
  1709. if (mQueryBits(lpSI->uStatus, SHADOW_SWITCH_LOGGING))
  1710. {
  1711. fLog = 0;
  1712. mClearBits(lpSI->uStatus, SHADOW_SWITCH_LOGGING);
  1713. }
  1714. if (mQueryBits(lpSI->uStatus, SHADOW_SWITCH_SHADOWING))
  1715. {
  1716. // DbgPrint("Agent closing database fShadow=%x\r\n", fShadow);
  1717. if (fShadow)
  1718. {
  1719. EnterShadowCrit();
  1720. if (hPQEnumCookieForIoctls != NULL)
  1721. {
  1722. EndPQEnum(hPQEnumCookieForIoctls);
  1723. hPQEnumCookieForIoctls = NULL;
  1724. }
  1725. CloseDatabase();
  1726. fShadow = 0;
  1727. mClearBits(lpSI->uStatus, SHADOW_SWITCH_SHADOWING);
  1728. LeaveShadowCrit();
  1729. }
  1730. }
  1731. #ifdef HISTORY
  1732. if (mQueryBits(lpSI->uStatus, SHADOW_SWITCH_SHADOWFIND))
  1733. {
  1734. fShadowFind = 0;
  1735. mClearBits(lpSI->uStatus, SHADOW_SWITCH_SHADOWFIND);
  1736. }
  1737. #endif //HISTORY
  1738. if (mQueryBits(lpSI->uStatus, SHADOW_SWITCH_SPEAD_OPTIMIZE))
  1739. {
  1740. fSpeadOpt = 0;
  1741. mClearBits(lpSI->uStatus, SHADOW_SWITCH_SPEAD_OPTIMIZE);
  1742. }
  1743. break;
  1744. }
  1745. case SHADOW_SWITCH_ON:
  1746. {
  1747. if (mQueryBits(lpSI->uStatus, SHADOW_SWITCH_LOGGING))
  1748. {
  1749. #ifdef CSC_RECORDMANAGER_WINNT
  1750. #if defined(_X86_)
  1751. fLog = 1;
  1752. mClearBits(lpSI->uStatus, SHADOW_SWITCH_LOGGING);
  1753. #endif
  1754. #else
  1755. fLog = 1;
  1756. mClearBits(lpSI->uStatus, SHADOW_SWITCH_LOGGING);
  1757. #endif
  1758. }
  1759. if (mQueryBits(lpSI->uStatus, SHADOW_SWITCH_SHADOWING))
  1760. {
  1761. if (!fShadow)
  1762. {
  1763. if (OK_TO_ENABLE_CSC)
  1764. {
  1765. Assert(lpSI->lpFind32);
  1766. //
  1767. // Check that cFileName and cAlternateFileName contain a NULL
  1768. //
  1769. if (CscCheckForNullA(((LPFIND32A)(lpSI->lpFind32))->cFileName, MAX_PATH) == FALSE) {
  1770. lpSI->dwError = ERROR_INVALID_PARAMETER;
  1771. return -1;
  1772. }
  1773. if (CscCheckForNullA(((LPFIND32A)(lpSI->lpFind32))->cAlternateFileName, 14) == FALSE) {
  1774. lpSI->dwError = ERROR_INVALID_PARAMETER;
  1775. return -1;
  1776. }
  1777. // check if we can initialize the database
  1778. // KdPrint(("Trying to shadow....%s\n",
  1779. // ((LPFIND32A)(lpSI->lpFind32))->cFileName));
  1780. EnterShadowCrit();
  1781. if(InitDatabase(
  1782. ((LPFIND32A)(lpSI->lpFind32))->cFileName, // location
  1783. ((LPFIND32A)(lpSI->lpFind32))->cAlternateFileName, // user
  1784. ((LPFIND32A)(lpSI->lpFind32))->nFileSizeHigh, // default cache size if creating
  1785. ((LPFIND32A)(lpSI->lpFind32))->nFileSizeLow,
  1786. ((LPFIND32A)(lpSI->lpFind32))->dwReserved1, // cluster size
  1787. lpSI->ulRefPri,
  1788. &(lpSI->uOp)) // whether newly created
  1789. ==-1)
  1790. {
  1791. //we can't, let us quit
  1792. lpSI->dwError = GetLastErrorLocal();
  1793. fRet = -1;
  1794. LeaveShadowCrit();
  1795. break;
  1796. }
  1797. LeaveShadowCrit();
  1798. // KdPrint(("Starting to shadow....\n"));
  1799. fShadow = 1;
  1800. }
  1801. else
  1802. {
  1803. //we are not supposed to turn on csc. This happens only on NT
  1804. lpSI->dwError = ERROR_ACCESS_DENIED;
  1805. fRet = -1;
  1806. break;
  1807. }
  1808. }
  1809. mClearBits(lpSI->uStatus, SHADOW_SWITCH_SHADOWING);
  1810. }
  1811. #ifdef HISTORY
  1812. if (mQueryBits(lpSI->uStatus, SHADOW_SWITCH_SHADOWFIND))
  1813. {
  1814. fShadowFind = 1;
  1815. mClearBits(lpSI->uStatus, SHADOW_SWITCH_SHADOWFIND);
  1816. }
  1817. #endif //HISTORY
  1818. if (mQueryBits(lpSI->uStatus, SHADOW_SWITCH_SPEAD_OPTIMIZE))
  1819. {
  1820. fSpeadOpt = 1;
  1821. mClearBits(lpSI->uStatus, SHADOW_SWITCH_SPEAD_OPTIMIZE);
  1822. }
  1823. break;
  1824. }
  1825. }
  1826. return (fRet);
  1827. }
  1828. int IoctlGetShadow(
  1829. LPSHADOWINFO lpSI
  1830. )
  1831. /*++
  1832. Routine Description:
  1833. Parameters:
  1834. Return Value:
  1835. Notes:
  1836. --*/
  1837. {
  1838. int iRet=-1, iRet1;
  1839. OTHERINFO sOI;
  1840. PFDB pFdb=NULL;
  1841. PRESOURCE pResource=NULL;
  1842. if (!CSC_ENABLED)
  1843. {
  1844. lpSI->dwError = ERROR_SERVICE_NOT_ACTIVE;
  1845. return -1;
  1846. }
  1847. EnterShadowCrit();
  1848. UseGlobalFind32();
  1849. iRet1 = GetShadow(lpSI->hDir, lpSI->lpFind32->cFileName, &(lpSI->hShadow), &vsFind32, &(lpSI->uStatus), &sOI);
  1850. // If it worked and we have a shadow ID which is a filesystem object
  1851. if ((iRet1 >= SRET_OK)&& !mNotFsobj(lpSI->uStatus))
  1852. {
  1853. if (lpSI->hShadow)
  1854. {
  1855. if (lpSI->hDir)
  1856. {
  1857. if (!(vsFind32.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  1858. {
  1859. lpSI->uStatus |= SHADOW_IS_FILE;
  1860. if(pFdb = PFindFdbFromHShadow(lpSI->hShadow))
  1861. {
  1862. lpSI->uStatus |= (SHADOW_FILE_IS_OPEN | pFdb->usFlags);
  1863. }
  1864. }
  1865. }
  1866. else
  1867. {
  1868. // this is a share
  1869. DeclareFindFromShadowOnNtVars()
  1870. if(pResource = PFindResourceFromRoot(lpSI->hShadow, 0xffff, 0))
  1871. {
  1872. IFNOT_CSC_RECORDMANAGER_WINNT
  1873. {
  1874. lpSI->uStatus |= ((pResource->usLocalFlags|SHARE_CONNECTED)|
  1875. ((pResource->pheadFdb)?SHARE_FILES_OPEN:0) |
  1876. ((pResource->pheadFindInfo) ?SHARE_FINDS_IN_PROGRESS:0));
  1877. }
  1878. else
  1879. {
  1880. lpSI->uStatus |= MRxSmbCscGetSavedResourceStatus();
  1881. }
  1882. }
  1883. // UI expects to know whether a server is offline
  1884. // even when a share may not be offline. So we do the following drill anyways
  1885. {
  1886. #ifdef CSC_RECORDMANAGER_WINNT
  1887. BOOL fShareOnline = FALSE;
  1888. BOOL fPinnedOffline = FALSE;
  1889. // Leave Crit sec coz MRxSmbCscServerStateFromCompleteUNCPath may acquire SmbCeResource
  1890. LeaveShadowCrit();
  1891. if (MRxSmbCscServerStateFromCompleteUNCPath(
  1892. lpSI->lpFind32->cFileName,
  1893. &fShareOnline,
  1894. &fPinnedOffline)==STATUS_SUCCESS) {
  1895. if (!fShareOnline)
  1896. lpSI->uStatus |= SHARE_DISCONNECTED_OP;
  1897. if (fPinnedOffline)
  1898. lpSI->uStatus |= SHARE_PINNED_OFFLINE;
  1899. }
  1900. EnterShadowCrit();
  1901. #endif
  1902. }
  1903. }
  1904. CopyOtherInfoToShadowInfo(&sOI, lpSI);
  1905. if(GetAncestorsHSHADOW(lpSI->hShadow, NULL, &(lpSI->hShare)) < SRET_OK)
  1906. {
  1907. goto bailout;
  1908. }
  1909. *(lpSI->lpFind32) = vsFind32;
  1910. }
  1911. iRet = 1;
  1912. // if we couldn't find it in the database, and we are doing lookups for shares
  1913. // then let us lookup the in-memory data strucutres
  1914. if (!lpSI->hShadow && !lpSI->hDir)
  1915. {
  1916. #ifndef CSC_RECORDMANAGER_WINNT
  1917. {
  1918. path_t ppath;
  1919. memset((LPSTR)(vsFind32.cFileName), 0, sizeof(vsFind32.cFileName));
  1920. UniToBCS((LPSTR)(vsFind32.cFileName),
  1921. lpSI->lpFind32->cFileName,
  1922. wstrlen(lpSI->lpFind32->cFileName)*sizeof(USHORT),
  1923. sizeof(vsFind32.cFileName),
  1924. BCS_WANSI);
  1925. if (ppath = (path_t)AllocMem((strlen((LPSTR)(vsFind32.cFileName))+4)*sizeof(USHORT)))
  1926. {
  1927. MakePPath(ppath, (LPSTR)(vsFind32.cFileName));
  1928. pResource = PFindResource(ppath->pp_elements
  1929. , ANY_RESOURCE
  1930. , ANY_FHID
  1931. , 0xffff
  1932. , NULL);
  1933. if (pResource)
  1934. {
  1935. lpSI->uStatus = ResourceCscBitsToShareCscBits(mGetCSCBits(pResource));
  1936. lpSI->uStatus |= SHARE_CONNECTED;
  1937. }
  1938. FreeMem(ppath);
  1939. }
  1940. }
  1941. #else
  1942. {
  1943. if(MRxSmbCscCachingBitsFromCompleteUNCPath(lpSI->lpFind32->cFileName,
  1944. &(lpSI->uStatus)) == STATUS_SUCCESS)
  1945. {
  1946. lpSI->uStatus |= SHARE_CONNECTED;
  1947. }
  1948. }
  1949. #endif
  1950. }
  1951. }
  1952. bailout:
  1953. if (iRet < SRET_OK)
  1954. {
  1955. lpSI->dwError = GetLastErrorLocal();
  1956. }
  1957. LeaveShadowCrit();
  1958. return (iRet);
  1959. }
  1960. int IoctlAddHint( // Add a new hint or change an existing hint
  1961. LPSHADOWINFO lpSI
  1962. )
  1963. /*++
  1964. Routine Description:
  1965. Parameters:
  1966. Return Value:
  1967. Notes:
  1968. --*/
  1969. {
  1970. int iRet;
  1971. OTHERINFO sOI;
  1972. if (!CSC_ENABLED)
  1973. {
  1974. lpSI->dwError = ERROR_SERVICE_NOT_ACTIVE;
  1975. return -1;
  1976. }
  1977. EnterShadowCrit();
  1978. UseGlobalFind32();
  1979. vsFind32 = *(lpSI->lpFind32);
  1980. // BCSToUni(vsFind32.cFileName, (LPSTR)(lpSI->lpFind32->cFileName), MAX_PATH, BCS_WANSI);
  1981. if (lpSI->hDir)
  1982. {
  1983. iRet = CreateHint(lpSI->hDir, &vsFind32, lpSI->ulHintFlags, lpSI->ulHintPri, &(lpSI->hShadow));
  1984. #ifdef MAYBE
  1985. if (iRet == SRET_OBJECT_HINT)
  1986. {
  1987. if(RecalcIHPri(lpSI->hDir, lpSI->hShadow, &vsFind32, &sOI)>=SRET_OK)
  1988. {
  1989. SetPriorityHSHADOW(lpSI->hDir, lpSI->hShadow, RETAIN_VALUE, sOI.ulIHPri);
  1990. }
  1991. }
  1992. #endif //MAYBE
  1993. }
  1994. else
  1995. {
  1996. iRet = CreateGlobalHint(vsFind32.cFileName, lpSI->ulHintFlags, lpSI->ulHintPri);
  1997. }
  1998. if (iRet < SRET_OK)
  1999. {
  2000. lpSI->dwError = GetLastErrorLocal();
  2001. }
  2002. LeaveShadowCrit();
  2003. return ((iRet >= SRET_OK)?1:-1);
  2004. }
  2005. int IoctlDeleteHint( // Delete an existing hint
  2006. LPSHADOWINFO lpSI
  2007. )
  2008. /*++
  2009. Routine Description:
  2010. Parameters:
  2011. Return Value:
  2012. Notes:
  2013. --*/
  2014. {
  2015. int iRet;
  2016. BOOL fClearAll = (lpSI->ulHintPri == 0xffffffff);
  2017. if (!CSC_ENABLED)
  2018. {
  2019. lpSI->dwError = ERROR_SERVICE_NOT_ACTIVE;
  2020. return -1;
  2021. }
  2022. EnterShadowCrit();
  2023. UseGlobalFind32();
  2024. vsFind32 = *(lpSI->lpFind32);
  2025. // BCSToUni(vsFind32.cFileName, (LPSTR)(lpSI->lpFind32->cFileName), MAX_PATH, BCS_WANSI);
  2026. if (lpSI->hDir)
  2027. {
  2028. iRet = DeleteHint(lpSI->hDir, vsFind32.cFileName, fClearAll);
  2029. }
  2030. else
  2031. {
  2032. iRet = DeleteGlobalHint(vsFind32.cFileName, fClearAll);
  2033. }
  2034. if (iRet < SRET_OK)
  2035. {
  2036. lpSI->dwError = GetLastErrorLocal();
  2037. }
  2038. LeaveShadowCrit();
  2039. return ((iRet >= SRET_OK)?1:-1);
  2040. }
  2041. int IoctlGetHint(
  2042. LPSHADOWINFO lpSI
  2043. )
  2044. /*++
  2045. Routine Description:
  2046. Parameters:
  2047. Return Value:
  2048. Notes:
  2049. --*/
  2050. {
  2051. int iRet;
  2052. OTHERINFO sOI;
  2053. if (!CSC_ENABLED)
  2054. {
  2055. lpSI->dwError = ERROR_SERVICE_NOT_ACTIVE;
  2056. return -1;
  2057. }
  2058. EnterShadowCrit();
  2059. UseGlobalFind32();
  2060. iRet = GetShadow(lpSI->hDir, lpSI->lpFind32->cFileName, &(lpSI->hShadow), &vsFind32, &(lpSI->uStatus), &sOI);
  2061. if ((iRet>=SRET_OK) && (lpSI->hShadow) && mIsHint(sOI.ulHintFlags))
  2062. {
  2063. CopyOtherInfoToShadowInfo(&sOI, lpSI);
  2064. iRet = 1;
  2065. }
  2066. else
  2067. {
  2068. SetLastErrorLocal(ERROR_INVALID_ACCESS);
  2069. iRet = -1;
  2070. }
  2071. if (iRet < SRET_OK)
  2072. {
  2073. lpSI->dwError = GetLastErrorLocal();
  2074. }
  2075. LeaveShadowCrit();
  2076. return (iRet);
  2077. }
  2078. int IoctlFindOpenHSHADOW(
  2079. LPSHADOWINFO lpSI
  2080. )
  2081. /*++
  2082. Routine Description:
  2083. Parameters:
  2084. Return Value:
  2085. Notes:
  2086. --*/
  2087. {
  2088. int iRet=-1;
  2089. LPFINDSHADOW lpFSH;
  2090. HSHADOW hTmp;
  2091. ULONG uSrchFlags;
  2092. PRESOURCE pResource=NULL;
  2093. OTHERINFO sOI;
  2094. DeclareFindFromShadowOnNtVars()
  2095. PFDB pFdb = NULL;
  2096. if (!CSC_ENABLED)
  2097. {
  2098. lpSI->dwError = ERROR_SERVICE_NOT_ACTIVE;
  2099. return -1;
  2100. }
  2101. EnterShadowCrit();
  2102. UseGlobalFind32();
  2103. if (!lpDeleteCBForIoctl)
  2104. {
  2105. lpDeleteCBForIoctl = DeleteCallbackForFind;
  2106. }
  2107. uSrchFlags = FLAG_FINDSHADOW_META|FLAG_FINDSHADOW_NEWSTYLE
  2108. |((lpSI->uOp & FINDOPEN_SHADOWINFO_NORMAL)?FLAG_FINDSHADOW_ALLOW_NORMAL:0)
  2109. |((lpSI->uOp & FINDOPEN_SHADOWINFO_SPARSE)?FLAG_FINDSHADOW_ALLOW_SPARSE:0)
  2110. |((lpSI->uOp & FINDOPEN_SHADOWINFO_DELETED)?FLAG_FINDSHADOW_ALLOW_DELETED:0);
  2111. lpFSH = LpCreateFindShadow(lpSI->hDir, lpSI->lpFind32->dwFileAttributes
  2112. ,uSrchFlags
  2113. ,lpSI->lpFind32->cFileName, FsobjMMProc);
  2114. if (lpFSH)
  2115. {
  2116. if (FindOpenHSHADOW(lpFSH, &hTmp, &vsFind32, &(lpSI->uStatus), &sOI) >= SRET_OK)
  2117. {
  2118. CopyOtherInfoToShadowInfo(&sOI, lpSI);
  2119. if(GetAncestorsHSHADOW(hTmp, &(lpSI->hDir), &(lpSI->hShare)) < SRET_OK)
  2120. {
  2121. goto bailout;
  2122. }
  2123. *(lpSI->lpFind32) = vsFind32;
  2124. lpSI->hShadow = hTmp;
  2125. lpSI->uEnumCookie = (CSC_ENUMCOOKIE)lpFSH;
  2126. iRet = 1;
  2127. // check if this is a root
  2128. if(!lpFSH->hDir)
  2129. {
  2130. // the status bits we got are for the root
  2131. lpSI->uRootStatus = sOI.ulRootStatus;
  2132. // the server status is part of the otherinfo.
  2133. lpSI->uStatus = lpSI->uStatus;
  2134. if(pResource = PFindResourceFromRoot(lpSI->hShadow, 0xffff, 0))
  2135. {
  2136. IFNOT_CSC_RECORDMANAGER_WINNT
  2137. {
  2138. lpSI->uStatus |= ((pResource->usLocalFlags|SHARE_CONNECTED)|
  2139. ((pResource->pheadFdb)?SHARE_FILES_OPEN:0) |
  2140. ((pResource->pheadFindInfo) ?SHARE_FINDS_IN_PROGRESS:0));
  2141. lpSI->uOp = pResource->uDriveMap;
  2142. }
  2143. else
  2144. {
  2145. lpSI->uStatus |= MRxSmbCscGetSavedResourceStatus();
  2146. lpSI->uOp = MRxSmbCscGetSavedResourceDriveMap();
  2147. }
  2148. }
  2149. // UI expects to know whether a server is offline
  2150. // even when a share may not be offline. So we do the following drill anyways
  2151. {
  2152. #ifdef CSC_RECORDMANAGER_WINNT
  2153. BOOL fShareOnline = FALSE;
  2154. BOOL fPinnedOffline = FALSE;
  2155. // Leave Crit sec coz MRxSmbCscServerStateFromCompleteUNCPath may acquire SmbCeResource
  2156. LeaveShadowCrit();
  2157. if (MRxSmbCscServerStateFromCompleteUNCPath(
  2158. lpSI->lpFind32->cFileName,
  2159. &fShareOnline,
  2160. &fPinnedOffline)==STATUS_SUCCESS) {
  2161. if (!fShareOnline)
  2162. lpSI->uStatus |= SHARE_DISCONNECTED_OP;
  2163. if (fPinnedOffline)
  2164. lpSI->uStatus |= SHARE_PINNED_OFFLINE;
  2165. }
  2166. EnterShadowCrit();
  2167. #endif
  2168. }
  2169. }
  2170. else
  2171. {
  2172. // not a root, if this is a file and it is open
  2173. // let the caller know that
  2174. if (!(vsFind32.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  2175. {
  2176. lpSI->uStatus |= SHADOW_IS_FILE;
  2177. if (pFdb = PFindFdbFromHShadow(lpSI->hShadow))
  2178. {
  2179. lpSI->uStatus |= (SHADOW_FILE_IS_OPEN | pFdb->usFlags);
  2180. }
  2181. }
  2182. }
  2183. }
  2184. else
  2185. {
  2186. DestroyFindShadow(lpFSH);
  2187. }
  2188. }
  2189. if (hShareReint && (lpSI->hShare == hShareReint))
  2190. {
  2191. lpSI->uStatus |= SHARE_MERGING;
  2192. }
  2193. bailout:
  2194. if (iRet < 0)
  2195. {
  2196. lpSI->dwError = GetLastErrorLocal();
  2197. }
  2198. LeaveShadowCrit();
  2199. return(iRet);
  2200. }
  2201. int IoctlFindNextHSHADOW(
  2202. LPSHADOWINFO lpSI
  2203. )
  2204. /*++
  2205. Routine Description:
  2206. Parameters:
  2207. Return Value:
  2208. Notes:
  2209. --*/
  2210. {
  2211. int iRet=-1;
  2212. LPFINDSHADOW lpFSH = (LPFINDSHADOW)(lpSI->uEnumCookie);
  2213. LPFINDSHADOW lpFSHtmp = NULL;
  2214. HSHADOW hTmp;
  2215. PRESOURCE pResource=NULL;
  2216. OTHERINFO sOI;
  2217. PFDB pFdb = NULL;
  2218. DeclareFindFromShadowOnNtVars()
  2219. if (!CSC_ENABLED)
  2220. {
  2221. lpSI->dwError = ERROR_SERVICE_NOT_ACTIVE;
  2222. return -1;
  2223. }
  2224. EnterShadowCrit();
  2225. UseGlobalFind32();
  2226. if (lpFSH)
  2227. {
  2228. //
  2229. // Verify that the lpFSH is in fact one we gave out; ie it is on the
  2230. // vlpFindShadowList.
  2231. //
  2232. for (lpFSHtmp = vlpFindShadowList; lpFSHtmp; lpFSHtmp = lpFSHtmp->lpFSHNext) {
  2233. if (lpFSHtmp == lpFSH) {
  2234. break;
  2235. }
  2236. }
  2237. if (lpFSHtmp != lpFSH) {
  2238. SetLastErrorLocal(ERROR_INVALID_PARAMETER);
  2239. iRet = -1;
  2240. goto bailout;
  2241. }
  2242. // check if the directory has been deleted in the meanwhile
  2243. if (!(lpFSH->ulFlags & FLAG_FINDSHADOW_INVALID_DIRECTORY))
  2244. {
  2245. if (FindNextHSHADOW(lpFSH, &hTmp, &vsFind32, &(lpSI->uStatus), &sOI) >= SRET_OK)
  2246. {
  2247. CopyOtherInfoToShadowInfo(&sOI, lpSI);
  2248. if(GetAncestorsHSHADOW(hTmp, &(lpSI->hDir), &(lpSI->hShare)) < SRET_OK)
  2249. {
  2250. goto bailout;
  2251. }
  2252. *(lpSI->lpFind32) = vsFind32;
  2253. lpSI->hShadow = hTmp;
  2254. iRet = 1;
  2255. // check if this is a root
  2256. if(!lpFSH->hDir)
  2257. {
  2258. // the status bits we got are for the root
  2259. lpSI->uRootStatus = sOI.ulRootStatus;
  2260. // the server status is part of the otherinfo.
  2261. lpSI->uStatus = lpSI->uStatus;
  2262. if(pResource = PFindResourceFromRoot(lpSI->hShadow, 0xffff, 0))
  2263. {
  2264. IFNOT_CSC_RECORDMANAGER_WINNT
  2265. {
  2266. lpSI->uStatus |= ((pResource->usLocalFlags|SHARE_CONNECTED)|
  2267. ((pResource->pheadFdb)?SHARE_FILES_OPEN:0) |
  2268. ((pResource->pheadFindInfo) ?SHARE_FINDS_IN_PROGRESS:0));
  2269. lpSI->uOp = pResource->uDriveMap;
  2270. }
  2271. else
  2272. {
  2273. lpSI->uStatus |= MRxSmbCscGetSavedResourceStatus();
  2274. lpSI->uOp = MRxSmbCscGetSavedResourceDriveMap();
  2275. }
  2276. }
  2277. {
  2278. #ifdef CSC_RECORDMANAGER_WINNT
  2279. BOOL fShareOnline = FALSE;
  2280. BOOL fPinnedOffline = FALSE;
  2281. // Leave Crit sec coz MRxSmbCscServerStateFromCompleteUNCPath may acquire SmbCeResource
  2282. LeaveShadowCrit();
  2283. if (MRxSmbCscServerStateFromCompleteUNCPath(
  2284. lpSI->lpFind32->cFileName,
  2285. &fShareOnline,
  2286. &fPinnedOffline)==STATUS_SUCCESS) {
  2287. if (!fShareOnline)
  2288. lpSI->uStatus |= SHARE_DISCONNECTED_OP;
  2289. if (fPinnedOffline)
  2290. lpSI->uStatus |= SHARE_PINNED_OFFLINE;
  2291. }
  2292. EnterShadowCrit();
  2293. #endif
  2294. }
  2295. }
  2296. else
  2297. {
  2298. // not a root, if this is a file and it is open
  2299. // let the caller know that
  2300. if (!(vsFind32.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
  2301. {
  2302. lpSI->uStatus |= SHADOW_IS_FILE;
  2303. if (pFdb = PFindFdbFromHShadow(lpSI->hShadow))
  2304. {
  2305. // or in the latest known bits
  2306. lpSI->uStatus |= (SHADOW_FILE_IS_OPEN | pFdb->usFlags);
  2307. }
  2308. }
  2309. }
  2310. }
  2311. }
  2312. }
  2313. if (hShareReint && (lpSI->hShare == hShareReint))
  2314. {
  2315. lpSI->uStatus |= SHARE_MERGING;
  2316. }
  2317. bailout:
  2318. if (iRet < 0)
  2319. {
  2320. lpSI->dwError = GetLastErrorLocal();
  2321. }
  2322. LeaveShadowCrit();
  2323. return(iRet);
  2324. }
  2325. int IoctlFindCloseHSHADOW(
  2326. LPSHADOWINFO lpSI
  2327. )
  2328. /*++
  2329. Routine Description:
  2330. Parameters:
  2331. Return Value:
  2332. Notes:
  2333. --*/
  2334. {
  2335. int iRet = -1;
  2336. LPFINDSHADOW lpFSH = (LPFINDSHADOW)(lpSI->uEnumCookie);
  2337. if (!CSC_ENABLED)
  2338. {
  2339. lpSI->dwError = ERROR_SERVICE_NOT_ACTIVE;
  2340. return -1;
  2341. }
  2342. EnterShadowCrit();
  2343. if (lpFSH)
  2344. {
  2345. DestroyFindShadow(lpFSH);
  2346. iRet = 1;
  2347. }
  2348. LeaveShadowCrit();
  2349. return(iRet);
  2350. }
  2351. int IoctlFindOpenHint(
  2352. LPSHADOWINFO lpSI
  2353. )
  2354. /*++
  2355. Routine Description:
  2356. Parameters:
  2357. Return Value:
  2358. Notes:
  2359. --*/
  2360. {
  2361. int iRet=-1;
  2362. LPFINDSHADOW lpFSH;
  2363. OTHERINFO sOI;
  2364. HSHADOW hTmp;
  2365. if (!CSC_ENABLED)
  2366. {
  2367. return -1;
  2368. }
  2369. EnterShadowCrit();
  2370. UseGlobalFind32();
  2371. lpFSH = LpCreateFindShadow(lpSI->hDir, 0,
  2372. FLAG_FINDSHADOW_META|FLAG_FINDSHADOW_NEWSTYLE,
  2373. (lpSI->lpFind32->cFileName), HintobjMMProc);
  2374. if (lpFSH)
  2375. {
  2376. if (FindOpenHSHADOW(lpFSH, &hTmp, &vsFind32, &(lpSI->uStatus), &sOI) >= SRET_OK)
  2377. {
  2378. *(lpSI->lpFind32) = vsFind32;
  2379. // Find32AFromFind32((LPFIND32A)(lpSI->lpFind32), &vsFind32, BCS_WANSI);
  2380. CopyOtherInfoToShadowInfo(&sOI, lpSI);
  2381. lpSI->hShare = vsFind32.dwReserved0;
  2382. lpSI->hShadow = hTmp;
  2383. lpSI->uEnumCookie = (CSC_ENUMCOOKIE)lpFSH;
  2384. iRet = 1;
  2385. }
  2386. else
  2387. {
  2388. DestroyFindShadow(lpFSH);
  2389. }
  2390. }
  2391. LeaveShadowCrit();
  2392. return(iRet);
  2393. }
  2394. int IoctlFindNextHint(
  2395. LPSHADOWINFO lpSI
  2396. )
  2397. /*++
  2398. Routine Description:
  2399. Parameters:
  2400. Return Value:
  2401. Notes:
  2402. --*/
  2403. {
  2404. int iRet=-1;
  2405. LPFINDSHADOW lpFSH = (LPFINDSHADOW)(lpSI->uEnumCookie);
  2406. LPFINDSHADOW lpFSHtmp = NULL;
  2407. OTHERINFO sOI;
  2408. HSHADOW hTmp;
  2409. if (!CSC_ENABLED)
  2410. {
  2411. return -1;
  2412. }
  2413. EnterShadowCrit();
  2414. UseGlobalFind32();
  2415. if (lpFSH)
  2416. {
  2417. //
  2418. // Verify that the lpFSH is in fact one we gave out; ie it is on the
  2419. // vlpFindShadowList.
  2420. //
  2421. for (lpFSHtmp = vlpFindShadowList; lpFSHtmp; lpFSHtmp = lpFSHtmp->lpFSHNext) {
  2422. if (lpFSHtmp == lpFSH) {
  2423. break;
  2424. }
  2425. }
  2426. if (lpFSHtmp != lpFSH) {
  2427. iRet = -1;
  2428. goto AllDone;
  2429. }
  2430. if (FindNextHSHADOW(lpFSH, &hTmp, &vsFind32, &(lpSI->uStatus), &sOI) >= SRET_OK)
  2431. {
  2432. *(lpSI->lpFind32) = vsFind32;
  2433. // Find32AFromFind32((LPFIND32A)(lpSI->lpFind32), &vsFind32, BCS_WANSI);
  2434. lpSI->hShare = 0;
  2435. lpSI->hShadow = hTmp;
  2436. CopyOtherInfoToShadowInfo(&sOI, lpSI);
  2437. iRet = 1;
  2438. }
  2439. }
  2440. AllDone:
  2441. LeaveShadowCrit();
  2442. return(iRet);
  2443. }
  2444. int IoctlFindCloseHint(
  2445. LPSHADOWINFO lpSI
  2446. )
  2447. /*++
  2448. Routine Description:
  2449. Parameters:
  2450. Return Value:
  2451. Notes:
  2452. --*/
  2453. {
  2454. int iRet = -1;
  2455. LPFINDSHADOW lpFSH = (LPFINDSHADOW)(lpSI->uEnumCookie);
  2456. if (!CSC_ENABLED)
  2457. {
  2458. return -1;
  2459. }
  2460. EnterShadowCrit();
  2461. if (lpFSH)
  2462. {
  2463. DestroyFindShadow(lpFSH);
  2464. iRet = 1;
  2465. }
  2466. LeaveShadowCrit();
  2467. return(iRet);
  2468. }
  2469. int IoctlSetPriorityHSHADOW(
  2470. LPSHADOWINFO lpSI
  2471. )
  2472. /*++
  2473. Routine Description:
  2474. Parameters:
  2475. Return Value:
  2476. Notes:
  2477. --*/
  2478. {
  2479. int iRet=SRET_ERROR;
  2480. if (!CSC_ENABLED)
  2481. {
  2482. lpSI->dwError = ERROR_SERVICE_NOT_ACTIVE;
  2483. return -1;
  2484. }
  2485. EnterShadowCrit();
  2486. if (!FailModificationsToShare(lpSI))
  2487. {
  2488. iRet = SetPriorityHSHADOW(lpSI->hDir, lpSI->hShadow, lpSI->ulRefPri, lpSI->ulHintPri);
  2489. }
  2490. if (iRet < 0)
  2491. {
  2492. lpSI->dwError = GetLastErrorLocal();
  2493. }
  2494. LeaveShadowCrit();
  2495. return ((iRet >= SRET_OK)?1:-1);
  2496. }
  2497. int IoctlGetPriorityHSHADOW(
  2498. LPSHADOWINFO lpSI
  2499. )
  2500. /*++
  2501. Routine Description:
  2502. Parameters:
  2503. Return Value:
  2504. Notes:
  2505. --*/
  2506. {
  2507. int iRet;
  2508. if (!CSC_ENABLED)
  2509. {
  2510. lpSI->dwError = ERROR_SERVICE_NOT_ACTIVE;
  2511. return -1;
  2512. }
  2513. EnterShadowCrit();
  2514. iRet = GetPriorityHSHADOW(lpSI->hDir, lpSI->hShadow, &(lpSI->ulRefPri), &(lpSI->ulHintPri));
  2515. if (iRet < 0)
  2516. {
  2517. lpSI->dwError = GetLastErrorLocal();
  2518. }
  2519. LeaveShadowCrit();
  2520. return ((iRet >= SRET_OK)?1:-1);
  2521. }
  2522. int IoctlGetAliasHSHADOW(
  2523. LPSHADOWINFO lpSI
  2524. )
  2525. /*++
  2526. Routine Description:
  2527. Parameters:
  2528. Return Value:
  2529. Notes:
  2530. --*/
  2531. {
  2532. int iRet;
  2533. HSHADOW hShadow, hDir;
  2534. if (!CSC_ENABLED)
  2535. {
  2536. return -1;
  2537. }
  2538. EnterShadowCrit();
  2539. iRet = GetRenameAliasHSHADOW(lpSI->hDir, lpSI->hShadow
  2540. , &hDir, &hShadow);
  2541. lpSI->hDir = hDir;
  2542. lpSI->hShadow = hShadow;
  2543. LeaveShadowCrit();
  2544. return ((iRet >= SRET_OK)?1:-1);
  2545. }
  2546. LPFINDSHADOW LpCreateFindShadow(
  2547. HSHADOW hDir,
  2548. ULONG uAttrib,
  2549. ULONG uSrchFlags,
  2550. USHORT *lpPattern,
  2551. METAMATCHPROC lpfnMMProc
  2552. )
  2553. /*++
  2554. Routine Description:
  2555. Parameters:
  2556. Return Value:
  2557. Notes:
  2558. --*/
  2559. {
  2560. int len;
  2561. LPFINDSHADOW lpFSH;
  2562. //
  2563. // Limit # outstanding FindOpens/HintOpens
  2564. //
  2565. if (vuFindShadowListCount >= 128) {
  2566. return NULL;
  2567. }
  2568. len = wstrlen(lpPattern);
  2569. lpFSH = (LPFINDSHADOW)AllocMem(sizeof(FINDSHADOW)+(len+1)*sizeof(USHORT));
  2570. if (lpFSH)
  2571. {
  2572. lpFSH->lpPattern = (USHORT *)((UCHAR *)lpFSH + sizeof(FINDSHADOW));
  2573. memcpy(lpFSH->lpPattern, lpPattern, (len+1)*sizeof(USHORT));
  2574. // BCSToUni(lpFSH->lpPattern, lpPattern, len, BCS_WANSI);
  2575. // Convert the patterns to uppercase, as demanded by metamatch
  2576. UniToUpper(lpFSH->lpPattern, lpFSH->lpPattern, len*sizeof(USHORT));
  2577. lpFSH->hDir = hDir;
  2578. lpFSH->uAttrib = uAttrib;
  2579. lpFSH->uSrchFlags = uSrchFlags;
  2580. lpFSH->lpfnMMProc = lpfnMMProc;
  2581. // link this in the list of outstanding ioctl finds
  2582. lpFSH->lpFSHNext = vlpFindShadowList;
  2583. vlpFindShadowList = lpFSH;
  2584. vuFindShadowListCount++;
  2585. ASSERT(vuFindShadowListCount <= 128);
  2586. }
  2587. return (lpFSH);
  2588. }
  2589. int DestroyFindShadow(
  2590. LPFINDSHADOW lpFSH
  2591. )
  2592. /*++
  2593. Routine Description:
  2594. Parameters:
  2595. Return Value:
  2596. Notes:
  2597. --*/
  2598. {
  2599. int iRet = -1;
  2600. LPFINDSHADOW *lplpFSHT;
  2601. if (lpFSH)
  2602. {
  2603. for (lplpFSHT = &vlpFindShadowList; *lplpFSHT; lplpFSHT = &((*lplpFSHT)->lpFSHNext))
  2604. {
  2605. if (*lplpFSHT == lpFSH)
  2606. {
  2607. *lplpFSHT = lpFSH->lpFSHNext;
  2608. FreeMem(lpFSH);
  2609. vuFindShadowListCount--;
  2610. ASSERT(vuFindShadowListCount >= 0);
  2611. iRet = 1;
  2612. break;
  2613. }
  2614. }
  2615. }
  2616. return (iRet);
  2617. }
  2618. int
  2619. DeleteCallbackForFind(
  2620. HSHADOW hDir,
  2621. HSHADOW hShadow
  2622. )
  2623. /*++
  2624. Routine Description:
  2625. Parameters:
  2626. Return Value:
  2627. Notes:
  2628. --*/
  2629. {
  2630. LPFINDSHADOW lpFSH;
  2631. int iRet = 0;
  2632. for (lpFSH = vlpFindShadowList; lpFSH ; lpFSH = lpFSH->lpFSHNext)
  2633. {
  2634. if (lpFSH->hDir == hShadow)
  2635. {
  2636. lpFSH->ulFlags |= FLAG_FINDSHADOW_INVALID_DIRECTORY;
  2637. ++iRet;
  2638. }
  2639. }
  2640. return iRet;
  2641. }
  2642. int HintobjMMProc( LPFIND32 lpFind32,
  2643. HSHADOW hDir,
  2644. HSHADOW hShadow,
  2645. ULONG uStatus,
  2646. LPOTHERINFO lpOI,
  2647. LPFINDSHADOW lpFSH
  2648. )
  2649. /*++
  2650. Routine Description:
  2651. Parameters:
  2652. Return Value:
  2653. Notes:
  2654. --*/
  2655. {
  2656. int iRet;
  2657. iRet = MM_RET_CONTINUE; // Continue
  2658. hDir;
  2659. if (mIsHint(lpOI->ulHintFlags)&&
  2660. IFSMgr_MetaMatch(lpFSH->lpPattern, lpFind32->cFileName,UFLG_NT|UFLG_META))
  2661. iRet = MM_RET_FOUND_BREAK;
  2662. return (iRet);
  2663. }
  2664. #ifdef MAYBE
  2665. int RecalcIHPri( HSHADOW hDir,
  2666. HSHADOW hShadow,
  2667. LPFIND32 lpFind32,
  2668. LPOTHERINFO lpOI
  2669. )
  2670. {
  2671. USHORT *lpuType=NULL;
  2672. int len, iRet=SRET_ERROR;
  2673. SHADOWCHECK sSC;
  2674. HSHADOW hChild, hParent;
  2675. ULONG ulFlagsIn, uStatus;
  2676. if (GetShadowInfo(hParent = hDir, hChild = hShadow, lpFind32, &uStatus, NULL) != SRET_OK)
  2677. goto bailout;
  2678. len = wstrlen(lpFind32->cFileName)*2;
  2679. if (!(lpuType = (USHORT *)AllocMem(len+2)))
  2680. goto bailout;
  2681. memcpy(lpuType, lpFind32->cFileName, len);
  2682. memset(lpOI, 0, sizeof(OTHERINFO));
  2683. do
  2684. {
  2685. memset(&sSC, 0, sizeof(SHADOWCHECK));
  2686. sSC.lpuName = (USHORT *)hChild;
  2687. sSC.lpuType = lpuType;
  2688. sSC.uFlagsIn = ulFlagsIn;
  2689. MetaMatchInit(&(sSC.ulCookie));
  2690. if (MetaMatch(hParent, lpFind32, &(sSC.ulCookie), &hChild
  2691. , &uStatus, NULL
  2692. , GetShadowWithChecksProc
  2693. , &sSC)!=SRET_OK)
  2694. goto bailout;
  2695. if (mIsHint(sSC.ulHintFlags))
  2696. {
  2697. if (mHintExclude(sSC.ulHintFlags) || (lpOI->ulIHPri < sSC.ulHintPri))
  2698. {
  2699. lpOI->ulHintFlags = sSC.ulHintFlags;
  2700. lpOI->ulIHPri = sSC.ulHintPri;
  2701. }
  2702. // If we find an exclusion hint here, we need to quit
  2703. // because this is the closest exclusion hint we got
  2704. if (mHintExclude(sSC.ulHintFlags))
  2705. break;
  2706. }
  2707. if (!hParent)
  2708. break;
  2709. hChild = hParent;
  2710. GetAncestorsHSHADOW(hChild, &hParent, NULL);
  2711. // Start checking the subtree hints
  2712. ulFlagsIn = FLAG_IN_SHADOWCHECK_SUBTREE;
  2713. }
  2714. while (TRUE);
  2715. iRet = SRET_OK;
  2716. bailout:
  2717. if (lpuType)
  2718. {
  2719. FreeMem(lpuType);
  2720. }
  2721. return (iRet);
  2722. }
  2723. #endif //MAYBE
  2724. int SetResourceFlags(
  2725. HSHARE hShare,
  2726. ULONG uStatus,
  2727. ULONG uOp
  2728. )
  2729. /*++
  2730. Routine Description:
  2731. Parameters:
  2732. Return Value:
  2733. Notes:
  2734. --*/
  2735. {
  2736. #ifndef CSC_RECORDMANAGER_WINNT
  2737. PRESOURCE pResource;
  2738. if(pResource = PFindResourceFromHShare(hShare, 0xffff, 0))
  2739. {
  2740. switch (mBitOpShadowFlags(uOp))
  2741. {
  2742. case SHADOW_FLAGS_ASSIGN:
  2743. pResource->usFlags = (USHORT)uStatus;
  2744. break;
  2745. case SHADOW_FLAGS_OR:
  2746. pResource->usFlags |= (USHORT)uStatus;
  2747. break;
  2748. case SHADOW_FLAGS_AND:
  2749. pResource->usFlags &= (USHORT)uStatus;
  2750. break;
  2751. }
  2752. }
  2753. #else
  2754. //on NT, we just make the one call, if it can't find it, then
  2755. //it just does nothing......
  2756. DeclareFindFromShadowOnNtVars()
  2757. PSetResourceStatusFromHShare(hShare, 0xffff, 0, uStatus, uOp);
  2758. #endif //ifndef CSC_RECORDMANAGER_WINNT
  2759. return(0); //stop complaining about no return value
  2760. }
  2761. int PUBLIC MakeSpace(
  2762. long nFileSizeHigh,
  2763. long nFileSizeLow,
  2764. BOOL fClearPinned
  2765. )
  2766. /*++
  2767. Routine Description:
  2768. Parameters:
  2769. Return Value:
  2770. Notes:
  2771. --*/
  2772. {
  2773. CSC_ENUMCOOKIE hPQ;
  2774. PQPARAMS sPQP;
  2775. int iRet = SRET_ERROR;
  2776. SHADOWSTORE sShdStr;
  2777. ULONG uSize = 0;
  2778. ULONG uSizeIn;
  2779. ULONG ulStartSeconds;
  2780. DEBUG_LOG(RECORD, ("Begin MakeSpace\r\n"));
  2781. ulStartSeconds = GetTimeInSecondsSince1970();
  2782. Win32ToDosFileSize(nFileSizeHigh, nFileSizeLow, &uSizeIn);
  2783. // DbgPrint("Begin Makespace(%d)\n", uSizeIn);
  2784. if (GetShadowSpaceInfo(&sShdStr) < SRET_OK) {
  2785. DbgPrint("MakeSpace: GetShadowSpaceInfo error\n");
  2786. return SRET_ERROR;
  2787. }
  2788. // DbgPrint(" Before cleanup, max=%d cur=%d\n",
  2789. // sShdStr.sMax.ulSize,
  2790. // sShdStr.sCur.ulSize);
  2791. if (
  2792. (sShdStr.sMax.ulSize > sShdStr.sCur.ulSize)
  2793. &&
  2794. ((sShdStr.sMax.ulSize - sShdStr.sCur.ulSize) > uSizeIn)
  2795. ) {
  2796. // DbgPrint("Makespace exit (nothing to do)\n");
  2797. return SRET_OK;
  2798. }
  2799. // Open the priority q
  2800. if (!(hPQ = HBeginPQEnum())) {
  2801. DbgPrint("MakeSpace: Error opening Priority Q database\n");
  2802. return SRET_ERROR;
  2803. }
  2804. memset(&sPQP, 0, sizeof(PQPARAMS));
  2805. sPQP.uEnumCookie = hPQ;
  2806. //
  2807. // go down the Q once
  2808. //
  2809. do {
  2810. if (PrevPriSHADOW(&sPQP) < SRET_OK) {
  2811. // DbgPrint(" PQ record read error\n");
  2812. break;
  2813. }
  2814. if (sPQP.hShadow == 0)
  2815. break;
  2816. // Nuke only the files and only those which are not open
  2817. // and are not pinned
  2818. if (
  2819. !mNotFsobj(sPQP.ulStatus) // It is a file system object
  2820. &&
  2821. (sPQP.ulStatus & SHADOW_IS_FILE) // It is a file
  2822. &&
  2823. // told to clear pinned or it is not pinned
  2824. (fClearPinned || !(sPQP.ulHintPri || mPinFlags(sPQP.ulHintFlags)))
  2825. &&
  2826. !mShadowNeedReint(sPQP.ulStatus) // It is not in use or is not dirty
  2827. ) {
  2828. if (PFindFdbFromHShadow(sPQP.hShadow)) {
  2829. // DbgPrint(" Skipping busy shadow (0x%x)\n", sPQP.hShadow);
  2830. continue;
  2831. }
  2832. if(DeleteShadowHelper(FALSE, sPQP.hDir, sPQP.hShadow) < SRET_OK) {
  2833. // DbgPrint(" error Deleting shadow %x\n", sPQP.hShadow);
  2834. break;
  2835. }
  2836. // get the latest data on how much space there is.
  2837. // this takes care of rounding up the size to the cluster
  2838. if (GetShadowSpaceInfo(&sShdStr) < SRET_OK) {
  2839. // DbgPrint(" error reading space status\n");
  2840. break;
  2841. }
  2842. // DbgPrint(" Deleted shadow 0x%x Cur=%d\n",
  2843. // sPQP.hShadow,
  2844. // sShdStr.sCur.ulSize);
  2845. if (
  2846. (sShdStr.sMax.ulSize > sShdStr.sCur.ulSize)
  2847. &&
  2848. ((sShdStr.sMax.ulSize - sShdStr.sCur.ulSize)>uSizeIn)
  2849. ) {
  2850. // DbgPrint(" Makespace exit (done enough)\n");
  2851. iRet = SRET_OK;
  2852. break;
  2853. }
  2854. } else {
  2855. // DbgPrint(" Skip 0x%x\n", sPQP.hShadow);
  2856. }
  2857. #if 0
  2858. if ((int)( GetTimeInSecondsSince1970() - ulStartSeconds) > 30) {
  2859. DbgPrint(" Aborting, have been in for more than 30 seconds\r\n");
  2860. break;
  2861. }
  2862. #endif
  2863. } while (sPQP.uPos);
  2864. if (hPQ)
  2865. EndPQEnum(hPQ);
  2866. DEBUG_LOG(RECORD, ("End MakeSpace\r\n"));
  2867. // DbgPrint("Makespace alldone exit %d (Max=%d Cur=%d)\n",
  2868. // iRet,
  2869. // sShdStr.sMax.ulSize,
  2870. // sShdStr.sCur.ulSize);
  2871. return (iRet);
  2872. }
  2873. LONG
  2874. PurgeUnpinnedFiles(
  2875. ULONG Timeout,
  2876. PULONG pnFiles,
  2877. PULONG pnYoungFiles)
  2878. {
  2879. CSC_ENUMCOOKIE hPQ;
  2880. PQPARAMS sPQP;
  2881. ULONG nFiles = 0;
  2882. ULONG nYoungFiles = 0;
  2883. int iRet = SRET_ERROR;
  2884. // DbgPrint("Begin PurgeUnpinnedFiles(%d)\n", Timeout);
  2885. // Open the priority q
  2886. hPQ = HBeginPQEnum();
  2887. if (!hPQ) {
  2888. // DbgPrint("PurgeUnpinnedFiles: Error opening Priority Q database\n");
  2889. return iRet;
  2890. }
  2891. memset(&sPQP, 0, sizeof(PQPARAMS));
  2892. sPQP.uEnumCookie = hPQ;
  2893. iRet = SRET_OK;
  2894. do {
  2895. SHAREINFO ShareInfo;
  2896. SHADOWINFO ShadowInfo;
  2897. OTHERINFO OtherInfo;
  2898. WIN32_FIND_DATA Find32;
  2899. ULONG Status;
  2900. ULONG cStatus;
  2901. ULONG NowSec;
  2902. ULONG FileSec;
  2903. LARGE_INTEGER TimeNow;
  2904. LARGE_INTEGER FileTime;
  2905. iRet = PrevPriSHADOW(&sPQP);
  2906. if (iRet < SRET_OK) {
  2907. // DbgPrint(" PQ record read error\n");
  2908. break;
  2909. }
  2910. if (sPQP.hShadow == 0)
  2911. break;
  2912. // Nuke only the files and only those which are not open
  2913. // and are not pinned
  2914. if (
  2915. mNotFsobj(sPQP.ulStatus) != 0
  2916. ||
  2917. mShadowIsFile(sPQP.hShadow) != SHADOW_IS_FILE
  2918. ||
  2919. mPinFlags(sPQP.ulHintFlags) != 0
  2920. ||
  2921. mShadowNeedReint(sPQP.ulStatus) != 0
  2922. ) {
  2923. // DbgPrint(" Skip(1) (0x%x)\n", sPQP.hShadow);
  2924. continue;
  2925. }
  2926. //
  2927. // See if on manually cached share
  2928. //
  2929. iRet = GetShareInfo(sPQP.hShare, &ShareInfo, &ShadowInfo);
  2930. if (iRet != SRET_OK) {
  2931. // DbgPrint(" GetShareInfo(0x%x) returned %d\n", sPQP.hShare, GetLastErrorLocal());
  2932. continue;
  2933. }
  2934. cStatus = ShadowInfo.uStatus & FLAG_CSC_SHARE_STATUS_CACHING_MASK;
  2935. if (cStatus != FLAG_CSC_SHARE_STATUS_MANUAL_REINT) {
  2936. // DbgPrint(" Skip(2) (0x%x)\n", sPQP.hShadow);
  2937. continue;
  2938. }
  2939. iRet = GetShadowInfo(sPQP.hDir, sPQP.hShadow, &Find32, &Status, &OtherInfo);
  2940. if (iRet != SRET_OK) {
  2941. // DbgPrint(" GetShadowInfo(0x%x/0x%x) returned %d\n",
  2942. // sPQP.hDir,
  2943. // sPQP.hShadow,
  2944. // GetLastErrorLocal());
  2945. continue;
  2946. }
  2947. // DbgPrint(" Name:%ws Size:0x%x Attr:0x%x ",
  2948. // Find32.cFileName,
  2949. // Find32.nFileSizeLow,
  2950. // Find32.dwFileAttributes);
  2951. KeQuerySystemTime(&TimeNow);
  2952. COPY_STRUCTFILETIME_TO_LARGEINTEGER(FileTime, Find32.ftLastAccessTime);
  2953. RtlTimeToSecondsSince1970(&TimeNow, &NowSec);
  2954. RtlTimeToSecondsSince1970(&FileTime, &FileSec);
  2955. if (
  2956. PFindFdbFromHShadow(sPQP.hShadow) == NULL
  2957. &&
  2958. (Timeout == 0 || (NowSec > FileSec && (NowSec - FileSec) > Timeout))
  2959. ) {
  2960. // DbgPrint(" YES!!! ");
  2961. if (DeleteShadowHelper(FALSE, sPQP.hDir, sPQP.hShadow) >= SRET_OK) {
  2962. // DbgPrint("-Delete succeeded\n");
  2963. nFiles++;
  2964. } else {
  2965. // DbgPrint("-Error (%d) deleting shadow 0x%x/0x%x\n",
  2966. // GetLastErrorLocal(),
  2967. // sPQP.hDir,
  2968. // sPQP.hShadow);
  2969. }
  2970. } else {
  2971. // DbgPrint(" NO!!!\n");
  2972. nYoungFiles++;
  2973. }
  2974. } while (sPQP.uPos);
  2975. EndPQEnum(hPQ);
  2976. if (iRet >= SRET_OK) {
  2977. *pnFiles = nFiles;
  2978. *pnYoungFiles = nYoungFiles;
  2979. }
  2980. // DbgPrint("PurgeUnpinnedFiles exit %d (nFiles=%d nYoungFiles=%d)\n",
  2981. // iRet,
  2982. // *pnFiles,
  2983. // *pnYoungFiles);
  2984. return (iRet);
  2985. }
  2986. int
  2987. PUBLIC TraversePQToCheckDirtyBits(
  2988. HSHARE hShare,
  2989. DWORD *lpcntDirty
  2990. )
  2991. /*++
  2992. Routine Description:
  2993. Parameters:
  2994. Return Value:
  2995. Notes:
  2996. --*/
  2997. {
  2998. CSC_ENUMCOOKIE hPQ;
  2999. PQPARAMS sPQP;
  3000. int iRet = SRET_ERROR;
  3001. ULONG ulStartSeconds;
  3002. *lpcntDirty = 0;
  3003. ulStartSeconds = GetTimeInSecondsSince1970();
  3004. // Open the priority q
  3005. if (!(hPQ = HBeginPQEnum()))
  3006. {
  3007. AssertSz(FALSE, "CSC.TraversePQToCheckDirty:: Error opening Priority Q database\r\n");
  3008. return SRET_ERROR;
  3009. }
  3010. memset(&sPQP, 0, sizeof(PQPARAMS));
  3011. sPQP.uEnumCookie = hPQ;
  3012. // go down the Q once
  3013. do
  3014. {
  3015. if(NextPriSHADOW(&sPQP) < SRET_OK)
  3016. {
  3017. AssertSz(FALSE, "CSC.TraversePQToCheckDirty:: PQ record read error\r\n");
  3018. goto bailout;
  3019. }
  3020. if (!sPQP.hShadow)
  3021. {
  3022. continue;
  3023. }
  3024. if ((sPQP.hShare == hShare) // this share
  3025. && !mNotFsobj(sPQP.ulStatus) // It is a file system object
  3026. )
  3027. {
  3028. if(sPQP.ulStatus & SHADOW_MODFLAGS)
  3029. {
  3030. ++*lpcntDirty;
  3031. }
  3032. }
  3033. if ((int)( GetTimeInSecondsSince1970() - ulStartSeconds) > 30)
  3034. {
  3035. KdPrint(("CSC.TraversePQToCheckDirty: Aborting, have been in for more than 30 seconds\r\n"));
  3036. goto bailout;
  3037. }
  3038. }
  3039. while (sPQP.uPos);
  3040. iRet = SRET_OK;
  3041. bailout:
  3042. if (hPQ)
  3043. EndPQEnum(hPQ);
  3044. return (iRet);
  3045. }
  3046. int PUBLIC ReduceRefPri(
  3047. VOID
  3048. )
  3049. /*++
  3050. Routine Description:
  3051. Parameters:
  3052. Return Value:
  3053. Notes:
  3054. --*/
  3055. {
  3056. CSC_ENUMCOOKIE hPQ;
  3057. PQPARAMS sPQP;
  3058. int iRet = SRET_ERROR;
  3059. OTHERINFO sOI;
  3060. // Open the priority q
  3061. if (!(hPQ = HBeginPQEnum()))
  3062. {
  3063. // AssertSz(FALSE, "ReduceRefPri: Error opening Priority Q database\r\n");
  3064. return SRET_ERROR;
  3065. }
  3066. memset(&sPQP, 0, sizeof(PQPARAMS));
  3067. sPQP.uEnumCookie = hPQ;
  3068. do
  3069. {
  3070. if(PrevPriSHADOW(&sPQP) < SRET_OK)
  3071. {
  3072. goto bailout;
  3073. }
  3074. if (!sPQP.hShadow)
  3075. break;
  3076. if (!mNotFsobj(sPQP.ulStatus))
  3077. {
  3078. if (!(sPQP.ulStatus & SHADOW_IS_FILE))
  3079. continue;
  3080. InitOtherInfo(&sOI);
  3081. if (sPQP.ulRefPri > 1)
  3082. {
  3083. sOI.ulRefPri = sPQP.ulRefPri-1;
  3084. ChangePriEntryStatusHSHADOW(sPQP.hDir, sPQP.hShadow, 0, SHADOW_FLAGS_OR, TRUE, &sOI);
  3085. }
  3086. }
  3087. }
  3088. while (sPQP.uPos);
  3089. iRet = SRET_OK;
  3090. bailout:
  3091. if (hPQ)
  3092. EndPQEnum(hPQ);
  3093. return (iRet);
  3094. }
  3095. BOOL HaveSpace(
  3096. long nFileSizeHigh,
  3097. long nFileSizeLow
  3098. )
  3099. /*++
  3100. Routine Description:
  3101. Parameters:
  3102. Return Value:
  3103. Notes:
  3104. --*/
  3105. {
  3106. SHADOWSTORE sShdStr;
  3107. ULONG uSizeIn;
  3108. Win32ToDosFileSize(nFileSizeHigh, nFileSizeLow, &uSizeIn);
  3109. if (!uSizeIn)
  3110. {
  3111. return TRUE;
  3112. }
  3113. if (GetShadowSpaceInfo(&sShdStr) < SRET_OK)
  3114. {
  3115. return SRET_ERROR;
  3116. }
  3117. if (((sShdStr.sMax.ulSize - sShdStr.sCur.ulSize) >= uSizeIn))
  3118. {
  3119. return TRUE;
  3120. }
  3121. return FALSE;
  3122. }
  3123. int
  3124. IoctlAddDeleteHintFromInode(
  3125. LPSHADOWINFO lpSI,
  3126. BOOL fAdd
  3127. )
  3128. /*++
  3129. Routine Description:
  3130. Parameters:
  3131. Return Value:
  3132. Notes:
  3133. --*/
  3134. {
  3135. OTHERINFO sOI;
  3136. unsigned uStatus;
  3137. int iRet = -1;
  3138. if(GetShadowInfo(lpSI->hDir, lpSI->hShadow, NULL, &uStatus, &sOI) >= SRET_OK)
  3139. {
  3140. if (fAdd)
  3141. {
  3142. // increment the pin count if no flags to be altered or we are supposed to alter pin count
  3143. if (!(lpSI->ulHintFlags) || mPinAlterCount(lpSI->ulHintFlags))
  3144. {
  3145. sOI.ulHintPri++;
  3146. }
  3147. sOI.ulHintFlags |= lpSI->ulHintFlags;
  3148. if (sOI.ulHintPri > MAX_PRI)
  3149. {
  3150. lpSI->dwError = ERROR_INVALID_PARAMETER;
  3151. goto bailout;
  3152. }
  3153. }
  3154. else
  3155. {
  3156. sOI.ulHintFlags &= (~lpSI->ulHintFlags);
  3157. // decrement the pin count if no flags to be altered or we are supposed to alter pin count
  3158. if (!(lpSI->ulHintFlags) || mPinAlterCount(lpSI->ulHintFlags))
  3159. {
  3160. if (sOI.ulHintPri == MIN_PRI)
  3161. {
  3162. lpSI->dwError = ERROR_INVALID_PARAMETER;
  3163. goto bailout;
  3164. }
  3165. --sOI.ulHintPri;
  3166. }
  3167. }
  3168. if (SetShadowInfoEx(lpSI->hDir, lpSI->hShadow, NULL, 0, SHADOW_FLAGS_OR, &sOI, NULL, NULL) >= SRET_OK)
  3169. {
  3170. lpSI->ulHintFlags = sOI.ulHintFlags;
  3171. lpSI->ulHintPri = sOI.ulHintPri;
  3172. iRet = 1;
  3173. }
  3174. else
  3175. {
  3176. lpSI->dwError = ERROR_WRITE_FAULT;
  3177. }
  3178. }
  3179. bailout:
  3180. return (iRet);
  3181. }
  3182. int
  3183. IoctlCopyShadow(
  3184. LPSHADOWINFO lpSI
  3185. )
  3186. /*++
  3187. Routine Description:
  3188. Parameters:
  3189. Return Value:
  3190. Notes:
  3191. --*/
  3192. {
  3193. PFDB pFdb=NULL;
  3194. USHORT *pusLocal;
  3195. int iRet=-1;
  3196. // the shadowcritical section is already taken
  3197. iRet = CopyHSHADOW(lpSI->hDir, lpSI->hShadow, ((LPFIND32A)(lpSI->lpFind32))->cFileName, lpSI->lpFind32->dwFileAttributes);
  3198. if (iRet >= SRET_ERROR)
  3199. {
  3200. pFdb = PFindFdbFromHShadow(lpSI->hShadow);
  3201. if (pFdb)
  3202. {
  3203. pusLocal = PLocalFlagsFromPFdb(pFdb);
  3204. Assert(pusLocal);
  3205. if (pFdb->usFlags & SHADOW_DIRTY)
  3206. {
  3207. // set the snapshotted bit.
  3208. // If by the time the file is closed, the snapshotted bit is still set
  3209. // it is transferred back to SHADOW_DIRTY in disconnected state.
  3210. // it is the job of the SetShadowInfo ioctl to clear the
  3211. // snapshotted bit when the agent is coming down to
  3212. // clear the modified bits on the shadow after
  3213. // reintegration
  3214. pFdb->usFlags &= ~SHADOW_DIRTY;
  3215. *pusLocal |= FLAG_FDB_SHADOW_SNAPSHOTTED;
  3216. }
  3217. }
  3218. }
  3219. else
  3220. {
  3221. lpSI->dwError = GetLastErrorLocal();
  3222. }
  3223. return iRet;
  3224. }
  3225. int
  3226. IoctlChangeHandleCachingState(
  3227. LPSHADOWINFO lpSI
  3228. )
  3229. /*++
  3230. Routine Description:
  3231. Parameters:
  3232. lpSI SHADOWINFO structure pointer.
  3233. If lpSI->uStatus is FALSE, then handle caching is disabled, else it is enabled
  3234. Return Value:
  3235. Notes:
  3236. --*/
  3237. {
  3238. lpSI->uStatus = EnableHandleCaching(lpSI->uStatus != FALSE);
  3239. return 1;
  3240. }
  3241. int
  3242. IoctlRenameShadow(
  3243. LPSHADOWINFO lpSI
  3244. )
  3245. /*++
  3246. Routine Description:
  3247. Given a source Inode, rename it into a destination directory. The source and the
  3248. destination can be across shares
  3249. Parameters:
  3250. lpSI SHADOWINFO structure pointer.
  3251. Return Value:
  3252. Notes:
  3253. Shadow ciritcal section is already taken
  3254. --*/
  3255. {
  3256. int iRet=-1;
  3257. ULONG uStatus, uStatusDest;
  3258. HSHARE hShare;
  3259. HSHADOW hShadowTo;
  3260. BOOL fReplaceFile = (lpSI->uStatus != 0); // yuk
  3261. UseGlobalFind32();
  3262. lpSI->dwError = ERROR_SUCCESS;
  3263. // get the name of the shadow
  3264. if (GetShadowInfo(lpSI->hDir, lpSI->hShadow, &vsFind32, &uStatus, NULL) >= 0)
  3265. {
  3266. // if it is open, bail
  3267. if (PFindFdbFromHShadow(lpSI->hShadow))
  3268. {
  3269. SetLastErrorLocal(ERROR_ACCESS_DENIED);
  3270. }
  3271. else
  3272. {
  3273. if (lpSI->lpFind32)
  3274. {
  3275. vsFind32 = *lpSI->lpFind32;
  3276. vsFind32.cAlternateFileName[0] = 0;
  3277. MRxSmbCscGenerate83NameAsNeeded(lpSI->hDirTo,vsFind32.cFileName,vsFind32.cAlternateFileName);
  3278. }
  3279. // check if it already exists in the destination directory
  3280. if ((GetShadow( lpSI->hDirTo,
  3281. vsFind32.cFileName,
  3282. &hShadowTo, NULL,
  3283. &uStatusDest, NULL) >= 0) && hShadowTo)
  3284. {
  3285. // try deleting if we are supposed to replace it
  3286. if (fReplaceFile)
  3287. {
  3288. if (DeleteShadow(lpSI->hDirTo, hShadowTo)< SRET_OK)
  3289. {
  3290. lpSI->dwError = GetLastErrorLocal();
  3291. Assert(lpSI->dwError != ERROR_SUCCESS);
  3292. }
  3293. }
  3294. else
  3295. {
  3296. SetLastErrorLocal(ERROR_FILE_EXISTS);
  3297. }
  3298. }
  3299. if (lpSI->dwError == ERROR_SUCCESS)
  3300. {
  3301. // just in case this is a rename across shares, get the handle to the share
  3302. if (GetAncestorsHSHADOW(lpSI->hDirTo, NULL, &hShare) >= 0)
  3303. {
  3304. // do the rename
  3305. iRet = RenameShadowEx(
  3306. lpSI->hDir,
  3307. lpSI->hShadow,
  3308. hShare,
  3309. lpSI->hDirTo,
  3310. &vsFind32,
  3311. uStatus,
  3312. NULL,
  3313. 0,
  3314. NULL,
  3315. NULL,
  3316. &lpSI->hShadow
  3317. );
  3318. if (iRet < 0)
  3319. {
  3320. lpSI->dwError = GetLastErrorLocal();
  3321. }
  3322. }
  3323. else
  3324. {
  3325. lpSI->dwError = GetLastErrorLocal();
  3326. }
  3327. }
  3328. }
  3329. }
  3330. else
  3331. {
  3332. SetLastErrorLocal(ERROR_FILE_NOT_FOUND);
  3333. }
  3334. return ((iRet >= SRET_OK)?1:-1);
  3335. }
  3336. int IoctlEnableCSCForUser(
  3337. LPSHADOWINFO lpSI
  3338. )
  3339. /*++
  3340. Routine Description:
  3341. Parameters:
  3342. lpSI SHADOWINFO structure pointer.
  3343. Return Value:
  3344. -1
  3345. Notes:
  3346. --*/
  3347. {
  3348. int iRet = SRET_ERROR;
  3349. EnterShadowCrit();
  3350. if (fShadow)
  3351. {
  3352. lpSI->dwError = 0;
  3353. iRet = SRET_OK;
  3354. }
  3355. else
  3356. {
  3357. if (OK_TO_ENABLE_CSC)
  3358. {
  3359. Assert(lpSI->lpFind32);
  3360. //
  3361. // Check that cFileName and cAlternateFileName contain a NULL
  3362. //
  3363. if (CscCheckForNullA(((LPFIND32A)(lpSI->lpFind32))->cFileName, MAX_PATH) == FALSE) {
  3364. lpSI->dwError = ERROR_INVALID_PARAMETER;
  3365. LeaveShadowCrit();
  3366. return -1;
  3367. }
  3368. if (CscCheckForNullA(((LPFIND32A)(lpSI->lpFind32))->cAlternateFileName, 14) == FALSE) {
  3369. lpSI->dwError = ERROR_INVALID_PARAMETER;
  3370. LeaveShadowCrit();
  3371. return -1;
  3372. }
  3373. // check if we can initialize the database
  3374. // KdPrint(("Trying to shadow....%s\n",
  3375. // ((LPFIND32A)(lpSI->lpFind32))->cFileName));
  3376. if(InitDatabase(
  3377. ((LPFIND32A)(lpSI->lpFind32))->cFileName, // location
  3378. ((LPFIND32A)(lpSI->lpFind32))->cAlternateFileName, // user
  3379. ((LPFIND32A)(lpSI->lpFind32))->nFileSizeHigh, // default cache size if creating
  3380. ((LPFIND32A)(lpSI->lpFind32))->nFileSizeLow,
  3381. ((LPFIND32A)(lpSI->lpFind32))->dwReserved1, // cluster size
  3382. lpSI->ulRefPri,
  3383. &(lpSI->uOp)) // whether newly created
  3384. ==-1)
  3385. {
  3386. //we can't, let us quit
  3387. lpSI->dwError = GetLastErrorLocal();
  3388. }
  3389. else
  3390. {
  3391. // KdPrint(("Starting to shadow....\n"));
  3392. fShadow = 1;
  3393. iRet = SRET_OK;
  3394. sGS.uFlagsEvents |= FLAG_GLOBALSTATUS_START;
  3395. MRxSmbCscSignalAgent(NULL, SIGNALAGENTFLAG_DONT_LEAVE_CRIT_SECT|SIGNALAGENTFLAG_CONTINUE_FOR_NO_AGENT);
  3396. }
  3397. }
  3398. else
  3399. {
  3400. //we are not supposed to turn on csc. This happens only on NT
  3401. lpSI->dwError = ERROR_ACCESS_DENIED;
  3402. }
  3403. }
  3404. LeaveShadowCrit();
  3405. return iRet;
  3406. }
  3407. int
  3408. IoctlDisableCSCForUser(
  3409. LPSHADOWINFO lpSI
  3410. )
  3411. /*++
  3412. Routine Description:
  3413. Parameters:
  3414. lpSI SHADOWINFO structure pointer.
  3415. Return Value:
  3416. -1
  3417. Notes:
  3418. --*/
  3419. {
  3420. int iRet = SRET_ERROR;
  3421. if (!fShadow)
  3422. {
  3423. iRet = 1;
  3424. }
  3425. else
  3426. {
  3427. if (!IsCSCBusy() && (hShareReint == 0))
  3428. {
  3429. ClearCSCStateOnRedirStructures();
  3430. CloseDatabase();
  3431. fShadow = 0;
  3432. iRet = 1;
  3433. sGS.uFlagsEvents |= FLAG_GLOBALSTATUS_STOP;
  3434. MRxSmbCscSignalAgent(NULL, SIGNALAGENTFLAG_DONT_LEAVE_CRIT_SECT|SIGNALAGENTFLAG_CONTINUE_FOR_NO_AGENT);
  3435. }
  3436. else
  3437. {
  3438. SetLastErrorLocal(ERROR_BUSY);
  3439. }
  3440. }
  3441. return iRet;
  3442. }
  3443. #ifndef CSC_RECORDMANAGER_WINNT
  3444. int
  3445. IoctlTransitionShareToOffline(
  3446. LPSHADOWINFO lpSI
  3447. )
  3448. /*++
  3449. Routine Description:
  3450. Parameters:
  3451. lpSI SHADOWINFO structure pointer. lpSI->hShare identifies the share to take offline.
  3452. if lpSI->uStatus is 0, the online to offline transition should fail.
  3453. Return Value:
  3454. -1
  3455. Notes:
  3456. fails on win9x
  3457. --*/
  3458. {
  3459. return -1;
  3460. }
  3461. BOOL
  3462. FailModificationsToShare(
  3463. LPSHADOWINFO lpSI
  3464. )
  3465. {
  3466. return FALSE;
  3467. }
  3468. #else
  3469. BOOL
  3470. FailModificationsToShare(
  3471. LPSHADOWINFO lpSI
  3472. )
  3473. {
  3474. HSHARE hShare=0;
  3475. HSHADOW hShadow = 0;
  3476. // if no reintegration is in progress or if there is, it is blocking kind
  3477. // then we don't fail share modifications
  3478. if (!hShareReint || vfBlockingReint)
  3479. {
  3480. return FALSE;
  3481. }
  3482. if (!lpSI->hShare)
  3483. {
  3484. hShadow = (lpSI->hDir)?lpSI->hDir:lpSI->hShadow;
  3485. if ((GetAncestorsHSHADOW(hShadow, NULL, &hShare) < SRET_OK)||
  3486. (hShare == hShareReint))
  3487. {
  3488. SetLastErrorLocal(ERROR_OPERATION_ABORTED);
  3489. return TRUE;
  3490. }
  3491. }
  3492. return FALSE;
  3493. }
  3494. void
  3495. IncrementActivityCountForShare(
  3496. HSHARE hShare
  3497. )
  3498. {
  3499. if (!hShareReint || vfBlockingReint)
  3500. {
  3501. return;
  3502. }
  3503. if (hShare == hShareReint)
  3504. {
  3505. vdwActivityCount++;
  3506. }
  3507. }
  3508. BOOL
  3509. CSCFailUserOperation(
  3510. HSHARE hShare
  3511. )
  3512. /*++
  3513. Routine Description:
  3514. Parameters:
  3515. Return Value:
  3516. Notes:
  3517. --*/
  3518. {
  3519. if (!hShareReint || !vfBlockingReint)
  3520. {
  3521. return FALSE;
  3522. }
  3523. return(hShare == hShareReint);
  3524. }
  3525. int
  3526. IoctlTransitionShareToOffline(
  3527. LPSHADOWINFO lpSI
  3528. )
  3529. /*++
  3530. Routine Description:
  3531. Parameters:
  3532. lpSI SHADOWINFO structure pointer. lpSI->hShare identifies the share to take offline.
  3533. if lpSI->uStatus is 0, the online to offline transition should fail.
  3534. Return Value:
  3535. Notes:
  3536. --*/
  3537. {
  3538. return -1;
  3539. }
  3540. #endif
  3541. BOOLEAN
  3542. CscCheckForNullA(
  3543. PUCHAR pBuf,
  3544. ULONG Count)
  3545. {
  3546. ULONG i;
  3547. for (i = 0; i < Count; i++) {
  3548. if (pBuf[i] == '\0') {
  3549. return TRUE;
  3550. }
  3551. }
  3552. return FALSE;
  3553. }
  3554. BOOLEAN
  3555. CscCheckForNullW(
  3556. PWCHAR pBuf,
  3557. ULONG Count)
  3558. {
  3559. ULONG i;
  3560. for (i = 0; i < Count; i++) {
  3561. if (pBuf[i] == L'\0') {
  3562. return TRUE;
  3563. }
  3564. }
  3565. return FALSE;
  3566. }