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.

746 lines
20 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. HookCmmn.c
  5. Abstract:
  6. The purpose of this module is to have a common source for many routines
  7. used by the hook on win95 and on NT. In this way, there'll be only one
  8. place to change even if there's some code uglyness (ifdefs, etc.)
  9. Initially, i (jll) have not actually removed any routines from the win95
  10. hook....i have just made copies of them here. accordingly, everything is
  11. initially under ifdef-NT. the rule that is being used is that anything that
  12. requires visibility of the Rx Fcb structures will not be included here;
  13. rather, it'll be in the minirdr part. the following are steps that need to be
  14. accomplished:
  15. 1. ensure that the win95 shadow vxd can be built from these sources.
  16. 1a. juggle the win95 vxd compile to use precomp and stdcall.
  17. 2. juggle the record manager structs so that we'll be RISCable
  18. 3. remove any routines from hook.h that are actually here.
  19. 4. remove a number of other routines that i splated around from hook.c
  20. under NT-ifdef and place them here.
  21. Author:
  22. Shishir Pardikar [Shishirp] 01-jan-1995
  23. Revision History:
  24. Joe Linn [JoeLinn] 10-mar-97 Initial munging for NT
  25. --*/
  26. #include "precomp.h"
  27. #pragma hdrstop
  28. #pragma code_seg("PAGE")
  29. #undef RxDbgTrace
  30. #define RxDbgTrace(a,b,__d__) {qweee __d__;}
  31. #ifdef DEBUG
  32. //cshadow dbgprint interface
  33. #define HookCmmnKdPrint(__bit,__x) {\
  34. if (((HOOKCMMN_KDP_##__bit)==0) || FlagOn(HookCmmnKdPrintVector,(HOOKCMMN_KDP_##__bit))) {\
  35. KdPrint (__x);\
  36. }\
  37. }
  38. #define HOOKCMMN_KDP_ALWAYS 0x00000000
  39. #define HOOKCMMN_KDP_BADERRORS 0x00000001
  40. #define HOOKCMMN_KDP_ISSPECIALAPP 0x00000002
  41. #define HOOKCMMN_KDP_INITDATABASE 0x00000004
  42. #define HOOKCMMN_KDP_TUNNELING 0x00000008
  43. #define HOOKCMMN_KDP_GOOD_DEFAULT (HOOKCMMN_KDP_BADERRORS \
  44. | 0)
  45. ULONG HookCmmnKdPrintVector = HOOKCMMN_KDP_GOOD_DEFAULT;
  46. ULONG HookCmmnKdPrintVectorDef = HOOKCMMN_KDP_GOOD_DEFAULT;
  47. #else
  48. #define HookCmmnKdPrint(__bit,__x) {NOTHING;}
  49. #endif
  50. //this is just for editing ease......
  51. //#ifdef CSC_RECORDMANAGER_WINNT
  52. //#endif //ifdef CSC_RECORDMANAGER_WINNT
  53. #ifdef CSC_RECORDMANAGER_WINNT
  54. BOOL fInitDB = FALSE; // Database Initialized
  55. BOOL fReadInit = FALSE; // Init values have been read
  56. BOOL fSpeadOpt = TRUE; // spead option, reads the cached files even when
  57. // locks are set on the share
  58. GLOBALSTATUS sGS; // Global status used for communicating with ring3
  59. // Semaphore used to synchronize in memory structures
  60. VMM_SEMAPHORE semHook;
  61. // This strucutre is used as temporary I/O buffer only within Shadow critical
  62. // section
  63. WIN32_FIND_DATA vsFind32;
  64. // Agent Info, obtained through IoctlRegisterAgent
  65. ULONG hthreadReint=0; // Thred ID
  66. ULONG hwndReint=0; // windows handle.
  67. ULONG heventReint;
  68. // upto 16 threads can temporarily enable and disable shadowing
  69. ULONG rghthreadTemp[16];
  70. // Reintegration happens one share at a time. If it is going on, then BeginReint
  71. // in ioctl.c sets hShareReint to the share on which we are doing reint
  72. // if vfBlockingReint is TRUE, then all operations on that share will fail
  73. // when the share is reintegrating.
  74. // If vfBlockingReint is not true, then if the dwActivityCount is non-zero
  75. // the ioctls to change any state on any of the descendents of this share fail
  76. // causing the agent to aboort reintegration
  77. // The acitvycount is incremented based on a trigger from the redir/hook, when
  78. // any namespace mutating operation is performed.
  79. HSHARE hShareReint=0; // Share that is currently being reintegrated
  80. BOOL vfBlockingReint = TRUE;
  81. DWORD vdwActivityCount = 0;
  82. //from shadow.asm ---------------------------------------------------
  83. int fShadow = 0;
  84. #if defined(_X86_)
  85. int fLog = 1;
  86. #else
  87. int fLog = 0;
  88. #endif
  89. //tunnel cache
  90. SH_TUNNEL rgsTunnel[10] = {0};
  91. #ifdef DEBUG
  92. ULONG cntReadHits=0;
  93. tchar pathbuff[MAX_PATH+1];
  94. #endif
  95. BOOL FindTempAgentHandle(
  96. ULONG hthread)
  97. {
  98. int i;
  99. for (i=0; i < (sizeof(rghthreadTemp)/sizeof(ULONG)); ++i)
  100. {
  101. if (rghthreadTemp[i]==hthread)
  102. {
  103. return TRUE;
  104. }
  105. }
  106. return FALSE;
  107. }
  108. BOOL
  109. RegisterTempAgent(
  110. VOID
  111. )
  112. {
  113. int i;
  114. ULONG hthread;
  115. hthread = GetCurThreadHandle();
  116. for (i=0; i< (sizeof(rghthreadTemp)/sizeof(ULONG)); ++i)
  117. {
  118. if (!rghthreadTemp[i])
  119. {
  120. rghthreadTemp[i] = hthread;
  121. return TRUE;
  122. }
  123. }
  124. return FALSE;
  125. }
  126. BOOL
  127. UnregisterTempAgent(
  128. VOID
  129. )
  130. {
  131. int i;
  132. ULONG hthread;
  133. hthread = GetCurThreadHandle();
  134. for (i=0; i < (sizeof(rghthreadTemp)/sizeof(ULONG)); ++i)
  135. {
  136. if (rghthreadTemp[i]==hthread)
  137. {
  138. rghthreadTemp[i] = 0;
  139. return TRUE;
  140. }
  141. }
  142. return FALSE;
  143. }
  144. BOOL IsSpecialApp
  145. (
  146. VOID
  147. )
  148. {
  149. ULONG hthread;
  150. hthread = GetCurThreadHandle();
  151. if ((hthread==hthreadReint) || FindTempAgentHandle(hthread))
  152. {
  153. HookCmmnKdPrint(ISSPECIALAPP,("This is our Special App \r\n"));
  154. return TRUE;
  155. }
  156. return FALSE;
  157. }
  158. #define SetHintsFromList(a,b) ((-1))
  159. int InitShadowDB(VOID)
  160. {
  161. //for NT, we don't have all this hint stuff....just return success
  162. return(1);
  163. #if 0
  164. VMMHKEY hKeyShadow;
  165. int iSize = sizeof(int), iRet = -1;
  166. DWORD dwType;
  167. extern char vszExcludeList[], vszIncludeList[];
  168. BOOL fOpen = FALSE;
  169. char rgchList[128];
  170. if (_RegOpenKey(HKEY_LOCAL_MACHINE, REG_KEY_SHADOW, &hKeyShadow) == ERROR_SUCCESS)
  171. {
  172. fOpen = TRUE;
  173. iSize = sizeof(rgchList);
  174. if (_RegQueryValueEx(hKeyShadow, vszExcludeList, NULL, &dwType, rgchList, &iSize)==ERROR_SUCCESS)
  175. {
  176. if (SetHintsFromList(rgchList, TRUE) < 0)
  177. goto bailout;
  178. }
  179. iSize = sizeof(rgchList);
  180. if (_RegQueryValueEx(hKeyShadow, vszIncludeList, NULL, &dwType, rgchList, &iSize)==ERROR_SUCCESS)
  181. {
  182. if (SetHintsFromList(rgchList, FALSE) < 0)
  183. goto bailout;
  184. }
  185. iRet = 1;
  186. }
  187. bailout:
  188. if (fOpen)
  189. {
  190. _RegCloseKey(hKeyShadow);
  191. }
  192. return (iRet);
  193. #endif //0
  194. }
  195. int ReinitializeDatabase(
  196. LPSTR lpszLocation,
  197. LPSTR lpszUserName,
  198. DWORD nFileSizeHigh,
  199. DWORD nFileSizeLow,
  200. DWORD dwClusterSize
  201. )
  202. {
  203. BOOL fDBReinited = FALSE;
  204. if(OpenShadowDB(lpszLocation, lpszUserName, nFileSizeHigh, nFileSizeLow, dwClusterSize, TRUE, &fDBReinited) >= 0)
  205. {
  206. if (InitShadowDB() >= 0)
  207. {
  208. Assert(fDBReinited == TRUE);
  209. fInitDB = 1;
  210. }
  211. else
  212. {
  213. CloseShadowDB();
  214. }
  215. }
  216. if (fInitDB != 1)
  217. {
  218. fInitDB = -1;
  219. fShadow = 0;
  220. }
  221. return (fInitDB);
  222. }
  223. int
  224. InitDatabase(
  225. LPSTR lpszLocation,
  226. LPSTR lpszUserName,
  227. DWORD nFileSizeHigh,
  228. DWORD nFileSizeLow,
  229. DWORD dwClusterSize,
  230. BOOL fReformat,
  231. BOOL *lpfNew
  232. )
  233. {
  234. int iRet = 1;
  235. BOOL fDBReinited = FALSE;
  236. LPSTR PrefixedLocation = NULL;
  237. HookCmmnKdPrint(INITDATABASE,("Opening database at %s for %s with size %d \r\n", lpszLocation, lpszUserName, nFileSizeLow));
  238. //
  239. // When CSC is started by the kernel as part of a remote boot, the input path
  240. // will already be in NT format.
  241. //
  242. if (( _strnicmp(lpszLocation,"\\Device\\Harddisk",strlen("\\Device\\Harddisk")) != 0 ) &&
  243. ( _strnicmp(lpszLocation,"\\ArcName",strlen("\\ArcName")) != 0 )) {
  244. //this would be NT only..........
  245. PrefixedLocation = AllocMem(strlen(lpszLocation)+sizeof(NT_DB_PREFIX));
  246. if (!PrefixedLocation)
  247. {
  248. return -1;
  249. }
  250. strcpy(PrefixedLocation, NT_DB_PREFIX);
  251. strcat(PrefixedLocation, lpszLocation);
  252. HookCmmnKdPrint(INITDATABASE,("Opening database at %s changing to %s \r\n", lpszLocation, PrefixedLocation));
  253. //fortunately, this is call-by-value....so i can just overwrite the input parameter
  254. lpszLocation = PrefixedLocation;
  255. }
  256. // Do onetime init
  257. if (!fReadInit)
  258. {
  259. ReadInitValues();
  260. memset(rghthreadTemp, 0, sizeof(rghthreadTemp));
  261. fReadInit = TRUE;
  262. }
  263. // check if the database is not already initialized
  264. if (!fInitDB)
  265. {
  266. // open/create it
  267. iRet = OpenShadowDB(
  268. lpszLocation,
  269. lpszUserName,
  270. nFileSizeHigh,
  271. nFileSizeLow,
  272. dwClusterSize,
  273. fReformat,
  274. &fDBReinited
  275. );
  276. // open/create DB succeeded?
  277. if (iRet < 0)
  278. {
  279. //no
  280. HookCmmnKdPrint(ALWAYS,("Error Opening/Createing shadow database \r\n"));
  281. fInitDB = -1;
  282. fShadow = 0;
  283. }
  284. else
  285. {
  286. *lpfNew = fDBReinited;
  287. // did it exist in the first place?
  288. if (fDBReinited)
  289. {
  290. // no it didn't, let use create things like the filters and such
  291. iRet = InitShadowDB();
  292. }
  293. if (iRet >= 0)
  294. {
  295. fInitDB = 1;
  296. }
  297. else
  298. {
  299. CloseShadowDB();
  300. }
  301. }
  302. }
  303. if (PrefixedLocation)
  304. {
  305. FreeMem(PrefixedLocation);
  306. }
  307. return (iRet);
  308. }
  309. int
  310. CloseDatabase(
  311. VOID
  312. )
  313. {
  314. if (fInitDB)
  315. {
  316. CloseShadowDB();
  317. fInitDB = FALSE;
  318. return (1);
  319. }
  320. return (0);
  321. }
  322. BOOL IsBusy
  323. (
  324. HSHADOW hShadow
  325. )
  326. {
  327. DeclareFindFromShadowOnNtVars()
  328. if (PFindFdbFromHShadow(hShadow))
  329. return TRUE;
  330. return FALSE;
  331. }
  332. int PRIVATE DeleteShadowHelper
  333. (
  334. BOOL fMarkDeleted,
  335. HSHADOW hDir,
  336. HSHADOW hNew
  337. )
  338. {
  339. int iRet = -1;
  340. if (!fMarkDeleted)
  341. {
  342. if (DeleteShadow(hDir, hNew) < SRET_OK)
  343. goto bailout;
  344. }
  345. else
  346. {
  347. if (TruncateDataHSHADOW(hDir, hNew) < SRET_OK)
  348. goto bailout;
  349. // ACHTUNG!! other people depend on status being SHADOW_DELETED
  350. if (SetShadowInfo(hDir, hNew, NULL, SHADOW_DELETED, SHADOW_FLAGS_OR) < SRET_OK)
  351. goto bailout;
  352. }
  353. iRet = 0;
  354. bailout:
  355. return (iRet);
  356. }
  357. /*+-------------------------------------------------------------------------*/
  358. /* @doc INTERNAL HOOK
  359. @func BOOL | InsertTunnelInfo | 2.0
  360. The <f InsertTunnelInfo> function inserts file names
  361. in a tunnelling table. These entries are considered
  362. useful only for STALE_TUNNEL_INFO seconds. Tunnelling is
  363. used to retain LPOTHERINFO for files that get renamed/deleted
  364. and some other file is renamed to it. This typically done
  365. by editors, spreadsheets and such while saving things.
  366. @parm HSHADOW | hDir | Directory to which this guy belongs
  367. @parm LPPE | lppe | PathELement for the file to be tunnelled
  368. @parm LPOTHERINFO | lpOI | Info to be kept with the tunnelled entry
  369. @comm >>comment_text, <p parm> etc...
  370. @rdesc This function returns TRUE if successful. Otherwise the
  371. return value is FALSE.
  372. @xref >><f related_func>, <t RELATEDSTRUCT> ...
  373. */
  374. BOOL InsertTunnelInfo(
  375. HSHADOW hDir,
  376. USHORT *lpcFileName,
  377. USHORT *lpcAlternateFileName, // assume 14 USHORTs
  378. LPOTHERINFO lpOI
  379. )
  380. {
  381. int i, iHole = -1;
  382. ULONG uTime = IFSMgr_Get_NetTime(), cbFileName;
  383. cbFileName = (wstrlen(lpcFileName)+1)*sizeof(USHORT);
  384. ASSERT(hDir!=0);
  385. FreeStaleEntries();
  386. for (i=0;i< (sizeof(rgsTunnel)/sizeof(SH_TUNNEL)); ++i)
  387. {
  388. if (!rgsTunnel[i].hDir && (iHole < 0))
  389. {
  390. iHole = i;
  391. }
  392. if ((rgsTunnel[i].hDir==hDir)
  393. && (!wstrnicmp(lpcFileName, rgsTunnel[i].lpcFileName, MAX_PATH*sizeof(USHORT))||
  394. !wstrnicmp( lpcFileName,
  395. rgsTunnel[i].cAlternateFileName,
  396. sizeof(rgsTunnel[i].cAlternateFileName)))
  397. ) {
  398. FreeEntry(&rgsTunnel[i]);
  399. iHole = i;
  400. break;
  401. }
  402. }
  403. if (iHole >=0)
  404. {
  405. if (!(rgsTunnel[iHole].lpcFileName = (USHORT *)AllocMem(cbFileName)))
  406. {
  407. return (FALSE);
  408. }
  409. rgsTunnel[iHole].uTime = uTime;
  410. rgsTunnel[iHole].hDir = hDir;
  411. rgsTunnel[iHole].ubHintFlags = (UCHAR)(lpOI->ulHintFlags);
  412. rgsTunnel[iHole].ubHintPri = (UCHAR)(lpOI->ulHintPri);
  413. rgsTunnel[iHole].ubIHPri = (UCHAR)(lpOI->ulIHPri);
  414. rgsTunnel[iHole].ubRefPri = (UCHAR)(lpOI->ulRefPri);
  415. // copy without the NULL, we know that allocmem will have a NULL at the end
  416. memcpy(rgsTunnel[iHole].lpcFileName, lpcFileName, cbFileName-sizeof(USHORT));
  417. // assumes 14 USHORTS
  418. memcpy( rgsTunnel[iHole].cAlternateFileName,
  419. lpcAlternateFileName,
  420. sizeof(rgsTunnel[iHole].cAlternateFileName));
  421. HookCmmnKdPrint(TUNNELING,("InsertTunnelInfo: Inserting %ws/%ws, Hintpri=%d, HintFlags=%d RefPri=%d \r\n",
  422. lpcFileName,lpcAlternateFileName,
  423. lpOI->ulHintPri,
  424. lpOI->ulHintFlags,
  425. lpOI->ulRefPri
  426. ));
  427. return (TRUE);
  428. }
  429. return (FALSE);
  430. }
  431. /*+-------------------------------------------------------------------------*/
  432. /* @doc INTERNAL HOOK
  433. @func BOOL | RetrieveTunnelInfo | 2.0
  434. The <f RetrieveTunnelInfo> function returns to the caller
  435. OTHERINFO structure containing priorities and such about
  436. files which have been recently renamed or deleted. Entries
  437. which are older than STALE_TUNNEL_INFO seconds are thrown
  438. out.
  439. @parm HSHADOW | hDir | Directory to which this guy belongs
  440. @parm ushort *| lpcFileName| name of the file whose info is needed
  441. @parm LPOTHERINFO | lpOI | Info to be retrieved from the tunnelled entry
  442. @comm >>comment_text, <p parm> etc...
  443. @rdesc This function returns TRUE if successful. Otherwise the
  444. return value is FALSE.
  445. @xref >><f related_func>, <t RELATEDSTRUCT> ...
  446. */
  447. #ifndef MRXSMB_BUILD_FOR_CSC_DCON
  448. BOOL RetrieveTunnelInfo(
  449. #else
  450. RETRIEVE_TUNNEL_INFO_RETURNS
  451. RetrieveTunnelInfo(
  452. #endif
  453. HSHADOW hDir,
  454. USHORT *lpcFileName,
  455. WIN32_FIND_DATA *lpFind32, // if NULL, get only otherinfo
  456. LPOTHERINFO lpOI
  457. )
  458. {
  459. int i;
  460. #ifdef MRXSMB_BUILD_FOR_CSC_DCON
  461. RETRIEVE_TUNNEL_INFO_RETURNS RetVal;
  462. #endif
  463. ASSERT(hDir!=0);
  464. FreeStaleEntries();
  465. for (i=0;i< (sizeof(rgsTunnel)/sizeof(SH_TUNNEL)); ++i)
  466. {
  467. #ifndef MRXSMB_BUILD_FOR_CSC_DCON
  468. if (rgsTunnel[i].hDir
  469. && (!wstrnicmp(lpcFileName, rgsTunnel[i].lpcFileName, MAX_PATH*sizeof(USHORT))||
  470. !wstrnicmp( lpcFileName,
  471. rgsTunnel[i].cAlternateFileName,
  472. sizeof(rgsTunnel[i].cAlternateFileName)))
  473. ) {
  474. #else
  475. if (rgsTunnel[i].hDir==hDir)
  476. {
  477. if (!wstrnicmp(lpcFileName,
  478. rgsTunnel[i].cAlternateFileName,
  479. sizeof(rgsTunnel[i].cAlternateFileName)) ) {
  480. RetVal = TUNNEL_RET_SHORTNAME_TUNNEL;
  481. } else if ( !wstrnicmp(lpcFileName, rgsTunnel[i].lpcFileName, MAX_PATH*sizeof(USHORT)) ){
  482. RetVal = TUNNEL_RET_LONGNAME_TUNNEL;
  483. } else {
  484. continue;
  485. }
  486. #endif
  487. InitOtherInfo(lpOI);
  488. lpOI->ulHintFlags = (ULONG)(rgsTunnel[i].ubHintFlags);
  489. lpOI->ulHintPri = (ULONG)(rgsTunnel[i].ubHintPri);
  490. lpOI->ulIHPri = (ULONG)(rgsTunnel[i].ubIHPri);
  491. // don't copy the reference priority, it is assigned by the record manager
  492. // lpOI->ulRefPri = (ULONG)(rgsTunnel[i].ubRefPri);
  493. HookCmmnKdPrint(TUNNELING,("RetrieveTunnelInfo: %ws found, Hintpri=%d, HintFlags=%d RefPri=%d \r\n",
  494. lpcFileName,
  495. lpOI->ulHintPri,
  496. lpOI->ulHintFlags,
  497. lpOI->ulRefPri
  498. ));
  499. if (lpFind32)
  500. {
  501. memcpy( lpFind32->cFileName,
  502. rgsTunnel[i].lpcFileName,
  503. (wstrlen(rgsTunnel[i].lpcFileName)+1)*sizeof(USHORT)
  504. );
  505. memcpy( lpFind32->cAlternateFileName,
  506. rgsTunnel[i].cAlternateFileName,
  507. sizeof(rgsTunnel[i].cAlternateFileName)
  508. );
  509. HookCmmnKdPrint(TUNNELING,("Recovered LFN %ws/%ws \r\n",
  510. lpFind32->cFileName,
  511. lpFind32->cAlternateFileName));
  512. }
  513. FreeEntry(&rgsTunnel[i]);
  514. #ifndef MRXSMB_BUILD_FOR_CSC_DCON
  515. return (TRUE);
  516. }
  517. }
  518. return (FALSE);
  519. #else
  520. return (RetVal);
  521. }
  522. }
  523. return (TUNNEL_RET_NOTFOUND);
  524. #endif
  525. }
  526. VOID FreeStaleEntries()
  527. {
  528. int i;
  529. ULONG uTime = IFSMgr_Get_NetTime();
  530. for (i=0;i< (sizeof(rgsTunnel)/sizeof(SH_TUNNEL)); ++i)
  531. {
  532. if (rgsTunnel[i].lpcFileName
  533. && ((uTime- rgsTunnel[i].uTime)>STALE_TUNNEL_INFO))
  534. {
  535. FreeEntry(&rgsTunnel[i]);
  536. }
  537. }
  538. }
  539. void FreeEntry(LPSH_TUNNEL lpshTunnel)
  540. {
  541. FreeMem(lpshTunnel->lpcFileName);
  542. memset(lpshTunnel, 0, sizeof(SH_TUNNEL));
  543. }
  544. //got this from hook.c...not the same because w95 looks at the
  545. //resource flags directly
  546. BOOL IsShadowVisible(
  547. #ifdef MRXSMB_BUILD_FOR_CSC_DCON
  548. BOOLEAN Disconnected,
  549. #else
  550. PRESOURCE pResource,
  551. #endif //ifdef MRXSMB_BUILD_FOR_CSC_DCON
  552. DWORD dwAttr,
  553. ULONG uShadowStatus
  554. )
  555. {
  556. BOOL fVisible = 1;
  557. // To a filesystem API the shadow is never visible when it is marked
  558. // as being deleted
  559. if (mShadowDeleted(uShadowStatus))
  560. return (0);
  561. #ifdef MRXSMB_BUILD_FOR_CSC_DCON
  562. if (Disconnected)
  563. #else
  564. if (mIsDisconnected(pResource))
  565. #endif //ifdef MRXSMB_BUILD_FOR_CSC_DCON
  566. {
  567. if (IsFile(dwAttr))
  568. {
  569. #ifdef OFFLINE
  570. #ifdef CSC_RECORDMANAGER_WINNT
  571. ASSERT(FALSE);
  572. #endif //ifdef CSC_RECORDMANAGER_WINNT
  573. if (mIsOfflineConnection(pResource))
  574. { // offline connection
  575. if (!mShadowOutofSync(uShadowStatus))
  576. {
  577. fVisible = 0;
  578. }
  579. }
  580. else
  581. #endif //OFFLINE
  582. {// pure disconnected state
  583. // ignore sparse files
  584. if (mShadowSparse(uShadowStatus))
  585. {
  586. fVisible = 0;
  587. }
  588. }
  589. }
  590. }
  591. else
  592. { // connected state, bypass all out of ssync files, doesn't include
  593. // stale, because we can handle staleness during open
  594. if (IsFile(dwAttr))
  595. {
  596. if (mShadowOutofSync(uShadowStatus))
  597. {
  598. fVisible = 0;
  599. }
  600. }
  601. else if (dwAttr & FILE_ATTRIBUTE_DIRECTORY)
  602. { // and locallycreated or orphaned directories
  603. if (mQueryBits(uShadowStatus, SHADOW_LOCALLY_CREATED|SHADOW_ORPHAN))
  604. {
  605. fVisible = 0;
  606. }
  607. }
  608. }
  609. return (fVisible);
  610. }
  611. //got this from hook.c...not the same because w95 looks at the
  612. //resource flags directly
  613. //CODE.IMPROVEMENT we should define a common header for RESOURCE and FDB so that most stuff
  614. // would just work.
  615. int MarkShareDirty(
  616. PUSHORT ShareStatus,
  617. ULONG hShare
  618. )
  619. {
  620. if (!mQueryBits(*ShareStatus, SHARE_REINT))
  621. {
  622. SetShareStatus(hShare, SHARE_REINT, SHADOW_FLAGS_OR);
  623. mSetBits(*ShareStatus, SHARE_REINT);
  624. }
  625. return SRET_OK;
  626. }
  627. #endif //ifdef CSC_RECORDMANAGER_WINNT
  628.