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.

6280 lines
142 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. CShadow.c
  5. Abstract:
  6. This file implements the "cshadow" interface that is used by the redir and ioctls.
  7. The cshadow interface hides the actual implementation of the csc database from the
  8. users of the database.
  9. There are three persistant database types exposed
  10. 1) The database of shares
  11. 2) The filesystem hierarchy under any particular share
  12. 3) The priority queue / Master File Table
  13. Operations for set and get are provided on the 1) and 2). 3) Is allwed to be
  14. enumerated. The priority queue is enumerated by the usermode agent to a) fill partially
  15. filled files and b) keep the space used within the specified constraints
  16. Author:
  17. Shishir Pardikar [Shishirp] 01-jan-1995
  18. Revision History:
  19. Joe Linn [JoeLinn] 23-jan-97 Ported for use on NT
  20. --*/
  21. #include "precomp.h"
  22. #pragma hdrstop
  23. #pragma code_seg("PAGE")
  24. #ifndef CSC_RECORDMANAGER_WINNT
  25. #define WIN32_APIS
  26. #include "record.h"
  27. #include "cshadow.h"
  28. #endif //ifndef CSC_RECORDMANAGER_WINNT
  29. #include "string.h"
  30. #include "stdlib.h"
  31. #include "vxdwraps.h"
  32. // Defines and Typedefs -------------------------------------------------------------------
  33. #undef RxDbgTrace
  34. #define RxDbgTrace(a,b,__d__) {qweee __d__;}
  35. #ifdef DEBUG
  36. //cshadow dbgprint interface
  37. #define CShadowKdPrint(__bit,__x) {\
  38. if (((CSHADOW_KDP_##__bit)==0) || FlagOn(CShadowKdPrintVector,(CSHADOW_KDP_##__bit))) {\
  39. KdPrint (__x);\
  40. }\
  41. }
  42. #define CSHADOW_KDP_ALWAYS 0x00000000
  43. #define CSHADOW_KDP_BADERRORS 0x00000001
  44. #define CSHADOW_KDP_CREATESHADOWHI 0x00000002
  45. #define CSHADOW_KDP_CREATESHADOWLO 0x00000004
  46. #define CSHADOW_KDP_DELETESHADOWBAD 0x00000008
  47. #define CSHADOW_KDP_DELETESHADOWHI 0x00000010
  48. #define CSHADOW_KDP_DELETESHADOWLO 0x00000020
  49. #define CSHADOW_KDP_RENAMESHADOWHI 0x00000040
  50. #define CSHADOW_KDP_RENAMESHADOWLO 0x00000080
  51. #define CSHADOW_KDP_GETSHADOWHI 0x00000100
  52. #define CSHADOW_KDP_GETSHADOWLO 0x00000200
  53. #define CSHADOW_KDP_SETSHADOWINFOHI 0x00000400
  54. #define CSHADOW_KDP_SETSHADOWINFOLO 0x00000800
  55. #define CSHADOW_KDP_READSHADOWINFOHI 0x00001000
  56. #define CSHADOW_KDP_READSHADOWINFOLO 0x00002000
  57. #define CSHADOW_KDP_COPYLOCAL 0x00004000
  58. #define CSHADOW_KDP_COPYFILE 0x00008000
  59. #define CSHADOW_KDP_FINDCREATESHARE 0x80000000
  60. #define CSHADOW_KDP_MISC 0x00010000
  61. #define CSHADOW_KDP_STOREDATA 0x00020000
  62. #define CSHADOW_KDP_GOOD_DEFAULT (CSHADOW_KDP_BADERRORS \
  63. | CSHADOW_KDP_CREATESHADOWHI \
  64. | CSHADOW_KDP_DELETESHADOWHI \
  65. | CSHADOW_KDP_RENAMESHADOWHI \
  66. | CSHADOW_KDP_GETSHADOWHI \
  67. | CSHADOW_KDP_SETSHADOWINFOHI \
  68. | CSHADOW_KDP_FINDCREATESHARE \
  69. | 0)
  70. #define IF_HSHADOW_SPECIAL(___hshadow) if((___hshadow)==hShadowSpecial_x)
  71. #define SET_HSHADOW_SPECIAL(___hshadow) {hShadowSpecial_x = (___hshadow);}
  72. ULONG CShadowKdPrintVector = CSHADOW_KDP_BADERRORS;
  73. //ULONG CShadowKdPrintVector = CSHADOW_KDP_GOOD_DEFAULT;
  74. ULONG CShadowKdPrintVectorDef = CSHADOW_KDP_GOOD_DEFAULT;
  75. #else
  76. #define CShadowKdPrint(__bit,__x) {NOTHING;}
  77. #define IF_HSHADOW_SPECIAL(___hshadow) if(FALSE)
  78. #define SET_HSHADOW_SPECIAL(___hshadow) {NOTHING;}
  79. #endif
  80. // ReadShadowInfo action flags
  81. #define RSI_COMPARE 0x0001
  82. #define RSI_GET 0x0002
  83. #define RSI_SET 0x0004
  84. #define mIsDir(lpF32) (((LPFIND32)(lpF32))->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  85. #define ENTERCRIT_SHADOW {if (semShadow)\
  86. Wait_Semaphore(semShadow, BLOCK_SVC_INTS);}
  87. #define LEAVECRIT_SHADOW {if (semShadow)\
  88. Signal_Semaphore(semShadow);}
  89. #define InuseGlobalFRExt() (vfInuseFRExt)
  90. #define UseGlobalFilerecExt() {Assert(!vfInuseFRExt);vfInuseFRExt = TRUE;memset(&vsFRExt, 0, sizeof(FILERECEXT));}
  91. #define UnUseGlobalFilerecExt() (vfInuseFRExt = FALSE)
  92. #pragma intrinsic (memcmp, memcpy, memset, strcat, strcmp, strcpy, strlen)
  93. // Global data ----------------------------------------------------------------------------
  94. USHORT vwzRegDelimiters[] = L";, ";
  95. USHORT *vrgwExclusionListDef[] =
  96. {
  97. L"*.SLM",
  98. L"*.MDB",
  99. L"*.LDB",
  100. L"*.MDW",
  101. L"*.MDE",
  102. L"*.PST",
  103. L"*.DB?"
  104. };
  105. USHORT **vlplpExclusionList = vrgwExclusionListDef;
  106. ULONG vcntExclusionListEntries = (sizeof(vrgwExclusionListDef)/sizeof(USHORT *));
  107. USHORT *vrgwBandwidthConservationListDef[] =
  108. {
  109. L"*.EXE",
  110. L"*.DLL",
  111. L"*.SYS",
  112. L"*.COM",
  113. L"*.HLP",
  114. L"*.CPL",
  115. L"*.INF"
  116. };
  117. USHORT **vlplpBandwidthConservationList = vrgwBandwidthConservationListDef;
  118. ULONG vcntBandwidthConservationListEntries = (sizeof(vrgwBandwidthConservationListDef)/sizeof(USHORT *));
  119. USHORT vtzExcludedCharsList[] = L":*?";
  120. ULONG hShadowSpecial_x = -1;
  121. VMM_SEMAPHORE semShadow=0; // To serialize Shadow database accesses
  122. ULONG hShadowCritOwner=0;
  123. #ifdef DEBUG
  124. BOOL vfInShadowCrit = FALSE;
  125. extern BOOL vfStopHandleCaching;
  126. #endif
  127. char vszShadowVolume[] = "SHADOW";
  128. USHORT vwszFileSystemName[] = L"FAT";
  129. FILERECEXT vsFRExt;
  130. BOOL vfInuseFRExt = FALSE;
  131. LPVOID lpdbShadow = NULL;
  132. // vdwSparseStaleDetecionCount is a tick counter used to keep track of how many stale or sparse
  133. // file inodes were encountered by the cshadow interface during all APIs that produce
  134. // sparse or stale files, such as CreateShadowInternal, SetShadowinfoEx and ReadShadowInfo
  135. // The agent continues to loop through the PQ till he finds that he has looped through
  136. // the entire PQ and hasn't encountered a single sparse or stale file at which point he
  137. // goes in a mode where he starts to check whether any inodes have been newly sparsed
  138. // or gone stale. If none are, then he doesn't enumerate the queue, else he goes to
  139. // the earlier state.
  140. // ACHTUNG: It is to be noted that a sparse or a stale entry may get counted multiple times.
  141. // As an example, when a shadow is created the count is bumped once, then if it's
  142. // pin data is changed it is bumped up, similarly when it is moved in the priority Q
  143. // it is again changed because SetPriorityHSHADOW goes through SetShadowInfoEx
  144. DWORD vdwSparseStaleDetecionCount=0;
  145. DWORD vdwManualFileDetectionCount=0;
  146. // vdwCSCNameSpaceVersion is bumped up everytime a create,rename or delete is performed on
  147. // the local database. This is useful for quickly checking cache-coherency. When a full
  148. // UNC name is cached, the version# of the database is obtained before caching. When using the
  149. // cached UNC name, the version # is queried. If it has changed, the cache is thrown away.
  150. // The version is at a very coarse granularity. It would be nice to have a finer control
  151. DWORD vdwCSCNameSpaceVersion=0;
  152. DWORD vdwPQVersion=0;
  153. AssertData
  154. AssertError
  155. // a callback function that someone can set and be called when a directory delete succeeds
  156. // this is useful only for ioctls doing finds on a directory, at the moment
  157. // If there is a more general need for callbacks, we will extend this to be a list etc.
  158. LPDELETECALLBACK lpDeleteCBForIoctl = NULL;
  159. // status of the database. Used mostly for encryption state
  160. ULONG vulDatabaseStatus=0;
  161. // Local function prototypes -----------------------------------------------------------
  162. int PRIVATE ReadShadowInfo(HSHADOW, HSHADOW, LPFIND32, ULONG far *, LPOTHERINFO, LPVOID, LPDWORD, ULONG);
  163. int CopyFilerecToOtherInfo(LPFILERECEXT lpFR, LPOTHERINFO lpOI);
  164. int CopyOtherInfoToFilerec(LPOTHERINFO lpOI, LPFILERECEXT lpFR);
  165. int CreateShadowInternal(HSHADOW, LPFIND32, ULONG, LPOTHERINFO, LPHSHADOW);
  166. int CopySharerecToFindInfo(LPSHAREREC, LPFIND32);
  167. int CopyOtherInfoToSharerec(LPOTHERINFO, LPSHAREREC);
  168. int CopyPQToOtherInfo(LPPRIQREC, LPOTHERINFO);
  169. int CopyOtherInfoToPQ(LPOTHERINFO, LPPRIQREC);
  170. int CopySharerecToShadowInfo(LPSHAREREC lpSR, LPSHADOWINFO lpSI);
  171. int RenameDirFileHSHADOW(HSHADOW, HSHADOW, HSHARE, HSHADOW, HSHADOW, ULONG, LPOTHERINFO, ULONG, LPFILERECEXT, LPFIND32, LPVOID, LPDWORD);
  172. int RenameFileHSHADOW(HSHADOW, HSHADOW, HSHADOW, HSHADOW, ULONG, LPOTHERINFO, ULONG, LPFILERECEXT, LPFIND32, LPVOID, LPDWORD);
  173. int DestroyShareInternal(LPSHAREREC);
  174. //prototypes added to make it compile on NT
  175. int PUBLIC SetPriorityHSHADOW(
  176. HSHADOW hDir,
  177. HSHADOW hShadow,
  178. ULONG ulRefPri,
  179. ULONG ulIHPri
  180. );
  181. int CopySharerecToOtherInfo(LPSHAREREC lpSR, LPOTHERINFO lpOI);
  182. int MetaMatchShare(
  183. HSHADOW hDir,
  184. LPFIND32 lpFind32,
  185. ULONG *lpuCookie,
  186. LPHSHADOW lphShadow,
  187. ULONG *lpuStatus,
  188. LPOTHERINFO lpOI,
  189. METAMATCHPROC lpfnMMP,
  190. LPVOID lpData
  191. );
  192. int MetaMatchDir( HSHADOW hDir,
  193. LPFIND32 lpFind32,
  194. ULONG *lpuCookie,
  195. LPHSHADOW lphShadow,
  196. ULONG *lpuStatus,
  197. LPOTHERINFO lpOI,
  198. METAMATCHPROC lpfnMMP,
  199. LPVOID lpData
  200. );
  201. int
  202. DeleteShadowInternal( //
  203. HSHADOW hDir,
  204. HSHADOW hShadow,
  205. BOOL fForce
  206. );
  207. int
  208. CShadowFindFilerecFromInode(
  209. LPVOID lpdbID,
  210. HSHADOW hDir,
  211. HSHADOW hShadow,
  212. LPPRIQREC lpPQ,
  213. LPFILERECEXT lpFRUse
  214. );
  215. BOOL
  216. CopySecurityContextToBuffer(
  217. LPRECORDMANAGER_SECURITY_CONTEXT lpSecurityContext,
  218. LPVOID lpSecurityBlob,
  219. LPDWORD lpdwBlobSize
  220. );
  221. BOOL
  222. CopyBufferToSecurityContext(
  223. LPVOID lpSecurityBlob,
  224. LPDWORD lpdwBlobSize,
  225. LPRECORDMANAGER_SECURITY_CONTEXT lpSecurityContext
  226. );
  227. int CopyFindInfoToSharerec(
  228. LPFIND32 lpFind32,
  229. LPSHAREREC lpSR
  230. );
  231. #ifdef DEBUG
  232. int
  233. ValidatePri(
  234. LPFILERECEXT lpFR
  235. );
  236. #endif
  237. VOID
  238. AdjustSparseStaleDetectionCount(
  239. ULONG hShare,
  240. LPFILERECEXT lpFRUse
  241. );
  242. VOID FreeLists(
  243. VOID
  244. );
  245. VOID
  246. CscNotifyAgentOfFullCacheIfRequired(
  247. VOID);
  248. //
  249. // From cscapi.h
  250. //
  251. #define FLAG_CSC_SHARE_STATUS_MANUAL_REINT 0x0000
  252. #define FLAG_CSC_SHARE_STATUS_AUTO_REINT 0x0040
  253. #define FLAG_CSC_SHARE_STATUS_VDO 0x0080
  254. #define FLAG_CSC_SHARE_STATUS_NO_CACHING 0x00c0
  255. #define FLAG_CSC_SHARE_STATUS_CACHING_MASK 0x00c0
  256. // Functions -------------------------------------------------------------------------------
  257. BOOL FExistsShadowDB(
  258. LPSTR lpszLocation
  259. )
  260. /*++
  261. Routine Description:
  262. Parameters:
  263. Return Value:
  264. Notes:
  265. --*/
  266. {
  267. return (FExistsRecDB(lpszLocation));
  268. }
  269. int OpenShadowDB(
  270. LPSTR lpszLocation,
  271. LPSTR lpszUserName,
  272. DWORD dwDefDataSizeHigh,
  273. DWORD dwDefDataSizeLow,
  274. DWORD dwClusterSize,
  275. BOOL fReinit,
  276. BOOL *lpfReinited
  277. )
  278. /*++
  279. Routine Description:
  280. Parameters:
  281. Return Value:
  282. Notes:
  283. --*/
  284. {
  285. DWORD Status;
  286. BOOL fEncrypt;
  287. if (!semShadow)
  288. {
  289. CShadowKdPrint(ALWAYS,("OpenShadowDB:Shadow Semaphore doesn't exist, bailing out \r\n"));
  290. SetLastErrorLocal(ERROR_SERVICE_NOT_ACTIVE);
  291. return -1;
  292. }
  293. Status = CscInitializeSecurityDescriptor();
  294. if (Status != ERROR_SUCCESS) {
  295. CShadowKdPrint(BADERRORS,("Failed to initialize Security descriptor Status=%x\n",Status));
  296. return -1;
  297. }
  298. if (!(lpdbShadow = OpenRecDB(lpszLocation, lpszUserName, dwDefDataSizeHigh, dwDefDataSizeLow, dwClusterSize, fReinit, lpfReinited, &vulDatabaseStatus)))
  299. {
  300. return -1;
  301. }
  302. Status = CscInitializeSecurity(lpdbShadow);
  303. if (Status != ERROR_SUCCESS)
  304. {
  305. CloseShadowDB();
  306. CscUninitializeSecurityDescriptor();
  307. CShadowKdPrint(BADERRORS,("OpenShadowDB %s at %s for %s with size %ld %lx \n",
  308. "couldn't Initialize Security %lx",
  309. lpszLocation, lpszUserName, dwDefDataSizeLow,Status));
  310. return -1;
  311. }
  312. fEncrypt = -1;
  313. if(mDatabasePartiallyEncrypted(vulDatabaseStatus))
  314. {
  315. fEncrypt = TRUE;
  316. }
  317. else if (mDatabasePartiallyUnencrypted(vulDatabaseStatus))
  318. {
  319. fEncrypt = FALSE;
  320. }
  321. // do the best we can
  322. if (fEncrypt != -1)
  323. {
  324. if(EncryptDecryptDB(lpdbShadow, fEncrypt))
  325. {
  326. if (fEncrypt)
  327. {
  328. vulDatabaseStatus = ((vulDatabaseStatus & ~FLAG_DATABASESTATUS_ENCRYPTION_MASK) | FLAG_DATABASESTATUS_ENCRYPTED);
  329. }
  330. else
  331. {
  332. vulDatabaseStatus = ((vulDatabaseStatus & ~FLAG_DATABASESTATUS_ENCRYPTION_MASK) | FLAG_DATABASESTATUS_UNENCRYPTED);
  333. }
  334. SetDatabaseStatus(vulDatabaseStatus, FLAG_DATABASESTATUS_ENCRYPTION_MASK);
  335. }
  336. }
  337. // CSCInitLists();
  338. return 1;
  339. }
  340. int CloseShadowDB(
  341. VOID
  342. )
  343. /*++
  344. Routine Description:
  345. Parameters:
  346. Return Value:
  347. Notes:
  348. --*/
  349. {
  350. if (!lpdbShadow)
  351. {
  352. return -1;
  353. }
  354. if(!CloseRecDB(lpdbShadow))
  355. {
  356. return -1;
  357. }
  358. CscUninitializeSecurityDescriptor();
  359. FreeLists();
  360. lpdbShadow = NULL;
  361. Assert(semShadow != 0);
  362. return (1);
  363. }
  364. //on NT, we allocate this statically
  365. #ifdef CSC_RECORDMANAGER_WINNT
  366. FAST_MUTEX Nt5CscShadowMutex;
  367. #endif
  368. BOOL
  369. InitializeShadowCritStructures (
  370. void
  371. )
  372. {
  373. #ifndef CSC_RECORDMANAGER_WINNT
  374. semShadow = Create_Semaphore(1);
  375. #else
  376. semShadow = &Nt5CscShadowMutex;
  377. ExInitializeFastMutex(semShadow);
  378. #endif
  379. return (semShadow != 0);
  380. }
  381. VOID
  382. CleanupShadowCritStructures(
  383. VOID
  384. )
  385. {
  386. // Assert(semShadow);
  387. #ifndef CSC_RECORDMANAGER_WINNT
  388. Destroy_Semaphore(semShadow);
  389. #else
  390. semShadow = NULL;
  391. #endif
  392. }
  393. #ifdef DEBUG
  394. WINNT_DOIT(
  395. PSZ ShadowCritAcquireFile;
  396. ULONG ShadowCritAcquireLine;
  397. BOOLEAN ShadowCritDbgPrintEnable = FALSE; //TRUE;
  398. )
  399. #endif
  400. #ifndef CSC_RECORDMANAGER_WINNT
  401. int EnterShadowCrit( void)
  402. #else
  403. int __EnterShadowCrit(ENTERLEAVESHADOWCRIT_SIGNATURE)
  404. #endif
  405. {
  406. #ifdef CSC_RECORDMANAGER_WINNT
  407. if(!MRxSmbIsCscEnabled) {
  408. SetLastErrorLocal(ERROR_SERVICE_NOT_ACTIVE);
  409. DbgPrint("CSC not enabled, not asserting for semShadow\n");
  410. return(1);
  411. }
  412. #endif
  413. Assert(semShadow != NULL);
  414. ENTERCRIT_SHADOW;
  415. hShadowCritOwner = GetCurThreadHandle();
  416. #ifdef DEBUG
  417. ++vfInShadowCrit;
  418. WINNT_DOIT(
  419. ShadowCritAcquireFile = FileName;
  420. ShadowCritAcquireLine = LineNumber;
  421. if (ShadowCritDbgPrintEnable) {
  422. DbgPrint("ACQUIRESHADOWCRIT at %s %u\n",FileName,LineNumber);
  423. }
  424. )
  425. #endif
  426. return 1;
  427. }
  428. #ifndef CSC_RECORDMANAGER_WINNT
  429. int LeaveShadowCrit( void)
  430. #else
  431. int __LeaveShadowCrit(ENTERLEAVESHADOWCRIT_SIGNATURE)
  432. #endif
  433. {
  434. #ifdef CSC_RECORDMANAGER_WINNT
  435. if(!MRxSmbIsCscEnabled) {
  436. DbgPrint("CSC not enabled, not asserting for vfInShadowCrit\n");
  437. SetLastErrorLocal(ERROR_SERVICE_NOT_ACTIVE);
  438. return(1);
  439. }
  440. #endif
  441. Assert(vfInShadowCrit != 0);
  442. #ifdef DEBUG
  443. --vfInShadowCrit;
  444. WINNT_DOIT(
  445. ShadowCritAcquireLine *= -1;
  446. if (ShadowCritDbgPrintEnable) {
  447. DbgPrint("RELEASESHADOWCRIT at %s %u\n",FileName,LineNumber);
  448. }
  449. )
  450. #endif
  451. hShadowCritOwner = 0;
  452. LEAVECRIT_SHADOW;
  453. return 1;
  454. }
  455. int LeaveShadowCritIfThisThreadOwnsIt(
  456. void
  457. )
  458. {
  459. if (hShadowCritOwner == GetCurThreadHandle())
  460. {
  461. LeaveShadowCrit();
  462. }
  463. return 1;
  464. }
  465. int SetList(
  466. USHORT *lpList,
  467. DWORD cbBufferSize,
  468. int typeList
  469. )
  470. /*++
  471. Routine Description:
  472. This routine sets various lists that the CSHADOW interface provides. The known lists include
  473. the exclusion list and the bandwidth conservation list.
  474. The exclusion list contains wildcarded file extensions that should not be cached automatically.
  475. The bandwidth conservation list is the list of file types for which opens should be
  476. done locally if possible.
  477. Parameters:
  478. lpList A list of wide character strings terminated by a NULL string
  479. typeList CSHADOW_LIST_TYPE_EXCLUDE or CSHADOW_LIST_TYPE_CONSERVE_BW
  480. Return Value:
  481. Notes:
  482. --*/
  483. {
  484. DWORD dwCount=0;
  485. USHORT **lplpListArray = NULL, *lpuT;
  486. int iRet = -1;
  487. BOOL fUpdateList = FALSE;
  488. if (cbBufferSize)
  489. {
  490. CShadowKdPrint(MISC, (" %ws\r\n", lpList));
  491. #if 0
  492. if (typeList == CSHADOW_LIST_TYPE_EXCLUDE)
  493. {
  494. DbgPrint("ExclusionList: %ws\n", lpList);
  495. }
  496. if (typeList == CSHADOW_LIST_TYPE_CONSERVE_BW)
  497. {
  498. DbgPrint("BW: %ws\n", lpList);
  499. }
  500. #endif
  501. if (CreateStringArrayFromDelimitedList(lpList, vwzRegDelimiters, NULL, &dwCount))
  502. {
  503. if (dwCount)
  504. {
  505. lplpListArray = (LPWSTR *)AllocMem(dwCount * sizeof(USHORT *) + cbBufferSize);
  506. if (lplpListArray)
  507. {
  508. lpuT = (USHORT *)((LPBYTE)lplpListArray + dwCount * sizeof(USHORT *));
  509. // copy it while uppercasing
  510. memcpy(lpuT, lpList, cbBufferSize);
  511. UniToUpper(lpuT, lpuT, cbBufferSize);
  512. if (CreateStringArrayFromDelimitedList( lpuT,
  513. vwzRegDelimiters,
  514. lplpListArray,
  515. &dwCount))
  516. {
  517. fUpdateList = TRUE;
  518. }
  519. }
  520. }
  521. else
  522. {
  523. Assert(lplpListArray == NULL);
  524. fUpdateList = TRUE;
  525. }
  526. if (fUpdateList)
  527. {
  528. switch (typeList)
  529. {
  530. case CSHADOW_LIST_TYPE_EXCLUDE:
  531. if(vlplpExclusionList != vrgwExclusionListDef)
  532. {
  533. if (vlplpExclusionList)
  534. {
  535. FreeMem(vlplpExclusionList);
  536. }
  537. }
  538. vlplpExclusionList = lplpListArray;
  539. vcntExclusionListEntries = dwCount;
  540. iRet = 0;
  541. break;
  542. case CSHADOW_LIST_TYPE_CONSERVE_BW:
  543. if(vlplpBandwidthConservationList != vrgwBandwidthConservationListDef)
  544. {
  545. if (vlplpBandwidthConservationList)
  546. {
  547. FreeMem(vlplpBandwidthConservationList);
  548. }
  549. }
  550. vlplpBandwidthConservationList = lplpListArray;
  551. vcntBandwidthConservationListEntries = dwCount;
  552. iRet = 0;
  553. break;
  554. default:
  555. break;
  556. }
  557. }
  558. }
  559. }
  560. if (iRet == -1)
  561. {
  562. if (lplpListArray)
  563. {
  564. FreeMem(lplpListArray);
  565. }
  566. }
  567. return (iRet);
  568. }
  569. VOID FreeLists(
  570. VOID
  571. )
  572. /*++
  573. Routine Description:
  574. Free the user associated lists and set them back to the default
  575. Parameters:
  576. None
  577. Return Value:
  578. None
  579. Notes:
  580. Called while shutting down the database
  581. --*/
  582. {
  583. if(vlplpExclusionList != vrgwExclusionListDef)
  584. {
  585. if (vlplpExclusionList)
  586. {
  587. FreeMem(vlplpExclusionList);
  588. vlplpExclusionList = NULL;
  589. }
  590. vlplpExclusionList = vrgwExclusionListDef;
  591. vcntExclusionListEntries = (sizeof(vrgwExclusionListDef)/sizeof(USHORT *));
  592. }
  593. if(vlplpBandwidthConservationList != vrgwBandwidthConservationListDef)
  594. {
  595. if (vlplpBandwidthConservationList)
  596. {
  597. FreeMem(vlplpBandwidthConservationList);
  598. vlplpBandwidthConservationList = NULL;
  599. }
  600. vcntBandwidthConservationListEntries = 0;
  601. }
  602. }
  603. int BeginInodeTransactionHSHADOW(
  604. VOID
  605. )
  606. /*++
  607. Routine Description:
  608. Parameters:
  609. Return Value:
  610. Notes:
  611. This routine ensures that an inode is not reused while this is happening. It is used by various APIs so that while they
  612. are travesring a hierarchy, they don't end up pointing somewhere else if they refer to an inode.
  613. --*/
  614. {
  615. if (!lpdbShadow)
  616. {
  617. SetLastErrorLocal(ERROR_SERVICE_NOT_ACTIVE);
  618. return -1;
  619. }
  620. BeginInodeTransaction();
  621. return 1;
  622. }
  623. int EndInodeTransactionHSHADOW(
  624. VOID
  625. )
  626. /*++
  627. Routine Description:
  628. Parameters:
  629. Return Value:
  630. Notes:
  631. The converse of BeginInodeTransaction. The timespan betwen the two is supposed to be very short (20 sec).
  632. --*/
  633. {
  634. if (!lpdbShadow)
  635. {
  636. SetLastErrorLocal(ERROR_SERVICE_NOT_ACTIVE);
  637. return -1;
  638. }
  639. EndInodeTransaction();
  640. return 1;
  641. }
  642. HSHADOW HAllocShadowID( HSHADOW hDir,
  643. BOOL fFile
  644. )
  645. /*++
  646. Routine Description:
  647. Parameters:
  648. Return Value:
  649. Notes:
  650. --*/
  651. {
  652. HSHADOW hShadow;
  653. Assert(vfInShadowCrit != 0);
  654. hShadow = UlAllocInode(lpdbShadow, hDir, fFile);
  655. return (hShadow);
  656. }
  657. int FreeShadowID( HSHADOW hShadow
  658. )
  659. /*++
  660. Routine Description:
  661. Parameters:
  662. Return Value:
  663. Notes:
  664. --*/
  665. {
  666. return(FreeInode(lpdbShadow, hShadow));
  667. }
  668. int GetShadowSpaceInfo(
  669. LPSHADOWSTORE lpShSt
  670. )
  671. /*++
  672. Routine Description:
  673. Parameters:
  674. Return Value:
  675. Notes:
  676. --*/
  677. {
  678. SHAREHEADER sSH;
  679. if (ReadShareHeader(lpdbShadow, &sSH) < SRET_OK)
  680. return SRET_ERROR;
  681. lpShSt->sMax = sSH.sMax;
  682. lpShSt->sCur = sSH.sCur;
  683. lpShSt->uFlags= sSH.uFlags;
  684. return SRET_OK;
  685. }
  686. int SetMaxShadowSpace(
  687. long nFileSizeHigh,
  688. long nFileSizeLow
  689. )
  690. /*++
  691. Routine Description:
  692. Parameters:
  693. Return Value:
  694. Notes:
  695. --*/
  696. {
  697. SHAREHEADER sSH;
  698. if (ReadShareHeader(lpdbShadow, &sSH) < SRET_OK)
  699. return SRET_ERROR;
  700. Win32ToDosFileSize(nFileSizeHigh, nFileSizeLow, &(sSH.sMax.ulSize));
  701. if (WriteShareHeader(lpdbShadow, &sSH) < SRET_OK)
  702. return SRET_ERROR;
  703. return SRET_OK;
  704. }
  705. int AdjustShadowSpace(
  706. long nFileSizeHighOld,
  707. long nFileSizeLowOld,
  708. long nFileSizeHighNew,
  709. long nFileSizeLowNew,
  710. BOOL fFile
  711. )
  712. /*++
  713. Routine Description:
  714. Parameters:
  715. Return Value:
  716. Notes:
  717. --*/
  718. {
  719. DWORD dwFileSizeNew, dwFileSizeOld;
  720. STOREDATA sSD;
  721. int iRet = 0;
  722. memset(&sSD, 0, sizeof(STOREDATA));
  723. dwFileSizeNew = RealFileSize(nFileSizeLowNew);
  724. dwFileSizeOld = RealFileSize(nFileSizeLowOld);
  725. if (dwFileSizeNew > dwFileSizeOld)
  726. {
  727. sSD.ulSize = dwFileSizeNew - dwFileSizeOld;
  728. iRet = AddStoreData(lpdbShadow, &sSD);
  729. }
  730. else if (dwFileSizeNew < dwFileSizeOld)
  731. {
  732. sSD.ulSize = dwFileSizeOld - dwFileSizeNew;
  733. iRet = SubtractStoreData(lpdbShadow, &sSD);
  734. }
  735. return (iRet);
  736. }
  737. int AllocShadowSpace(
  738. long nFileSizeHigh,
  739. long nFileSizeLow,
  740. BOOL fFile
  741. )
  742. /*++
  743. Routine Description:
  744. Parameters:
  745. Return Value:
  746. Notes:
  747. --*/
  748. {
  749. STOREDATA sSD;
  750. memset(&sSD, 0, sizeof(STOREDATA));
  751. sSD.ulSize = RealFileSize(nFileSizeLow);
  752. AddStoreData(lpdbShadow, &sSD);
  753. return (0);
  754. }
  755. int FreeShadowSpace(
  756. long nFileSizeHigh,
  757. long nFileSizeLow,
  758. BOOL fFile
  759. )
  760. /*++
  761. Routine Description:
  762. Parameters:
  763. Return Value:
  764. Notes:
  765. --*/
  766. {
  767. STOREDATA sSD;
  768. memset(&sSD, 0, sizeof(STOREDATA));
  769. sSD.ulSize = RealFileSize(nFileSizeLow);
  770. SubtractStoreData(lpdbShadow, &sSD);
  771. return (0);
  772. }
  773. int
  774. SetDatabaseStatus(
  775. ULONG ulStatus,
  776. ULONG uMask
  777. )
  778. /*++
  779. Routine Description:
  780. Parameters:
  781. Return Value:
  782. Notes:
  783. --*/
  784. {
  785. SHAREHEADER sSH;
  786. if (ReadShareHeader(lpdbShadow, &sSH) < SRET_OK)
  787. return SRET_ERROR;
  788. sSH.uFlags &= ~uMask;
  789. sSH.uFlags |= ulStatus;
  790. if (WriteShareHeader(lpdbShadow, &sSH) < SRET_OK)
  791. return SRET_ERROR;
  792. vulDatabaseStatus = sSH.uFlags;
  793. return SRET_OK;
  794. }
  795. int
  796. GetDatabaseInfo(
  797. SHAREHEADER *psSH
  798. )
  799. /*++
  800. Routine Description:
  801. Parameters:
  802. Return Value:
  803. Notes:
  804. --*/
  805. {
  806. if (ReadShareHeader(lpdbShadow, psSH) < SRET_OK)
  807. return SRET_ERROR;
  808. return SRET_OK;
  809. }
  810. int GetLocalNameHSHADOW( HSHADOW hShadow,
  811. LPBYTE lpName,
  812. int cbSize,
  813. BOOL fExternal
  814. )
  815. /*++
  816. Routine Description:
  817. Parameters:
  818. Return Value:
  819. Notes:
  820. --*/
  821. {
  822. LPSTR lpszName, lpT;
  823. int iRet = SRET_ERROR;
  824. lpT = lpszName = FormNameString(lpdbShadow, hShadow);
  825. if (!lpszName)
  826. {
  827. return (SRET_ERROR);
  828. }
  829. if (fExternal)
  830. {
  831. #ifdef CSC_RECORDMANAGER_WINNT
  832. lpT = lpszName + (sizeof(NT_DB_PREFIX)-1);
  833. #endif
  834. }
  835. // bad interface, caller can't know what the problem was; needed to send in a pointer to cbSize
  836. if (strlen(lpT) < ((ULONG)cbSize))
  837. {
  838. strcpy(lpName, lpT);
  839. iRet = SRET_OK;
  840. }
  841. FreeNameString(lpszName);
  842. return iRet;
  843. }
  844. int GetWideCharLocalNameHSHADOW(
  845. HSHADOW hShadow,
  846. USHORT *lpBuffer,
  847. LPDWORD lpdwSize,
  848. BOOL fExternal
  849. )
  850. /*++
  851. Routine Description:
  852. Parameters:
  853. Return Value:
  854. Notes:
  855. --*/
  856. {
  857. LPSTR lpszName, lpT;
  858. int iRet = SRET_ERROR;
  859. DWORD dwRequiredSize;
  860. lpT = lpszName = FormNameString(lpdbShadow, hShadow);
  861. if (!lpszName)
  862. {
  863. return (SRET_ERROR);
  864. }
  865. if (fExternal)
  866. {
  867. #ifdef CSC_RECORDMANAGER_WINNT
  868. lpT = lpszName + (sizeof(NT_DB_PREFIX)-1);
  869. #endif
  870. }
  871. dwRequiredSize = (strlen(lpT)+1)*sizeof(USHORT);
  872. // bad interface, caller can't know what the problem was; needed to send in a pointer to cbSize
  873. if ( dwRequiredSize <= *lpdwSize)
  874. {
  875. BCSToUni(lpBuffer, lpT, dwRequiredSize/sizeof(USHORT), BCS_WANSI);
  876. iRet = SRET_OK;
  877. }
  878. else
  879. {
  880. SetLastErrorLocal(ERROR_MORE_DATA);
  881. *lpdwSize = dwRequiredSize;
  882. }
  883. FreeNameString(lpszName);
  884. return iRet;
  885. }
  886. int CreateFileHSHADOW(
  887. HSHADOW hShadow
  888. )
  889. /*++
  890. Routine Description:
  891. Parameters:
  892. Return Value:
  893. Notes:
  894. --*/
  895. {
  896. CSCHFILE hf;
  897. LPSTR lpszName;
  898. int iRet = SRET_ERROR;
  899. ULONG ulAttrib = 0;
  900. lpszName = FormNameString(lpdbShadow, hShadow);
  901. if (!lpszName)
  902. {
  903. return (SRET_ERROR);
  904. }
  905. // Nuke it if it exists, this is a very strict semantics
  906. if(DeleteFileLocal(lpszName, ATTRIB_DEL_ANY) < SRET_OK)
  907. {
  908. if((GetLastErrorLocal() !=ERROR_FILE_NOT_FOUND) &&
  909. (GetLastErrorLocal() !=ERROR_PATH_NOT_FOUND))
  910. {
  911. FreeNameString(lpszName);
  912. return (SRET_ERROR);
  913. }
  914. }
  915. ulAttrib = ((IsLeaf(hShadow) && mDatabaseEncryptionEnabled(vulDatabaseStatus))? FILE_ATTRIBUTE_ENCRYPTED:0);
  916. if ((hf = R0OpenFileEx(ACCESS_READWRITE, ACTION_CREATEALWAYS, ulAttrib, lpszName, FALSE)))
  917. {
  918. CloseFileLocal(hf);
  919. iRet = SRET_OK;
  920. }
  921. FreeNameString(lpszName);
  922. return iRet;
  923. }
  924. #if defined(BITCOPY)
  925. int OpenFileHSHADOWAndCscBmp(
  926. HSHADOW hShadow,
  927. USHORT usOpenFlags,
  928. UCHAR bAction,
  929. CSCHFILE far *lphf,
  930. BOOL fOpenCscBmp,
  931. DWORD filesize, // if !fOpenCscBmp this field is ignored
  932. LPCSC_BITMAP * lplpbitmap
  933. )
  934. #else
  935. int OpenFileHSHADOW(
  936. HSHADOW hShadow,
  937. USHORT usOpenFlags,
  938. UCHAR bAction,
  939. CSCHFILE far *lphf
  940. )
  941. #endif // defined(BITCOPY)
  942. /*++
  943. Routine Description:
  944. Parameters:
  945. Return Value:
  946. Notes:
  947. --*/
  948. {
  949. LPSTR lpszName = NULL;
  950. int iRet = SRET_ERROR;
  951. ULONG ulAttrib = 0;
  952. *lphf = NULL;
  953. lpszName = FormNameString(lpdbShadow, hShadow);
  954. if (!lpszName)
  955. return (SRET_ERROR);
  956. if (!(bAction & (ACTION_NEXISTS_CREATE|ACTION_CREATEALWAYS))) {
  957. *lphf = OpenFileLocal(lpszName);
  958. if (*lphf != NULL) {
  959. #if defined(BITCOPY)
  960. if (fOpenCscBmp)
  961. CscBmpRead(lplpbitmap, lpszName, filesize);
  962. #endif // defined(BITCOPY)
  963. iRet = SRET_OK;
  964. }
  965. } else {
  966. // Nuke it if it exists, this is a very strict semantics
  967. if (DeleteFileLocal(lpszName, ATTRIB_DEL_ANY) < SRET_OK) {
  968. if ((GetLastErrorLocal() != ERROR_FILE_NOT_FOUND) &&
  969. (GetLastErrorLocal() != ERROR_PATH_NOT_FOUND)) {
  970. iRet = SRET_ERROR;
  971. goto Cleanup;
  972. }
  973. }
  974. ulAttrib = 0;
  975. if (IsLeaf(hShadow) && mDatabaseEncryptionEnabled(vulDatabaseStatus))
  976. ulAttrib = FILE_ATTRIBUTE_ENCRYPTED;
  977. *lphf = R0OpenFileEx(
  978. ACCESS_READWRITE,
  979. ACTION_CREATEALWAYS,
  980. ulAttrib,
  981. lpszName,
  982. FALSE);
  983. if (*lphf != NULL) {
  984. #if defined(BITCOPY)
  985. if (fOpenCscBmp)
  986. CscBmpRead(lplpbitmap, lpszName, 0);
  987. #endif // defined(BITCOPY)
  988. iRet = SRET_OK;
  989. }
  990. }
  991. Cleanup:
  992. if (lpszName != NULL)
  993. FreeNameString(lpszName);
  994. return iRet;
  995. }
  996. #if defined(BITCOPY)
  997. int
  998. OpenCscBmp(
  999. HSHADOW hShadow,
  1000. LPCSC_BITMAP *lplpbitmap)
  1001. {
  1002. LPSTR strmName = NULL;
  1003. int iRet = SRET_ERROR;
  1004. ULONG fileSizeLow;
  1005. ULONG fileSizeHigh;
  1006. strmName = FormAppendNameString(lpdbShadow, hShadow, CscBmpAltStrmName);
  1007. if (strmName == NULL)
  1008. return (SRET_ERROR);
  1009. if (GetSizeHSHADOW(hShadow, &fileSizeHigh, &fileSizeLow) < SRET_OK)
  1010. fileSizeLow = 0; // Set the bitmap size to 0 so it can expand later on
  1011. if (CscBmpRead(lplpbitmap, strmName, fileSizeLow) == 1)
  1012. iRet = SRET_OK;
  1013. FreeNameString(strmName);
  1014. return iRet;
  1015. }
  1016. #endif // defined(BITCOPY)
  1017. int GetSizeHSHADOW( HSHADOW hShadow,
  1018. ULONG *lpnFileSizeHigh,
  1019. ULONG *lpnFileSizeLow
  1020. )
  1021. /*++
  1022. Routine Description:
  1023. Parameters:
  1024. Return Value:
  1025. Notes:
  1026. --*/
  1027. {
  1028. ULONG uSize;
  1029. if (GetInodeFileSize(lpdbShadow, hShadow, &uSize) < SRET_OK)
  1030. return SRET_ERROR;
  1031. DosToWin32FileSize(uSize, lpnFileSizeHigh, lpnFileSizeLow);
  1032. return (0);
  1033. }
  1034. int GetDosTypeSizeHSHADOW( HSHADOW hShadow,
  1035. ULONG *lpFileSize
  1036. )
  1037. /*++
  1038. Routine Description:
  1039. Parameters:
  1040. Return Value:
  1041. Notes:
  1042. --*/
  1043. {
  1044. if (GetInodeFileSize(lpdbShadow, hShadow, lpFileSize) < SRET_OK)
  1045. return SRET_ERROR;
  1046. return (0);
  1047. }
  1048. BOOL PUBLIC
  1049. ExcludeFromCreateShadow(
  1050. USHORT *lpuName,
  1051. ULONG len,
  1052. BOOL fCheckFileTypeExclusionList
  1053. )
  1054. /*++
  1055. Routine Description:
  1056. Parameters:
  1057. lpuName File name
  1058. len size
  1059. fCheckFileTypeExclusionList if !FALSE, check exclusion list as well as the metacharacter rules
  1060. if FALSE check only the character exclusion rules
  1061. Return Value:
  1062. Notes:
  1063. --*/
  1064. {
  1065. ULONG i;
  1066. USHORT *lpuT1;
  1067. BOOL fRet = FALSE;
  1068. if (!len || (len> MAX_PATH))
  1069. {
  1070. return TRUE;
  1071. }
  1072. UseGlobalFilerecExt();
  1073. lpuT1 = (USHORT *)&vsFRExt;
  1074. memcpy(lpuT1, lpuName, len * sizeof(USHORT));
  1075. lpuT1[len] = 0;
  1076. if (!wstrpbrk(lpuT1, vtzExcludedCharsList))
  1077. {
  1078. //
  1079. if (fCheckFileTypeExclusionList)
  1080. {
  1081. for (i=0; i< vcntExclusionListEntries; ++i)
  1082. {
  1083. if(IFSMgr_MetaMatch(vlplpExclusionList[i], lpuT1, UFLG_NT|UFLG_META))
  1084. {
  1085. fRet = TRUE;
  1086. break;
  1087. }
  1088. }
  1089. }
  1090. }
  1091. else
  1092. {
  1093. fRet = TRUE; // exclude
  1094. }
  1095. UnUseGlobalFilerecExt();
  1096. return fRet;
  1097. }
  1098. BOOL PUBLIC
  1099. CheckForBandwidthConservation(
  1100. USHORT *lpuName,
  1101. ULONG len
  1102. )
  1103. /*++
  1104. Routine Description:
  1105. Parameters:
  1106. Return Value:
  1107. Notes:
  1108. --*/
  1109. {
  1110. ULONG i;
  1111. USHORT *lpuT1;
  1112. BOOL fRet = FALSE;
  1113. if (!len || (len> MAX_PATH))
  1114. {
  1115. return FALSE;
  1116. }
  1117. UseGlobalFilerecExt();
  1118. lpuT1 = (USHORT *)&vsFRExt;
  1119. memcpy(lpuT1, lpuName, len * sizeof(USHORT));
  1120. lpuT1[len] = 0;
  1121. for (i=0; i< vcntBandwidthConservationListEntries; ++i)
  1122. {
  1123. if(IFSMgr_MetaMatch(vlplpBandwidthConservationList[i], lpuT1, UFLG_NT|UFLG_META))
  1124. {
  1125. fRet = TRUE;
  1126. break;
  1127. }
  1128. }
  1129. UnUseGlobalFilerecExt();
  1130. return fRet;
  1131. }
  1132. int PUBLIC // ret
  1133. CreateShadow( //
  1134. HSHADOW hDir,
  1135. LPFIND32 lpFind32,
  1136. ULONG uFlags,
  1137. LPHSHADOW lphNew,
  1138. BOOL *lpfCreated
  1139. )
  1140. /*++
  1141. Routine Description:
  1142. Parameters:
  1143. Return Value:
  1144. Notes:
  1145. --*/
  1146. {
  1147. ULONG uStatus;
  1148. int iRet = SRET_ERROR;
  1149. Assert(vfInShadowCrit != 0);
  1150. if (lpfCreated)
  1151. {
  1152. *lpfCreated = FALSE;
  1153. }
  1154. mClearBits(uFlags, SHADOW_NOT_FSOBJ);
  1155. if (GetShadow(hDir, lpFind32->cFileName, lphNew, NULL, &uStatus, NULL)>=SRET_OK)
  1156. {
  1157. if (*lphNew)
  1158. {
  1159. CShadowKdPrint(ALWAYS,("CreateShadow: already exists for %ws\r\n", lpFind32->cFileName));
  1160. if (mNotFsobj(uStatus))
  1161. {
  1162. iRet = SRET_ERROR;
  1163. }
  1164. else
  1165. {
  1166. iRet = SetShadowInfo(hDir, *lphNew, lpFind32, uFlags, SHADOW_FLAGS_ASSIGN);
  1167. }
  1168. }
  1169. else
  1170. {
  1171. iRet = CreateShadowInternal(hDir, lpFind32, uFlags, NULL, lphNew);
  1172. if ((iRet >= SRET_OK) && lpfCreated)
  1173. {
  1174. *lpfCreated = TRUE;
  1175. }
  1176. }
  1177. }
  1178. return (iRet);
  1179. }
  1180. int PUBLIC // ret
  1181. CreateShadowInternal(
  1182. HSHADOW hDir,
  1183. LPFIND32 lpFind32,
  1184. ULONG uFlags,
  1185. LPOTHERINFO lpOI,
  1186. LPHSHADOW lphNew
  1187. )
  1188. /*++
  1189. Routine Description:
  1190. Routine that creates database entries for all names other than the root of a share
  1191. HCreateShareObj deals with createing the share entry where the root of the share gets created
  1192. Parameters:
  1193. hDir Directory inode in which to create the entry
  1194. lpFind32 WIN32_FIND_DATA info to be kept in the database
  1195. uFlags status flags (SHADOW_XXXX in csc\inc\shdcom.h) to be assigned to this entry
  1196. lpOI all the rest of the metadata needed for managing the entry. May be NULL
  1197. lphNew out parameter, returns the inode that was created if successful
  1198. Return Value:
  1199. Notes:
  1200. --*/
  1201. {
  1202. PRIQREC sPQ;
  1203. int iRet = SRET_ERROR;
  1204. LPFILERECEXT lpFR = NULL, lpFRUse;
  1205. HSHADOW hNew=0, hAncestor=0;
  1206. HSHARE hShare=0;
  1207. ULONG ulRefPri=MAX_PRI, ulrecDirEntry=INVALID_REC, ulHintPri=0, ulHintFlags=0;
  1208. STOREDATA sSD;
  1209. Assert(vfInShadowCrit != 0);
  1210. if (!(!hDir || IsDirInode(hDir)))
  1211. return SRET_ERROR;
  1212. BEGIN_TIMING(CreateShadowInternal);
  1213. if (InuseGlobalFRExt())
  1214. {
  1215. if (!(lpFR = (LPFILERECEXT)AllocMem(sizeof(FILERECEXT))))
  1216. goto bailout;
  1217. lpFRUse = lpFR;
  1218. }
  1219. else
  1220. {
  1221. UseGlobalFilerecExt();
  1222. lpFRUse = &vsFRExt;
  1223. }
  1224. memset(lpFRUse, 0, sizeof(FILERECEXT));
  1225. // Don't do anything for server yet
  1226. if (hDir)
  1227. {
  1228. *lphNew = hNew = UlAllocInode(lpdbShadow, hDir, IsFile(lpFind32->dwFileAttributes));
  1229. if (!hNew)
  1230. {
  1231. CShadowKdPrint(BADERRORS,("Error creating shadow Inode\r\n"));
  1232. goto bailout;
  1233. }
  1234. if (IsFile(lpFind32->dwFileAttributes))
  1235. {
  1236. if (lpFind32->nFileSizeHigh)
  1237. {
  1238. SetLastErrorLocal(ERROR_ONLY_IF_CONNECTED);
  1239. goto bailout;
  1240. }
  1241. if(CreateFileHSHADOW(hNew) == SRET_ERROR)
  1242. {
  1243. CShadowKdPrint(BADERRORS,("Error creating shadow data for %x \r\n", hNew));
  1244. goto bailout;
  1245. }
  1246. // start file priorities with max
  1247. ulRefPri=MAX_PRI;
  1248. }
  1249. else
  1250. {
  1251. if(CreateDirInode(lpdbShadow, 0, hDir, hNew) < 0)
  1252. {
  1253. CShadowKdPrint(BADERRORS,("Error creating shadow data for %x \r\n", hNew));
  1254. goto bailout;
  1255. }
  1256. // start directory priorities with MIN_PRI, this is to optimize
  1257. // later moving
  1258. // A better solution might be to change createshadow to take refpri and pincount
  1259. // as parameters
  1260. ulRefPri=MIN_PRI;
  1261. }
  1262. CopyFindInfoToFilerec(lpFind32, lpFRUse, CPFR_INITREC|CPFR_COPYNAME);
  1263. //RxDbgTrace(0,Dbg,("CreateShadowInternal3 %s %s\n",
  1264. // lpFRUse->sFR.rgcName, lpFRUse->sFR.rg83Name));
  1265. lpFRUse->sFR.uchRefPri = (UCHAR)ulRefPri;
  1266. lpFRUse->sFR.uchHintPri = (UCHAR)ulHintPri;
  1267. lpFRUse->sFR.uchHintFlags = (UCHAR)ulHintFlags;
  1268. // overwite filerec with any info that the user gave
  1269. if (lpOI)
  1270. {
  1271. CShadowKdPrint(CREATESHADOWHI,("ulHintPri=%x ulHintFlags=%x\r\n",lpOI->ulHintPri, lpOI->ulHintFlags));
  1272. CopyOtherInfoToFilerec(lpOI, lpFRUse);
  1273. }
  1274. lpFRUse->sFR.ftOrgTime = lpFRUse->sFR.ftLastWriteTime;
  1275. CShadowKdPrint(CREATESHADOWHI,("CreateShadow: %x for %ws: loctLo=%x loctHi=%x \r\n",
  1276. hNew,
  1277. lpFRUse->sFR.rgwName,
  1278. lpFRUse->sFR.ftOrgTime.dwLowDateTime,
  1279. lpFRUse->sFR.ftOrgTime.dwHighDateTime));
  1280. lpFRUse->sFR.ulidShadow = hNew;
  1281. lpFRUse->sFR.uStatus = (USHORT)uFlags;
  1282. lpFRUse->sFR.ulLastRefreshTime = (ULONG)IFSMgr_Get_NetTime();
  1283. // if this entry is being created offline, then it doesn't have any original inode
  1284. if (uFlags & SHADOW_LOCALLY_CREATED)
  1285. {
  1286. lpFRUse->sFR.ulidShadowOrg = 0;
  1287. }
  1288. else
  1289. {
  1290. lpFRUse->sFR.ulidShadowOrg = hNew;
  1291. }
  1292. #ifdef DEBUG
  1293. ValidatePri(lpFRUse);
  1294. #endif
  1295. if(!(ulrecDirEntry = AddFileRecordFR(lpdbShadow, hDir, lpFRUse)))
  1296. {
  1297. // could be legit failure if we are running out of disk space
  1298. CShadowKdPrint(CREATESHADOWHI,("Failed AddFileRecordFR for %x, %ws\r\n",
  1299. hNew,
  1300. lpFRUse->sFR.rgwName));
  1301. goto bailout;
  1302. }
  1303. Assert(ulrecDirEntry != INVALID_REC);
  1304. if(FindAncestorsFromInode(lpdbShadow, hDir, &hAncestor, &hShare) < 0)
  1305. {
  1306. CShadowKdPrint(CREATESHADOWHI,("Failed to find ancestor for %x, %ws\r\n",
  1307. hNew,
  1308. lpFRUse->sFR.rgwName));
  1309. goto bailout;
  1310. }
  1311. // mark the inode as locally created or not
  1312. // NB, this flag has meaning only for the inode
  1313. // We use this information during reintegration of
  1314. // renames and deletes
  1315. if (uFlags & SHADOW_LOCALLY_CREATED)
  1316. {
  1317. uFlags |= SHADOW_LOCAL_INODE;
  1318. }
  1319. else
  1320. {
  1321. uFlags &= ~SHADOW_LOCAL_INODE;
  1322. }
  1323. if (AddPriQRecord( lpdbShadow,
  1324. hShare,
  1325. hDir,
  1326. hNew,
  1327. uFlags,
  1328. (ULONG)(lpFRUse->sFR.uchRefPri),
  1329. (ULONG)(lpFRUse->sFR.uchIHPri),
  1330. (ULONG)(lpFRUse->sFR.uchHintPri),
  1331. (ULONG)(lpFRUse->sFR.uchHintFlags),
  1332. ulrecDirEntry) < 0)
  1333. {
  1334. CShadowKdPrint(CREATESHADOWHI,("Failed to AddPriQRecord for %x, %ws\r\n",
  1335. hNew,
  1336. lpFRUse->sFR.rgwName));
  1337. Assert(FALSE);
  1338. goto bailout;
  1339. }
  1340. // The check below was is a holdover from our now-defunct hints scheme
  1341. if (!mNotFsobj(lpFRUse->sFR.uStatus))
  1342. {
  1343. memset(&sSD, 0, sizeof(STOREDATA));
  1344. CShadowKdPrint(CREATESHADOWHI,("uchHintPri=%x uchHintFlags=%x\r\n",lpFRUse->sFR.uchHintPri, lpFRUse->sFR.uchHintFlags));
  1345. if ((!(lpFind32->dwFileAttributes &
  1346. (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE))))
  1347. {
  1348. sSD.ucntFiles++;
  1349. // if there is a initial pin count or special pinflags are set
  1350. // then this files data should not be considered for space accounting
  1351. sSD.ulSize = (lpFRUse->sFR.uchHintPri || mPinFlags(lpFRUse->sFR.uchHintFlags))?0:RealFileSize(lpFRUse->sFR.ulFileSize);
  1352. }
  1353. else
  1354. {
  1355. sSD.ucntDirs++;
  1356. }
  1357. if (sSD.ulSize)
  1358. {
  1359. CShadowKdPrint(STOREDATA,("CreateShadowInternal: Adding %d for hDir=%x Name=%ws\r\n", sSD.ulSize, hDir, lpFind32->cFileName));
  1360. }
  1361. else
  1362. {
  1363. if ((!(lpFind32->dwFileAttributes &
  1364. (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE)))
  1365. && RealFileSize(lpFRUse->sFR.ulFileSize)
  1366. )
  1367. {
  1368. Assert((lpFRUse->sFR.uchHintPri || mPinFlags(lpFRUse->sFR.uchHintFlags)));
  1369. }
  1370. }
  1371. AddStoreData(lpdbShadow, &sSD);
  1372. AdjustSparseStaleDetectionCount(hShare, lpFRUse);
  1373. }
  1374. vdwCSCNameSpaceVersion++;
  1375. vdwPQVersion++;
  1376. iRet = SRET_OK;
  1377. }
  1378. bailout:
  1379. if (iRet==SRET_ERROR)
  1380. {
  1381. if (hNew)
  1382. {
  1383. FreeInode(lpdbShadow, hNew);
  1384. }
  1385. }
  1386. if (lpFR)
  1387. FreeMem(lpFR);
  1388. else
  1389. UnUseGlobalFilerecExt();
  1390. END_TIMING(CreateShadowInternal);
  1391. return iRet;
  1392. }
  1393. int
  1394. DeleteShadow(
  1395. HSHADOW hDir,
  1396. HSHADOW hShadow
  1397. )
  1398. /*++
  1399. Routine Description:
  1400. Parameters:
  1401. Return Value:
  1402. Notes:
  1403. --*/
  1404. {
  1405. return DeleteShadowInternal(hDir, hShadow, FALSE); // try a gentle delete
  1406. }
  1407. ULONG DelShadowInternalEntries = 0;
  1408. #define JOE_DECL_CURRENT_PROGRESS CscProgressDelShdwI
  1409. JOE_DECL_PROGRESS();
  1410. int
  1411. DeleteShadowInternal( //
  1412. HSHADOW hDir,
  1413. HSHADOW hShadow,
  1414. BOOL fForce
  1415. )
  1416. /*++
  1417. Routine Description:
  1418. Parameters:
  1419. Return Value:
  1420. Notes:
  1421. --*/
  1422. {
  1423. STOREDATA sSD;
  1424. int iRet= SRET_ERROR;
  1425. PRIQREC sPQ;
  1426. LPFILERECEXT lpFR = NULL, lpFRUse;
  1427. Assert(vfInShadowCrit != 0);
  1428. DelShadowInternalEntries++;
  1429. JOE_INIT_PROGRESS(DelShadowInternalEntries,&hDir);
  1430. if (InuseGlobalFRExt())
  1431. {
  1432. if (!(lpFR = (LPFILERECEXT)AllocMem(sizeof(FILERECEXT))))
  1433. goto bailout;
  1434. lpFRUse = lpFR;
  1435. }
  1436. else
  1437. {
  1438. UseGlobalFilerecExt();
  1439. lpFRUse = &vsFRExt;
  1440. }
  1441. if (!hDir)
  1442. {
  1443. if(FindSharerecFromInode(lpdbShadow, hShadow, (LPSHAREREC)lpFRUse))
  1444. {
  1445. if (fForce || !HasDescendents(lpdbShadow, 0, ((LPSHAREREC)lpFRUse)->ulidShadow))
  1446. {
  1447. iRet = DestroyShareInternal((LPSHAREREC)lpFRUse);
  1448. }
  1449. }
  1450. }
  1451. else
  1452. {
  1453. int iRetInner;
  1454. //ASSERT(hShadow!=0);
  1455. JOE_PROGRESS(2);
  1456. if (!fForce && // not being forced
  1457. !FInodeIsFile(lpdbShadow, hDir, hShadow) && // and it is a dir
  1458. HasDescendents(lpdbShadow, hDir, hShadow)) // and has descendents
  1459. {
  1460. JOE_PROGRESS(3);
  1461. CShadowKdPrint(DELETESHADOWBAD,("DeleteShadow: Trying to delete a directory with descendents \r\n"));
  1462. SetLastErrorLocal(ERROR_DIR_NOT_EMPTY);
  1463. goto bailout;
  1464. }
  1465. JOE_PROGRESS(4);
  1466. if(FindPriQRecord(lpdbShadow, hDir, hShadow, &sPQ)<=0)
  1467. {
  1468. JOE_PROGRESS(5);
  1469. CShadowKdPrint(DELETESHADOWBAD,("DeleteShadow: Trying to delete a noexistent inode %x \r\n", hShadow));
  1470. SetLastErrorLocal(ERROR_FILE_NOT_FOUND);
  1471. goto bailout;
  1472. }
  1473. Assert(hShadow == sPQ.ulidShadow);
  1474. DeleteFromHandleCache(hShadow);
  1475. iRetInner = DeleteInodeFile(lpdbShadow, hShadow);
  1476. if(iRetInner<0){
  1477. if (GetLastErrorLocal() != ERROR_FILE_NOT_FOUND)
  1478. {
  1479. CShadowKdPrint(DELETESHADOWBAD,("DeleteShadow: delete stent inode %x \r\n", hShadow));
  1480. goto bailout;
  1481. }
  1482. }
  1483. JOE_PROGRESS(6);
  1484. if(DeleteFileRecFromInode(lpdbShadow, hDir, hShadow, sPQ.ulrecDirEntry, lpFRUse) == 0L)
  1485. {
  1486. JOE_PROGRESS(7);
  1487. CShadowKdPrint(DELETESHADOWBAD,("DeleteShadow:DeleteFileRecord failed \r\n"));
  1488. goto bailout;
  1489. }
  1490. JOE_PROGRESS(8);
  1491. Assert(hShadow == lpFRUse->sFR.ulidShadow);
  1492. JOE_PROGRESS(11);
  1493. // No error checking is done on the following call as they
  1494. // are benign errors.
  1495. iRetInner = DeletePriQRecord(lpdbShadow, hDir, hShadow, &sPQ);
  1496. if(iRetInner>=0){
  1497. JOE_PROGRESS(12);
  1498. CShadowKdPrint(DELETESHADOWBAD,("DeleteShadow priq %d\n", iRetInner));
  1499. }
  1500. JOE_PROGRESS(13);
  1501. memset((LPVOID)&sSD, 0, sizeof(STOREDATA));
  1502. // Let us deal with only file records for now
  1503. if (!mNotFsobj(lpFRUse->sFR.uStatus))
  1504. {
  1505. if(IsFile(lpFRUse->sFR.dwFileAttrib))
  1506. {
  1507. sSD.ucntFiles++;
  1508. // subtract store data only if it was accounted for in the first place
  1509. sSD.ulSize = (lpFRUse->sFR.uchHintPri || mPinFlags(lpFRUse->sFR.uchHintFlags))
  1510. ? 0 : RealFileSize(lpFRUse->sFR.ulFileSize);
  1511. }
  1512. else
  1513. {
  1514. sSD.ucntDirs++;
  1515. }
  1516. if (sSD.ulSize)
  1517. {
  1518. CShadowKdPrint(STOREDATA,("DeleteShadowInternal:Deleting storedata for hDir=%x Name=%ws\r\n", hDir, lpFRUse->sFR.rgwName));
  1519. }
  1520. SubtractStoreData(lpdbShadow, &sSD);
  1521. }
  1522. if (!FInodeIsFile(lpdbShadow, hDir, hShadow) && lpDeleteCBForIoctl)
  1523. {
  1524. (*lpDeleteCBForIoctl)(hDir, hShadow);
  1525. }
  1526. // we don't care if this fails because then the worst
  1527. // that can happen is that this inode will be permanenetly lost.
  1528. // Checkdisk utility should recover this.
  1529. JOE_PROGRESS(14);
  1530. FreeInode(lpdbShadow, hShadow);
  1531. // Yes we did delete a shadow
  1532. iRet = SRET_OK;
  1533. vdwCSCNameSpaceVersion++;
  1534. vdwPQVersion++;
  1535. }
  1536. bailout:
  1537. JOE_PROGRESS(20);
  1538. #if 0 //this insert has errors.........
  1539. #if VERBOSE > 2
  1540. if (iRet==SRET_OK)
  1541. CShadowKdPrint(DELETESHADOWHI,("DeleteShadow: deleted shadow %x for %s\r\n", lpFRUse->sFR.ulidShadow, lpName));
  1542. else
  1543. CShadowKdPrint(DELETESHADOWHI,("DeleteShadow: error deleting shadow for %s\r\n", lpName));
  1544. #endif //VERBOSE > 2
  1545. #endif //if 0 for errors
  1546. if (lpFR)
  1547. FreeMem(lpFR);
  1548. else
  1549. UnUseGlobalFilerecExt();
  1550. JOE_PROGRESS(21);
  1551. return (iRet);
  1552. }
  1553. int TruncateDataHSHADOW(
  1554. HSHADOW hDir,
  1555. HSHADOW hShadow
  1556. )
  1557. /*++
  1558. Routine Description:
  1559. Parameters:
  1560. Return Value:
  1561. Notes:
  1562. --*/
  1563. {
  1564. ULONG uSize=0;
  1565. // long nFileSizeHigh, nFileSizeLow;
  1566. Assert(vfInShadowCrit != 0);
  1567. Assert(!hDir || IsDirInode(hDir));
  1568. if (FInodeIsFile(lpdbShadow, hDir, hShadow))
  1569. {
  1570. // GetInodeFileSize(lpdbShadow, hShadow, &uSize);
  1571. // DosToWin32FileSize(uSize, &nFileSizeHigh, &nFileSizeLow);
  1572. if (TruncateInodeFile(lpdbShadow, hShadow) < SRET_OK)
  1573. return SRET_ERROR;
  1574. // FreeShadowSpace(nFileSizeHigh, nFileSizeLow, IsLeaf(hShadow));
  1575. }
  1576. else
  1577. {
  1578. if (!HasDescendents(lpdbShadow, hDir, hShadow))
  1579. {
  1580. CreateDirInode(lpdbShadow, 0, hDir, hShadow);
  1581. }
  1582. else
  1583. {
  1584. SetLastErrorLocal(ERROR_ACCESS_DENIED);
  1585. return SRET_ERROR;
  1586. }
  1587. }
  1588. return(SRET_OK);
  1589. }
  1590. int PUBLIC
  1591. RenameShadow(
  1592. HSHADOW hDirFrom,
  1593. HSHADOW hShadowFrom,
  1594. HSHADOW hDirTo,
  1595. LPFIND32 lpFind32To,
  1596. ULONG uShadowStatusTo,
  1597. LPOTHERINFO lpOI,
  1598. ULONG uRenameFlags,
  1599. LPHSHADOW lphShadowTo
  1600. )
  1601. /*++
  1602. Routine Description:
  1603. Parameters:
  1604. Return Value:
  1605. Notes:
  1606. --*/
  1607. {
  1608. return (RenameShadowEx(hDirFrom, hShadowFrom, 0, hDirTo, lpFind32To, uShadowStatusTo, lpOI, uRenameFlags, NULL, NULL, lphShadowTo));
  1609. }
  1610. int PUBLIC
  1611. RenameShadowEx(
  1612. HSHADOW hDirFrom,
  1613. HSHADOW hShadowFrom,
  1614. HSHARE hShareTo,
  1615. HSHADOW hDirTo,
  1616. LPFIND32 lpFind32To,
  1617. ULONG uShadowStatusTo,
  1618. LPOTHERINFO lpOI,
  1619. ULONG uRenameFlags,
  1620. LPVOID lpSecurityBlobTo,
  1621. LPDWORD lpdwBlobSizeTo,
  1622. LPHSHADOW lphShadowTo
  1623. )
  1624. /*++
  1625. Routine Description:
  1626. Parameters:
  1627. Return Value:
  1628. Notes:
  1629. --*/
  1630. {
  1631. int iRet = SRET_ERROR;
  1632. HSHADOW hShadowTo;
  1633. LPFILERECEXT lpFR = NULL, lpFRUse;
  1634. BOOL fFile = FInodeIsFile(lpdbShadow, hDirFrom, hShadowFrom);
  1635. Assert(vfInShadowCrit != 0);
  1636. Assert(!hDirFrom || IsDirInode(hDirFrom));
  1637. Assert(!hDirTo || IsDirInode(hDirTo));
  1638. if (InuseGlobalFRExt())
  1639. {
  1640. if (!(lpFR = (LPFILERECEXT)AllocMem(sizeof(FILERECEXT))))
  1641. goto bailout;
  1642. lpFRUse = lpFR;
  1643. }
  1644. else
  1645. {
  1646. UseGlobalFilerecExt();
  1647. lpFRUse = &vsFRExt;
  1648. }
  1649. // If we are keeping the renamer, we are going to have to create
  1650. // a new inode and an empty directory/file
  1651. if (mQueryBits(uRenameFlags, RNMFLGS_MARK_SOURCE_DELETED))
  1652. {
  1653. // Allocate an INODE for the new shadow
  1654. if (!(hShadowTo = UlAllocInode(lpdbShadow, hDirFrom, IsLeaf(hShadowFrom))))
  1655. {
  1656. goto bailout;
  1657. }
  1658. Assert(IsLeaf(hShadowFrom) == IsLeaf(hShadowTo));
  1659. if (!IsLeaf(hShadowTo))
  1660. {
  1661. if(CreateDirInode(lpdbShadow, 0, hDirFrom, hShadowTo) < 0)
  1662. goto bailout;
  1663. }
  1664. else
  1665. {
  1666. if(CreateFileHSHADOW(hShadowTo) < 0)
  1667. {
  1668. goto bailout;
  1669. }
  1670. }
  1671. }
  1672. else
  1673. {
  1674. hShadowTo = 0;
  1675. }
  1676. iRet = RenameDirFileHSHADOW(hDirFrom, hShadowFrom, hShareTo, hDirTo, hShadowTo, uShadowStatusTo, lpOI, uRenameFlags, lpFRUse, lpFind32To, lpSecurityBlobTo, lpdwBlobSizeTo);
  1677. if (lphShadowTo)
  1678. {
  1679. *lphShadowTo = (hShadowTo)?hShadowTo:hShadowFrom;
  1680. }
  1681. bailout:
  1682. if (lpFR)
  1683. FreeMem(lpFR);
  1684. else
  1685. UnUseGlobalFilerecExt();
  1686. return (iRet);
  1687. }
  1688. int RenameDirFileHSHADOW(
  1689. HSHADOW hDirFrom,
  1690. HSHADOW hShadowFrom,
  1691. HSHADOW hShareTo,
  1692. HSHADOW hDirTo,
  1693. HSHADOW hShadowTo,
  1694. ULONG uShadowStatusTo,
  1695. LPOTHERINFO lpOI,
  1696. ULONG uRenameFlags,
  1697. LPFILERECEXT lpFRUse,
  1698. LPFIND32 lpFind32To,
  1699. LPVOID lpSecurityBlobTo,
  1700. LPDWORD lpdwBlobSizeTo
  1701. )
  1702. /*++
  1703. Routine Description:
  1704. Parameters:
  1705. Return Value:
  1706. Notes:
  1707. --*/
  1708. {
  1709. FILEHEADER sFH;
  1710. PRIQREC sPQ;
  1711. int count, iRet = SRET_ERROR;
  1712. LPFILERECEXT lpFRDir = NULL;
  1713. ULONG ulrecDirEntryTo, ulrecDirEntryFrom;
  1714. BOOL fWasPinned=FALSE, fIsPinned=FALSE;
  1715. Assert(lpFind32To);
  1716. if(FindPriQRecord(lpdbShadow, hDirFrom, hShadowFrom, &sPQ)<=0)
  1717. {
  1718. // Assert(FALSE);
  1719. goto bailout;
  1720. }
  1721. ulrecDirEntryFrom = sPQ.ulrecDirEntry;
  1722. if(CShadowFindFilerecFromInode(lpdbShadow, hDirFrom, hShadowFrom, &sPQ, lpFRUse)<=0)
  1723. {
  1724. // Assert(FALSE);
  1725. goto bailout;
  1726. }
  1727. Assert(sPQ.ulidShadow == lpFRUse->sFR.ulidShadow);
  1728. fWasPinned = ((lpFRUse->sFR.uchHintPri || mPinFlags(lpFRUse->sFR.uchHintFlags)) != 0);
  1729. if (mQueryBits(uRenameFlags, RNMFLGS_MARK_SOURCE_DELETED))
  1730. {
  1731. lpFRDir = (LPFILERECEXT)AllocMem(sizeof(FILERECEXT));
  1732. if (!lpFRDir)
  1733. {
  1734. Assert(FALSE);
  1735. goto bailout;
  1736. }
  1737. }
  1738. if (lpFRDir)
  1739. {
  1740. Assert (mQueryBits(uRenameFlags, RNMFLGS_MARK_SOURCE_DELETED));
  1741. // Save it's contents
  1742. *lpFRDir = *lpFRUse;
  1743. }
  1744. // Change the name of hShadowFrom to the new name
  1745. CopyNamesToFilerec(lpFind32To, lpFRUse);
  1746. if (lpOI)
  1747. {
  1748. CopyOtherInfoToFilerec(lpOI, lpFRUse);
  1749. CopyOtherInfoToPQ(lpOI, &sPQ);
  1750. }
  1751. fIsPinned = ((lpFRUse->sFR.uchHintPri || mPinFlags(lpFRUse->sFR.uchHintFlags)) != 0);
  1752. // And it's status as requested by the caller
  1753. lpFRUse->sFR.uStatus = (USHORT)uShadowStatusTo;
  1754. if (uRenameFlags & RNMFLGS_USE_FIND32_TIMESTAMPS)
  1755. {
  1756. lpFRUse->sFR.ftLastWriteTime = lpFind32To->ftLastWriteTime;
  1757. lpFRUse->sFR.ftOrgTime = lpFind32To->ftLastAccessTime;
  1758. }
  1759. // Both SAVE and RETAIN should never be ON
  1760. Assert(mQueryBits(uRenameFlags, (RNMFLGS_SAVE_ALIAS|RNMFLGS_RETAIN_ALIAS))
  1761. !=(RNMFLGS_SAVE_ALIAS|RNMFLGS_RETAIN_ALIAS));
  1762. if (mQueryBits(uRenameFlags, RNMFLGS_SAVE_ALIAS))
  1763. {
  1764. Assert(!mQueryBits(uRenameFlags, RNMFLGS_RETAIN_ALIAS));
  1765. Assert(hShadowTo != 0);
  1766. lpFRUse->sFR.ulidShadowOrg = hShadowTo;
  1767. }
  1768. else if (!mQueryBits(uRenameFlags, RNMFLGS_RETAIN_ALIAS))
  1769. {
  1770. lpFRUse->sFR.ulidShadowOrg = 0;
  1771. }
  1772. // update the security context
  1773. CopyBufferToSecurityContext(lpSecurityBlobTo, lpdwBlobSizeTo, &(lpFRUse->sFR.Security));
  1774. // Write the record. Now hDirFrom is the renamee
  1775. if ((ulrecDirEntryTo = AddFileRecordFR(lpdbShadow, hDirTo, lpFRUse)) <=0)
  1776. {
  1777. // this could happen if there is no disk space
  1778. goto bailout;
  1779. }
  1780. // if this going across shares, fix up the PQ entry with the right share
  1781. if (hShareTo)
  1782. {
  1783. sPQ.ulidShare = hShareTo;
  1784. }
  1785. sPQ.ulidDir = hDirTo;
  1786. sPQ.ulrecDirEntry = ulrecDirEntryTo;
  1787. sPQ.uStatus = ((USHORT)uShadowStatusTo | (sPQ.uStatus & SHADOW_LOCAL_INODE));
  1788. if (UpdatePriQRecord(lpdbShadow, hDirTo, hShadowFrom, &sPQ)< 0)
  1789. {
  1790. Assert(FALSE);
  1791. goto bailout;
  1792. }
  1793. // by this time a hShadowFrom has been associated with the new name
  1794. // and is also pointing back to hDirTo
  1795. // We still have a filerec entry which associates hShadowFrom with
  1796. // the old name and we need to take care of it
  1797. if (mQueryBits(uRenameFlags, RNMFLGS_MARK_SOURCE_DELETED))
  1798. {
  1799. // we are running in disconnected mode
  1800. // need to keep the old name
  1801. Assert(hShadowTo != 0);
  1802. lpFRDir->sFR.uStatus = SHADOW_DELETED;
  1803. lpFRDir->sFR.ulidShadow = hShadowTo;
  1804. // update filerecord without doing any compares
  1805. if(UpdateFileRecFromInodeEx(lpdbShadow, hDirFrom, hShadowFrom, ulrecDirEntryFrom, lpFRDir, FALSE)<=0)
  1806. {
  1807. Assert(FALSE);
  1808. goto bailout;
  1809. }
  1810. if(AddPriQRecord(lpdbShadow, sPQ.ulidShare, hDirFrom, hShadowTo, SHADOW_DELETED
  1811. , (ULONG)(sPQ.uchRefPri), (ULONG)(sPQ.uchIHPri)
  1812. , (ULONG)(sPQ.uchHintPri), (ULONG)(sPQ.uchHintFlags), ulrecDirEntryFrom)<=0)
  1813. {
  1814. Assert(FALSE);
  1815. goto bailout;
  1816. }
  1817. }
  1818. else
  1819. {
  1820. if(DeleteFileRecFromInode(lpdbShadow, hDirFrom, hShadowFrom, ulrecDirEntryFrom, lpFRUse) <= 0L)
  1821. {
  1822. Assert(FALSE);
  1823. goto bailout;
  1824. }
  1825. }
  1826. if (IsLeaf(hShadowFrom) && (fWasPinned != fIsPinned))
  1827. {
  1828. CShadowKdPrint(STOREDATA,("RenameDirFileHSHADOW: hDirFrom=%x hShadowFrom=%x hDirTo=%x To=%ws\r\n", hDirFrom, hShadowFrom, hDirTo, lpFind32To->cFileName));
  1829. CShadowKdPrint(STOREDATA,("RenameDirFileHSHADOW: WasPinned=%d IsPinned=%d\r\n", fWasPinned, fIsPinned));
  1830. AdjustShadowSpace( 0,
  1831. (fWasPinned)?0:RealFileSize(lpFRUse->sFR.ulFileSize), // if it was pinned it's old size was zero for space computation
  1832. // else it was the actual size
  1833. 0,
  1834. (fWasPinned)?RealFileSize(lpFRUse->sFR.ulFileSize):0, // if it was pinned it's new size should be zero for space computation
  1835. // else it should be the actual size
  1836. TRUE);
  1837. }
  1838. iRet = SRET_OK;
  1839. vdwCSCNameSpaceVersion++;
  1840. bailout:
  1841. if (lpFRDir)
  1842. {
  1843. FreeMem(lpFRDir);
  1844. }
  1845. return (iRet);
  1846. }
  1847. int PUBLIC // ret
  1848. GetShadow( //
  1849. HSHADOW hDir,
  1850. USHORT *lpName,
  1851. LPHSHADOW lphShadow,
  1852. LPFIND32 lpFind32,
  1853. ULONG far *lpuShadowStatus,
  1854. LPOTHERINFO lpOI
  1855. ) //
  1856. /*++
  1857. Routine Description:
  1858. Parameters:
  1859. Return Value:
  1860. Notes:
  1861. --*/
  1862. {
  1863. return (GetShadowEx(hDir, lpName, lphShadow, lpFind32, lpuShadowStatus, lpOI, NULL, NULL));
  1864. }
  1865. int PUBLIC // ret
  1866. GetShadowEx( //
  1867. HSHADOW hDir,
  1868. USHORT *lpName,
  1869. LPHSHADOW lphShadow,
  1870. LPFIND32 lpFind32,
  1871. ULONG far *lpuShadowStatus,
  1872. LPOTHERINFO lpOI,
  1873. LPVOID lpSecurityBlob,
  1874. LPDWORD lpdwBlobSize
  1875. ) //
  1876. /*++
  1877. Routine Description:
  1878. Parameters:
  1879. Return Value:
  1880. Notes:
  1881. --*/
  1882. {
  1883. int iRet=SRET_ERROR;
  1884. LPFILERECEXT lpFR = NULL, lpFRUse;
  1885. Assert(vfInShadowCrit != 0);
  1886. if(!(!hDir || IsDirInode(hDir)))
  1887. {
  1888. return iRet;
  1889. }
  1890. BEGIN_TIMING(GetShadow);
  1891. if (InuseGlobalFRExt())
  1892. {
  1893. if (!(lpFR = (LPFILERECEXT)AllocMem(sizeof(FILERECEXT))))
  1894. goto bailout;
  1895. lpFRUse = lpFR;
  1896. }
  1897. else
  1898. {
  1899. UseGlobalFilerecExt();
  1900. lpFRUse = &vsFRExt;
  1901. }
  1902. *lphShadow = 0L;
  1903. *lpuShadowStatus = 0;
  1904. if (!hDir)
  1905. {
  1906. // We are looking for the root
  1907. if(FindShareRecord(lpdbShadow, lpName, (LPSHAREREC)lpFRUse))
  1908. {
  1909. *lphShadow = ((LPSHAREREC)lpFRUse)->ulidShadow;
  1910. *lpuShadowStatus = (ULONG)(((LPSHAREREC)lpFRUse)->uStatus);
  1911. if (lpFind32)
  1912. {
  1913. CopySharerecToFindInfo(((LPSHAREREC)lpFRUse), lpFind32);
  1914. }
  1915. if (lpOI)
  1916. {
  1917. CopySharerecToOtherInfo((LPSHAREREC)lpFRUse, lpOI);
  1918. }
  1919. CopySecurityContextToBuffer(
  1920. &((LPSHAREREC)lpFRUse)->sShareSecurity,
  1921. lpSecurityBlob,
  1922. lpdwBlobSize);
  1923. }
  1924. }
  1925. else
  1926. {
  1927. if (FindFileRecord(lpdbShadow, hDir, lpName, lpFRUse))
  1928. {
  1929. *lphShadow = lpFRUse->sFR.ulidShadow;
  1930. if (lpFind32)
  1931. {
  1932. CopyFilerecToFindInfo(lpFRUse, lpFind32);
  1933. }
  1934. *lpuShadowStatus = lpFRUse->sFR.uStatus;
  1935. CopySecurityContextToBuffer(&(lpFRUse->sFR.Security), lpSecurityBlob, lpdwBlobSize);
  1936. }
  1937. if (lpOI)
  1938. {
  1939. CopyFilerecToOtherInfo(lpFRUse, lpOI);
  1940. }
  1941. }
  1942. iRet = SRET_OK;
  1943. if (*lphShadow)
  1944. {
  1945. CShadowKdPrint(GETSHADOWHI,("GetShadow: %0lX is the shadow for %ws \r\n", *lphShadow, lpName));
  1946. if (0) { //keep this in case we need it again.........
  1947. if ((lpName[0]==L'm') && (lpName[1]==L'f') && (lpName[2]==0)) {
  1948. DbgPrint("Found mf!!!!\n");
  1949. SET_HSHADOW_SPECIAL(*lphShadow);
  1950. }
  1951. }
  1952. }
  1953. else
  1954. {
  1955. CShadowKdPrint(GETSHADOWHI,("GetShadow: No shadow for %ws \r\n", lpName));
  1956. }
  1957. bailout:
  1958. if (lpFR)
  1959. FreeMem(lpFR);
  1960. else
  1961. UnUseGlobalFilerecExt();
  1962. END_TIMING(GetShadow);
  1963. return iRet;
  1964. }
  1965. int PUBLIC // ret
  1966. ChkStatusHSHADOW( //
  1967. HSHADOW hDir,
  1968. HSHADOW hShadow,
  1969. LPFIND32 lpFind32,
  1970. ULONG far *lpuStatus
  1971. ) //
  1972. /*++
  1973. Routine Description:
  1974. Parameters:
  1975. Return Value:
  1976. Notes:
  1977. --*/
  1978. {
  1979. int iRet;
  1980. iRet = ReadShadowInfo(hDir, hShadow, lpFind32, lpuStatus, NULL, NULL, NULL, RSI_COMPARE);
  1981. return(iRet);
  1982. }
  1983. int PUBLIC // ret
  1984. ChkUpdtStatusHSHADOW( //
  1985. HSHADOW hDir,
  1986. HSHADOW hShadow,
  1987. LPFIND32 lpFind32,
  1988. ULONG far *lpuStatus
  1989. ) //
  1990. {
  1991. int iRet;
  1992. iRet = ReadShadowInfo(hDir, hShadow, lpFind32, lpuStatus, NULL, NULL, NULL, RSI_COMPARE|RSI_SET);
  1993. return(iRet);
  1994. }
  1995. int PUBLIC GetShadowInfo
  1996. (
  1997. HSHADOW hDir,
  1998. HSHADOW hShadow,
  1999. LPFIND32 lpFind32,
  2000. ULONG far *lpuStatus,
  2001. LPOTHERINFO lpOI
  2002. )
  2003. /*++
  2004. Routine Description:
  2005. Parameters:
  2006. Return Value:
  2007. Notes:
  2008. --*/
  2009. {
  2010. int iRet=SRET_ERROR;
  2011. SHAREREC sSR;
  2012. BEGIN_TIMING(GetShadowInfo);
  2013. iRet = ReadShadowInfo(hDir, hShadow, lpFind32, lpuStatus, lpOI, NULL, NULL, RSI_GET);
  2014. END_TIMING(GetShadowInfo);
  2015. return(iRet);
  2016. }
  2017. int PUBLIC GetShadowInfoEx
  2018. (
  2019. HSHADOW hDir,
  2020. HSHADOW hShadow,
  2021. LPFIND32 lpFind32,
  2022. ULONG far *lpuStatus,
  2023. LPOTHERINFO lpOI,
  2024. LPVOID lpSecurityBlob,
  2025. LPDWORD lpdwBlobSize
  2026. )
  2027. /*++
  2028. Routine Description:
  2029. Parameters:
  2030. Return Value:
  2031. Notes:
  2032. --*/
  2033. {
  2034. int iRet=SRET_ERROR;
  2035. SHAREREC sSR;
  2036. BEGIN_TIMING(GetShadowInfo);
  2037. iRet = ReadShadowInfo(hDir, hShadow, lpFind32, lpuStatus, lpOI, lpSecurityBlob, lpdwBlobSize, RSI_GET);
  2038. END_TIMING(GetShadowInfo);
  2039. return(iRet);
  2040. }
  2041. int PUBLIC // ret
  2042. SetShadowInfo( //
  2043. HSHADOW hDir,
  2044. HSHADOW hShadow,
  2045. LPFIND32 lpFind32,
  2046. ULONG uFlags,
  2047. ULONG uOp
  2048. ) //
  2049. /*++
  2050. Routine Description:
  2051. Parameters:
  2052. Return Value:
  2053. Notes:
  2054. --*/
  2055. {
  2056. return (SetShadowInfoEx(hDir, hShadow, lpFind32, uFlags, uOp, NULL, NULL, NULL));
  2057. }
  2058. int PUBLIC // ret
  2059. SetShadowInfoEx( //
  2060. HSHADOW hDir,
  2061. HSHADOW hShadow,
  2062. LPFIND32 lpFind32,
  2063. ULONG uFlags,
  2064. ULONG uOp,
  2065. LPOTHERINFO lpOI,
  2066. LPVOID lpSecurityBlob,
  2067. LPDWORD lpdwBlobSize
  2068. ) //
  2069. /*++
  2070. Routine Description:
  2071. This routine is the central routine that modifies the database entry for a particular inode
  2072. Parameters:
  2073. Return Value:
  2074. Notes:
  2075. --*/
  2076. {
  2077. int iRet = SRET_ERROR;
  2078. LPFILERECEXT lpFR = NULL, lpFRUse;
  2079. PRIQREC sPQ;
  2080. ULONG uOldSize = 0, uNewSize=0, ulOldHintPri=0, ulOldHintFlags = 0, ulOldRefPri, ulOldFlags;
  2081. BOOL fRefPriChange = FALSE;
  2082. Assert(vfInShadowCrit != 0);
  2083. if(!(!hDir || IsDirInode(hDir)))
  2084. {
  2085. return iRet;
  2086. }
  2087. BEGIN_TIMING(SetShadowInfoInternal);
  2088. if (lpFind32)
  2089. {
  2090. if(!( (IsLeaf(hShadow) && IsFile(lpFind32->dwFileAttributes)) ||
  2091. (!IsLeaf(hShadow) && !IsFile(lpFind32->dwFileAttributes))))
  2092. {
  2093. return SRET_ERROR;
  2094. }
  2095. }
  2096. if (InuseGlobalFRExt())
  2097. {
  2098. if (!(lpFR = (LPFILERECEXT)AllocMem(sizeof(FILERECEXT))))
  2099. goto bailout;
  2100. lpFRUse = lpFR;
  2101. }
  2102. else
  2103. {
  2104. UseGlobalFilerecExt();
  2105. lpFRUse = &vsFRExt;
  2106. }
  2107. if (!hDir)
  2108. {
  2109. // We are looking for the root
  2110. if(FindSharerecFromInode(lpdbShadow, hShadow, (LPSHAREREC)lpFRUse))
  2111. {
  2112. if (lpFind32)
  2113. {
  2114. CopyFindInfoToSharerec(lpFind32, (LPSHAREREC)lpFRUse);
  2115. }
  2116. if (lpOI)
  2117. {
  2118. CopyOtherInfoToSharerec(lpOI, (LPSHAREREC)lpFRUse);
  2119. }
  2120. CopyBufferToSecurityContext( lpSecurityBlob,
  2121. lpdwBlobSize,
  2122. &(((LPSHAREREC)lpFRUse)->sRootSecurity));
  2123. if (mAndShadowFlags(uOp))
  2124. {
  2125. ((LPSHAREREC)lpFRUse)->usRootStatus &= (USHORT)uFlags;
  2126. }
  2127. else if (mOrShadowFlags(uOp))
  2128. {
  2129. ((LPSHAREREC)lpFRUse)->usRootStatus |= (USHORT)uFlags;
  2130. }
  2131. else
  2132. {
  2133. ((LPSHAREREC)lpFRUse)->usRootStatus = (USHORT)uFlags;
  2134. }
  2135. iRet = SetShareRecord(lpdbShadow, ((LPSHAREREC)lpFRUse)->ulShare, (LPSHAREREC)lpFRUse);
  2136. }
  2137. }
  2138. else
  2139. {
  2140. IF_HSHADOW_SPECIAL(hShadow) {
  2141. //ASSERT(!"SpecialShadow in setshadinfo");
  2142. }
  2143. if(FindPriQRecord(lpdbShadow, hDir, hShadow, &sPQ) < 0)
  2144. {
  2145. goto bailout;
  2146. }
  2147. Assert((sPQ.ulidDir == hDir) && (sPQ.ulidShadow == hShadow));
  2148. if (CShadowFindFilerecFromInode(lpdbShadow, hDir, hShadow, &sPQ, lpFRUse)> 0)
  2149. {
  2150. Assert(lpFRUse->sFR.ulidShadow == hShadow);
  2151. uOldSize = uNewSize = lpFRUse->sFR.ulFileSize;
  2152. ulOldFlags = lpFRUse->sFR.usStatus;
  2153. if (lpFind32)
  2154. {
  2155. uNewSize = (ULONG)(lpFind32->nFileSizeLow);
  2156. CopyFindInfoToFilerec(lpFind32, lpFRUse, (mChange83Name(uOp))?CPFR_COPYNAME:0);
  2157. if (!mDontUpdateOrgTime(uOp))
  2158. {
  2159. lpFRUse->sFR.ftOrgTime = lpFRUse->sFR.ftLastWriteTime;
  2160. }
  2161. }
  2162. if (mAndShadowFlags(uOp))
  2163. {
  2164. lpFRUse->sFR.uStatus &= (USHORT)uFlags;
  2165. }
  2166. else if (mOrShadowFlags(uOp))
  2167. {
  2168. lpFRUse->sFR.uStatus |= (USHORT)uFlags;
  2169. }
  2170. else
  2171. {
  2172. lpFRUse->sFR.uStatus = (USHORT)uFlags;
  2173. }
  2174. if (mShadowNeedReint(ulOldFlags) && !mShadowNeedReint(lpFRUse->sFR.usStatus))
  2175. {
  2176. if(DeleteStream(lpdbShadow, hShadow, CscBmpAltStrmName) < SRET_OK)
  2177. {
  2178. DbgPrint("DeleteStream failed with %x /n", GetLastErrorLocal());
  2179. goto bailout;
  2180. }
  2181. }
  2182. if (lpOI)
  2183. {
  2184. // save some key old info before copying the new info
  2185. ulOldHintPri = lpFRUse->sFR.uchHintPri;
  2186. ulOldHintFlags = lpFRUse->sFR.uchHintFlags;
  2187. ulOldRefPri = lpFRUse->sFR.uchRefPri;
  2188. CopyOtherInfoToFilerec(lpOI, lpFRUse);
  2189. CopyOtherInfoToPQ(lpOI, &sPQ);
  2190. if (IsFile(lpFRUse->sFR.dwFileAttrib))
  2191. {
  2192. if ((!ulOldHintPri && !mPinFlags(ulOldHintFlags)) && // was unpinned
  2193. (lpFRUse->sFR.uchHintPri || mPinFlags(lpFRUse->sFR.uchHintFlags))) //is getting pinned
  2194. {
  2195. // If it went from unpinned to pinned
  2196. // make the new size 0
  2197. uNewSize = 0;
  2198. }
  2199. else if ((ulOldHintPri || mPinFlags(ulOldHintFlags)) && // was pinned
  2200. (!lpFRUse->sFR.uchHintPri && !mPinFlags(lpFRUse->sFR.uchHintFlags))) //is getting unpinned
  2201. {
  2202. // If it went from pinned to unpinned
  2203. // we must add the new size
  2204. uOldSize = 0;
  2205. }
  2206. }
  2207. if(mForceRelink(uOp) || ((ulOldRefPri != (ULONG)(sPQ.uchRefPri))
  2208. )
  2209. )
  2210. {
  2211. fRefPriChange = TRUE;
  2212. }
  2213. }
  2214. else
  2215. {
  2216. // if this is a pinned entry, we need to not have any space adjustment
  2217. if(lpFRUse->sFR.uchHintPri || mPinFlags(lpFRUse->sFR.uchHintFlags))
  2218. {
  2219. uOldSize = uNewSize;
  2220. }
  2221. }
  2222. if (IsFile(lpFRUse->sFR.dwFileAttrib))
  2223. {
  2224. Assert(lpFRUse->sFR.uchRefPri == MAX_PRI);
  2225. }
  2226. else
  2227. {
  2228. Assert(sPQ.uchRefPri == MIN_PRI);
  2229. Assert(lpFRUse->sFR.uchRefPri == MIN_PRI);
  2230. }
  2231. CShadowKdPrint(SETSHADOWINFOHI,("SetShadowInfo: %x %x: loctLo=%x loctHi=%x \r\n",
  2232. hDir,hShadow,
  2233. lpFRUse->sFR.ftOrgTime.dwLowDateTime,
  2234. lpFRUse->sFR.ftOrgTime.dwHighDateTime));
  2235. CopyBufferToSecurityContext(lpSecurityBlob, lpdwBlobSize, &(lpFRUse->sFR.Security));
  2236. #ifdef DEBUG
  2237. ValidatePri(lpFRUse);
  2238. #endif
  2239. if ((ulOldFlags & SHADOW_SPARSE) && !(lpFRUse->sFR.usStatus & SHADOW_SPARSE))
  2240. {
  2241. CShadowKdPrint(SETSHADOWINFOHI,("SetShadowInfo: File Unsparsed\n"));
  2242. }
  2243. if (mSetLastRefreshTime(uOp) || ((ulOldFlags & SHADOW_STALE) && !(lpFRUse->sFR.usStatus & SHADOW_STALE)))
  2244. {
  2245. lpFRUse->sFR.ulLastRefreshTime = (ULONG)IFSMgr_Get_NetTime();
  2246. }
  2247. if (UpdateFileRecFromInode(lpdbShadow, hDir, hShadow, sPQ.ulrecDirEntry, lpFRUse) < SRET_OK)
  2248. {
  2249. Assert(FALSE);
  2250. goto bailout;
  2251. }
  2252. if (mShadowNeedReint(ulOldFlags) && !mShadowNeedReint(lpFRUse->sFR.usStatus))
  2253. {
  2254. sPQ.usStatus = lpFRUse->sFR.uStatus;
  2255. // Assert(!(sPQ.usStatus & SHADOW_LOCAL_INODE));
  2256. lpFRUse->sFR.ulidShadowOrg = lpFRUse->sFR.ulidShadow;
  2257. }
  2258. else
  2259. {
  2260. sPQ.usStatus = ((USHORT)(lpFRUse->sFR.uStatus) | (sPQ.usStatus & SHADOW_LOCAL_INODE));
  2261. }
  2262. if (fRefPriChange)
  2263. {
  2264. // update the record with and relinking it in the queue
  2265. if (UpdatePriQRecordAndRelink(lpdbShadow, hDir, hShadow, &sPQ) < SRET_OK)
  2266. {
  2267. Assert(FALSE);
  2268. goto bailout;
  2269. }
  2270. }
  2271. else
  2272. {
  2273. // update the record without relinking
  2274. if (UpdatePriQRecord(lpdbShadow, hDir, hShadow, &sPQ) < SRET_OK)
  2275. {
  2276. Assert(FALSE);
  2277. goto bailout;
  2278. }
  2279. }
  2280. // we do space accounting only for files
  2281. // If the file went from pinned to upinned and viceversa
  2282. if (IsFile(lpFRUse->sFR.dwFileAttrib) && (uOldSize != uNewSize))
  2283. {
  2284. CShadowKdPrint(STOREDATA,("SetShadowInfo: Size changed for hDir=%x Name=%ws\r\n", hDir, lpFRUse->sFR.rgwName));
  2285. AdjustShadowSpace(0, uOldSize, 0, uNewSize, TRUE);
  2286. }
  2287. AdjustSparseStaleDetectionCount(0, lpFRUse);
  2288. iRet = SRET_OK;
  2289. }
  2290. }
  2291. bailout:
  2292. if (lpFR)
  2293. FreeMem(lpFR);
  2294. else
  2295. UnUseGlobalFilerecExt();
  2296. END_TIMING(SetShadowInfoInternal);
  2297. return iRet;
  2298. }
  2299. int PRIVATE ReadShadowInfo(
  2300. HSHADOW hDir,
  2301. HSHADOW hShadow,
  2302. LPFIND32 lpFind32,
  2303. ULONG far *lpuStatus,
  2304. LPOTHERINFO lpOI,
  2305. LPVOID lpSecurityBlob,
  2306. LPDWORD lpdwBlobSize,
  2307. ULONG uFlags
  2308. )
  2309. /*++
  2310. Routine Description:
  2311. Parameters:
  2312. Return Value:
  2313. Notes:
  2314. --*/
  2315. {
  2316. BOOL fStale = FALSE;
  2317. int iRet = SRET_ERROR;
  2318. LPFILERECEXT lpFR = NULL, lpFRUse;
  2319. PRIQREC sPQ;
  2320. Assert(vfInShadowCrit != 0);
  2321. if(!(!hDir || IsDirInode(hDir)))
  2322. {
  2323. return iRet;
  2324. }
  2325. if (InuseGlobalFRExt())
  2326. {
  2327. if (!(lpFR = (LPFILERECEXT)AllocMem(sizeof(FILERECEXT))))
  2328. goto bailout;
  2329. lpFRUse = lpFR;
  2330. }
  2331. else
  2332. {
  2333. UseGlobalFilerecExt();
  2334. lpFRUse = &vsFRExt;
  2335. }
  2336. Assert((uFlags & (RSI_GET|RSI_SET)) != (RSI_GET|RSI_SET));
  2337. if (!hDir)
  2338. {
  2339. if(FindSharerecFromInode(lpdbShadow, hShadow, (LPSHAREREC)lpFRUse))
  2340. {
  2341. if (lpuStatus != NULL) {
  2342. *lpuStatus = (ULONG)(((LPSHAREREC)lpFRUse)->usRootStatus);
  2343. }
  2344. if (lpFind32)
  2345. {
  2346. CopySharerecToFindInfo((LPSHAREREC)lpFRUse, lpFind32);
  2347. }
  2348. if (lpOI)
  2349. {
  2350. CopySharerecToOtherInfo((LPSHAREREC)lpFRUse, lpOI);
  2351. }
  2352. CopySecurityContextToBuffer(
  2353. &(((LPSHAREREC)lpFRUse)->sShareSecurity),
  2354. lpSecurityBlob,
  2355. lpdwBlobSize);
  2356. iRet = SRET_OK;
  2357. }
  2358. goto bailout;
  2359. }
  2360. Assert(hDir);
  2361. if(FindPriQRecord(lpdbShadow, hDir, hShadow, &sPQ) < 0)
  2362. goto bailout;
  2363. if(!CShadowFindFilerecFromInode(lpdbShadow, hDir, hShadow, &sPQ, lpFRUse))
  2364. {
  2365. CShadowKdPrint(ALWAYS,("ReadShadowInfo: !!! no filerec for pq entry Inode=%x, deleting PQ entry\r\n",
  2366. hShadow));
  2367. goto bailout;
  2368. }
  2369. CopySecurityContextToBuffer(&(lpFRUse->sFR.Security), lpSecurityBlob, lpdwBlobSize);
  2370. if (lpFind32)
  2371. {
  2372. if (uFlags & RSI_COMPARE)
  2373. {
  2374. // ACHTUNG!! we compare last write times. It is possible that
  2375. // somebody might have changed the filetime on the server to
  2376. // be something earlier than what we had when we shadowed the file
  2377. // for the first time. We detect this case here and say that the file
  2378. // is stale
  2379. #ifdef CSC_RECORDMANAGER_WINNT
  2380. fStale = ((CompareTimes(lpFind32->ftLastWriteTime, lpFRUse->sFR.ftOrgTime) != 0)||
  2381. (lpFind32->nFileSizeLow !=lpFRUse->sFR.ulFileSize));
  2382. #else
  2383. fStale = (CompareTimesAtDosTimePrecision(lpFind32->ftLastWriteTime, lpFRUse->sFR.ftOrgTime) != 0);
  2384. #endif
  2385. // If remote time > local time, copy the file
  2386. if ((!fStale && (lpFRUse->sFR.uStatus & SHADOW_STALE))||
  2387. (fStale && !(lpFRUse->sFR.uStatus & SHADOW_STALE)))
  2388. {
  2389. CShadowKdPrint(READSHADOWINFOHI,("ReadShadowInfo: %x: remtLo=%x remtHi=%x, \r\n locTLo=%x, locTHi=%x \r\n"
  2390. ,hShadow, lpFind32->ftLastWriteTime.dwLowDateTime, lpFind32->ftLastWriteTime.dwHighDateTime
  2391. , lpFRUse->sFR.ftOrgTime.dwLowDateTime, lpFRUse->sFR.ftOrgTime.dwHighDateTime));
  2392. // Toggle the staleness bit
  2393. lpFRUse->sFR.uStatus ^= SHADOW_STALE;
  2394. sPQ.usStatus = (USHORT)(lpFRUse->sFR.uStatus) | (sPQ.usStatus & SHADOW_LOCAL_INODE);
  2395. if (uFlags & RSI_SET)
  2396. {
  2397. if (UpdateFileRecFromInode(lpdbShadow, hDir, hShadow, sPQ.ulrecDirEntry, lpFRUse) < SRET_OK)
  2398. {
  2399. Assert(FALSE);
  2400. goto bailout;
  2401. }
  2402. if (UpdatePriQRecord(lpdbShadow, hDir, hShadow, &sPQ) < SRET_OK)
  2403. {
  2404. // Toggle the staleness bit
  2405. lpFRUse->sFR.uStatus ^= SHADOW_STALE;
  2406. //try to undo the change
  2407. if (UpdateFileRecFromInode(lpdbShadow, hDir, hShadow, sPQ.ulrecDirEntry, lpFRUse) < SRET_OK)
  2408. {
  2409. Assert(FALSE);
  2410. }
  2411. goto bailout;
  2412. }
  2413. AdjustSparseStaleDetectionCount(0, lpFRUse);
  2414. }
  2415. iRet = 1;
  2416. }
  2417. else
  2418. {
  2419. iRet = 0;
  2420. }
  2421. }
  2422. else
  2423. {
  2424. iRet = 0;
  2425. }
  2426. if (uFlags & RSI_GET)
  2427. {
  2428. CopyFilerecToFindInfo(lpFRUse, lpFind32);
  2429. Assert((IsLeaf(hShadow) && IsFile(lpFind32->dwFileAttributes)) ||
  2430. (!IsLeaf(hShadow) && !IsFile(lpFind32->dwFileAttributes)));
  2431. }
  2432. }
  2433. else
  2434. {
  2435. iRet = 0;
  2436. }
  2437. if (lpOI)
  2438. {
  2439. CopyFilerecToOtherInfo(lpFRUse, lpOI);
  2440. }
  2441. if (lpuStatus != NULL) {
  2442. *lpuStatus = lpFRUse->sFR.uStatus;
  2443. }
  2444. bailout:
  2445. if (lpFR)
  2446. {
  2447. FreeMem(lpFR);
  2448. }
  2449. else
  2450. {
  2451. UnUseGlobalFilerecExt();
  2452. }
  2453. return iRet;
  2454. }
  2455. HSHARE PUBLIC // ret
  2456. HCreateShareObj( //
  2457. USHORT *lpShare,
  2458. LPSHADOWINFO lpSI
  2459. ) //
  2460. /*++
  2461. Routine Description:
  2462. Parameters:
  2463. Return Value:
  2464. Notes:
  2465. --*/
  2466. {
  2467. ULONG ulidShare=0;
  2468. HSHADOW hRoot=0;
  2469. SHAREREC sSR;
  2470. Assert(vfInShadowCrit != 0);
  2471. memset(lpSI, 0, sizeof(SHADOWINFO));
  2472. if(!InitShareRec(&sSR, lpShare,0))
  2473. {
  2474. return 0;
  2475. }
  2476. if (!(ulidShare = AllocShareRecord(lpdbShadow, lpShare)))
  2477. return 0;
  2478. if(!(hRoot = UlAllocInode(lpdbShadow, 0L, FALSE)))
  2479. return 0;
  2480. // Let us create an empty root
  2481. if(CreateDirInode(lpdbShadow, ulidShare, 0L, hRoot) < 0L)
  2482. {
  2483. CShadowKdPrint(BADERRORS,("Error in creating root \r\n"));
  2484. return 0L;
  2485. }
  2486. if (AddPriQRecord(lpdbShadow, ulidShare, 0, hRoot, SHADOW_SPARSE, 0, 0, 0, 0, ulidShare) < 0)
  2487. {
  2488. CShadowKdPrint(BADERRORS,("Error in inserting root in the priorityQ\r\n"));
  2489. return 0L;
  2490. }
  2491. sSR.ulShare = ulidShare;
  2492. sSR.ulidShadow = hRoot;
  2493. sSR.uStatus = 0;
  2494. sSR.usRootStatus = SHADOW_SPARSE;
  2495. sSR.dwFileAttrib = FILE_ATTRIBUTE_DIRECTORY;
  2496. if (sSR.ftLastWriteTime.dwLowDateTime == 0 && sSR.ftLastWriteTime.dwHighDateTime == 0) {
  2497. KeQuerySystemTime(((PLARGE_INTEGER)(&sSR.ftLastWriteTime)));
  2498. if (sSR.ftOrgTime.dwLowDateTime == 0 && sSR.ftOrgTime.dwHighDateTime == 0)
  2499. sSR.ftOrgTime = sSR.ftLastWriteTime;
  2500. }
  2501. // there needs to be a way for passing in ftLastWriteTime, which we would
  2502. // stamp as the ftOrgTime. We don't use the ORG time right now, but we might want to
  2503. // in future
  2504. // All entities have been individually created. Let us tie them up
  2505. // in the database
  2506. ulidShare = AddShareRecord(lpdbShadow, &sSR);
  2507. if (ulidShare)
  2508. {
  2509. CopySharerecToShadowInfo(&sSR, lpSI);
  2510. vdwCSCNameSpaceVersion++;
  2511. vdwPQVersion++;
  2512. }
  2513. return ((HSHARE)ulidShare);
  2514. }
  2515. int PUBLIC // ret
  2516. DestroyHSHARE( //
  2517. HSHARE hShare
  2518. ) //
  2519. /*++
  2520. Routine Description:
  2521. Parameters:
  2522. Return Value:
  2523. Notes:
  2524. --*/
  2525. {
  2526. SHAREREC sSR;
  2527. int iRet = SRET_ERROR;
  2528. Assert(vfInShadowCrit != 0);
  2529. if(FindSharerecFromShare(lpdbShadow, hShare, &sSR))
  2530. {
  2531. if (DestroyShareInternal(&sSR) >= 0)
  2532. iRet = SRET_OK;
  2533. }
  2534. return (iRet);
  2535. }
  2536. int DestroyShareInternal( LPSHAREREC lpSR
  2537. )
  2538. {
  2539. PRIQREC sPQ;
  2540. int iRet = -1;
  2541. if (!mNotFsobj(lpSR->uStatus))
  2542. {
  2543. if(DeletePriQRecord(lpdbShadow, 0, lpSR->ulidShadow, &sPQ) >= 0)
  2544. {
  2545. if (DeleteShareRecord(lpdbShadow, lpSR->ulShare))
  2546. {
  2547. FreeInode(lpdbShadow, lpSR->ulidShadow);
  2548. DeleteInodeFile(lpdbShadow, lpSR->ulidShadow);
  2549. iRet = 1;
  2550. vdwCSCNameSpaceVersion++;
  2551. vdwPQVersion++;
  2552. }
  2553. else
  2554. {
  2555. CShadowKdPrint(BADERRORS, ("Failed to delete record for share=%x\r\n", lpSR->ulShare));
  2556. }
  2557. }
  2558. }
  2559. return (iRet);
  2560. }
  2561. int PUBLIC // ret
  2562. GetShareFromPath( //
  2563. USHORT *lpShare,
  2564. LPSHADOWINFO lpSI
  2565. ) //
  2566. /*++
  2567. Routine Description:
  2568. Parameters:
  2569. Return Value:
  2570. Notes:
  2571. --*/
  2572. {
  2573. SHAREREC sSR;
  2574. Assert(vfInShadowCrit != 0);
  2575. memset(lpSI, 0, sizeof(SHADOWINFO));
  2576. if(FindShareRecord(lpdbShadow, lpShare, &sSR))
  2577. {
  2578. CopySharerecToShadowInfo(&sSR, lpSI);
  2579. }
  2580. return SRET_OK;
  2581. }
  2582. int PUBLIC // ret
  2583. GetShareFromPathEx( //
  2584. USHORT *lpShare,
  2585. LPSHADOWINFO lpSI,
  2586. LPVOID lpSecurityBlob,
  2587. LPDWORD lpdwBlobSize
  2588. ) //
  2589. /*++
  2590. Routine Description:
  2591. Parameters:
  2592. Return Value:
  2593. Notes:
  2594. --*/
  2595. {
  2596. SHAREREC sSR;
  2597. memset(lpSI, 0, sizeof(SHADOWINFO));
  2598. Assert(vfInShadowCrit != 0);
  2599. if(FindShareRecord(lpdbShadow, lpShare, &sSR))
  2600. {
  2601. CopySharerecToShadowInfo(&sSR, lpSI);
  2602. CopySecurityContextToBuffer(&(sSR.sShareSecurity), lpSecurityBlob, lpdwBlobSize);
  2603. }
  2604. return SRET_OK;
  2605. }
  2606. int PUBLIC // ret
  2607. GetShareInfo( //
  2608. HSHARE hShare,
  2609. LPSHAREINFOW lpShareInfo,
  2610. LPSHADOWINFO lpSI
  2611. )
  2612. /*++
  2613. Routine Description:
  2614. Parameters:
  2615. Return Value:
  2616. Notes:
  2617. --*/
  2618. {
  2619. return (GetShareInfoEx(hShare, lpShareInfo, lpSI, NULL, NULL));
  2620. }
  2621. int PUBLIC
  2622. GetShareInfoEx(
  2623. HSHARE hShare,
  2624. LPSHAREINFOW lpShareInfo,
  2625. LPSHADOWINFO lpSI,
  2626. LPVOID lpSecurityBlob,
  2627. LPDWORD lpdwBlobSize
  2628. )
  2629. /*++
  2630. Routine Description:
  2631. Parameters:
  2632. Return Value:
  2633. Notes:
  2634. --*/
  2635. {
  2636. SHAREREC sSR;
  2637. Assert(vfInShadowCrit != 0);
  2638. if (!hShare)
  2639. {
  2640. SetLastErrorLocal(ERROR_INVALID_PARAMETER);
  2641. return SRET_ERROR;
  2642. }
  2643. if (GetShareRecord(lpdbShadow, hShare, &sSR) < SRET_OK)
  2644. {
  2645. return SRET_ERROR;
  2646. }
  2647. if (lpShareInfo)
  2648. {
  2649. lpShareInfo->hShare = hShare;
  2650. memset(lpShareInfo->rgSharePath, 0, sizeof(lpShareInfo->rgSharePath));
  2651. memcpy(lpShareInfo->rgSharePath, sSR.rgPath, wstrlen(sSR.rgPath)*sizeof(USHORT));
  2652. memcpy(lpShareInfo->rgFileSystem, vwszFileSystemName, wstrlen(vwszFileSystemName)*sizeof(USHORT));
  2653. lpShareInfo->usCaps = FS_CASE_IS_PRESERVED|FS_VOL_SUPPORTS_LONG_NAMES;
  2654. lpShareInfo->usState = RESSTAT_OK;
  2655. }
  2656. if (lpSI)
  2657. {
  2658. CopySharerecToShadowInfo(&sSR, lpSI);
  2659. }
  2660. CopySecurityContextToBuffer(&(sSR.sShareSecurity), lpSecurityBlob, lpdwBlobSize);
  2661. return (SRET_OK);
  2662. }
  2663. int
  2664. SetShareStatus( HSHARE hShare,
  2665. ULONG uStatus,
  2666. ULONG uOp
  2667. )
  2668. /*++
  2669. Routine Description:
  2670. Parameters:
  2671. Return Value:
  2672. Notes:
  2673. --*/
  2674. {
  2675. return (SetShareStatusEx(hShare, uStatus, uOp, NULL, NULL));
  2676. }
  2677. int
  2678. SetShareStatusEx(
  2679. HSHARE hShare,
  2680. ULONG uStatus,
  2681. ULONG uOp,
  2682. LPVOID lpSecurityBlob,
  2683. LPDWORD lpdwBlobSize
  2684. )
  2685. /*++
  2686. Routine Description:
  2687. Parameters:
  2688. Return Value:
  2689. Notes:
  2690. --*/
  2691. {
  2692. SHAREREC sSR;
  2693. Assert(vfInShadowCrit != 0);
  2694. if (!hShare)
  2695. {
  2696. SetLastErrorLocal(ERROR_INVALID_PARAMETER);
  2697. return SRET_ERROR;
  2698. }
  2699. if (GetShareRecord(lpdbShadow, hShare, &sSR) < SRET_OK)
  2700. {
  2701. return SRET_ERROR;
  2702. }
  2703. if (mAndShadowFlags(uOp))
  2704. {
  2705. sSR.uStatus &= (USHORT)uStatus;
  2706. }
  2707. else if (mOrShadowFlags(uOp))
  2708. {
  2709. sSR.uStatus |= (USHORT)uStatus;
  2710. }
  2711. else
  2712. {
  2713. sSR.uStatus = (USHORT)uStatus;
  2714. }
  2715. CopyBufferToSecurityContext(lpSecurityBlob, lpdwBlobSize, &(sSR.sShareSecurity));
  2716. return (SetShareRecord(lpdbShadow, hShare, &sSR));
  2717. }
  2718. int PUBLIC // ret
  2719. GetAncestorsHSHADOW( //
  2720. HSHADOW hName,
  2721. LPHSHADOW lphDir,
  2722. LPHSHARE lphShare
  2723. ) //
  2724. /*++
  2725. Routine Description:
  2726. Parameters:
  2727. Return Value:
  2728. Notes:
  2729. --*/
  2730. {
  2731. return (FindAncestorsFromInode(lpdbShadow, hName, lphDir, lphShare));
  2732. }
  2733. int PUBLIC SetPriorityHSHADOW(
  2734. HSHADOW hDir,
  2735. HSHADOW hShadow,
  2736. ULONG ulRefPri,
  2737. ULONG ulIHPri
  2738. )
  2739. /*++
  2740. Routine Description:
  2741. Parameters:
  2742. Return Value:
  2743. Notes:
  2744. --*/
  2745. {
  2746. OTHERINFO sOI;
  2747. ULONG uOp = SHADOW_FLAGS_OR;
  2748. Assert(vfInShadowCrit != 0);
  2749. ulIHPri;
  2750. InitOtherInfo(&sOI);
  2751. // we make sure that if the new priority being set is MAX_PRI, then this
  2752. // inode does get to the top of the PQ even if it's current priority is
  2753. // MAX_PRI.
  2754. if (ulRefPri == MAX_PRI)
  2755. {
  2756. uOp |= SHADOW_FLAGS_FORCE_RELINK;
  2757. }
  2758. sOI.ulRefPri = ulRefPri;
  2759. sOI.ulIHPri = 0;
  2760. if(SetShadowInfoEx(hDir, hShadow, NULL, 0, uOp, &sOI, NULL, NULL))
  2761. return (SRET_ERROR);
  2762. return (SRET_OK);
  2763. }
  2764. int PUBLIC GetPriorityHSHADOW(
  2765. HSHADOW hDir,
  2766. HSHADOW hShadow,
  2767. ULONG *lpulRefPri,
  2768. ULONG *lpulIHPri
  2769. )
  2770. /*++
  2771. Routine Description:
  2772. Parameters:
  2773. Return Value:
  2774. Notes:
  2775. --*/
  2776. {
  2777. PRIQREC sPQ;
  2778. Assert(vfInShadowCrit != 0);
  2779. if((FindPriQRecord(lpdbShadow, hDir, hShadow, &sPQ) < 0)||mNotFsobj(sPQ.usStatus))
  2780. return SRET_ERROR;
  2781. if (lpulRefPri)
  2782. {
  2783. *lpulRefPri = (ULONG)(sPQ.uchRefPri);
  2784. }
  2785. if (lpulIHPri)
  2786. {
  2787. *lpulIHPri = (ULONG)(sPQ.uchIHPri);
  2788. }
  2789. return (SRET_OK);
  2790. }
  2791. int PUBLIC
  2792. ChangePriEntryStatusHSHADOW(
  2793. HSHADOW hDir,
  2794. HSHADOW hShadow,
  2795. ULONG uStatus,
  2796. ULONG uOp,
  2797. BOOL fChangeRefPri,
  2798. LPOTHERINFO lpOI
  2799. )
  2800. /*++
  2801. Routine Description:
  2802. Parameters:
  2803. Return Value:
  2804. Notes:
  2805. --*/
  2806. {
  2807. PRIQREC sPQ;
  2808. int iRet;
  2809. #ifdef DEBUG
  2810. ULONG ulRefPri;
  2811. #endif
  2812. Assert(vfInShadowCrit != 0);
  2813. Assert(!hDir || IsDirInode(hDir));
  2814. BEGIN_TIMING(ChangePriEntryStatusHSHADOW);
  2815. if(FindPriQRecord(lpdbShadow, hDir, hShadow, &sPQ) < 0)
  2816. return SRET_ERROR;
  2817. #ifdef DEBUG
  2818. ulRefPri = (ULONG)(sPQ.uchRefPri);
  2819. #endif
  2820. if (uOp==SHADOW_FLAGS_AND)
  2821. {
  2822. sPQ.usStatus &= (USHORT)uStatus;
  2823. }
  2824. else if (uOp==SHADOW_FLAGS_OR)
  2825. {
  2826. sPQ.usStatus |= (USHORT)uStatus;
  2827. }
  2828. else
  2829. {
  2830. sPQ.usStatus = (USHORT)uStatus;
  2831. }
  2832. if (lpOI)
  2833. {
  2834. CopyOtherInfoToPQ(lpOI, &sPQ);
  2835. }
  2836. if (!fChangeRefPri)
  2837. {
  2838. Assert(ulRefPri == (ULONG)(sPQ.uchRefPri));
  2839. iRet = UpdatePriQRecord(lpdbShadow, hDir, hShadow, &sPQ);
  2840. }
  2841. else
  2842. {
  2843. iRet = UpdatePriQRecordAndRelink(lpdbShadow, hDir, hShadow, &sPQ);
  2844. vdwPQVersion++;
  2845. }
  2846. END_TIMING(ChangePriEntryStatusHSHADOW);
  2847. return (iRet);
  2848. }
  2849. CSC_ENUMCOOKIE PUBLIC // ret
  2850. HBeginPQEnum( //
  2851. VOID) // no params
  2852. /*++
  2853. Routine Description:
  2854. Parameters:
  2855. Return Value:
  2856. Notes:
  2857. --*/
  2858. {
  2859. Assert(vfInShadowCrit != 0);
  2860. return ((CSC_ENUMCOOKIE)BeginSeqReadPQ(lpdbShadow));
  2861. }
  2862. int PUBLIC EndPQEnum(
  2863. CSC_ENUMCOOKIE hPQEnum
  2864. )
  2865. /*++
  2866. Routine Description:
  2867. Parameters:
  2868. Return Value:
  2869. Notes:
  2870. --*/
  2871. {
  2872. Assert(vfInShadowCrit != 0);
  2873. return(EndSeqReadQ((CSCHFILE)hPQEnum));
  2874. }
  2875. int PUBLIC // ret
  2876. PrevPriSHADOW(
  2877. LPPQPARAMS lpPQ
  2878. )
  2879. /*++
  2880. Routine Description:
  2881. Parameters:
  2882. Return Value:
  2883. Notes:
  2884. --*/
  2885. {
  2886. QREC sQrec;
  2887. int iRet=-1;
  2888. Assert(vfInShadowCrit != 0);
  2889. sQrec.uchType = 0;
  2890. if (lpPQ->uPos)
  2891. {
  2892. sQrec.ulrecPrev = lpPQ->uPos;
  2893. iRet = SeqReadQ(lpPQ->uEnumCookie, &sQrec, &sQrec, Q_GETPREV);
  2894. }
  2895. else
  2896. {
  2897. iRet=SeqReadQ(lpPQ->uEnumCookie, &sQrec, &sQrec, Q_GETLAST);
  2898. }
  2899. if (iRet>=0)
  2900. {
  2901. // it is possible, that as the agent is traversing the PQ,
  2902. // the next inode he is trying to read may have already been
  2903. // deleted. In such a case, just fail, so he will start all
  2904. // over in due course
  2905. if(sQrec.uchType == REC_DATA)
  2906. {
  2907. lpPQ->hShare = sQrec.ulidShare;
  2908. lpPQ->hDir = sQrec.ulidDir;
  2909. lpPQ->hShadow = sQrec.ulidShadow;
  2910. lpPQ->ulStatus = sQrec.usStatus;
  2911. if (FInodeIsFile(lpdbShadow, sQrec.ulidDir, sQrec.ulidShadow))
  2912. {
  2913. lpPQ->ulStatus |= SHADOW_IS_FILE;
  2914. }
  2915. lpPQ->ulRefPri = (ULONG)(sQrec.uchRefPri);
  2916. lpPQ->ulHintPri = (ULONG)(sQrec.uchHintPri);
  2917. lpPQ->ulHintFlags = (ULONG)(sQrec.uchHintFlags);
  2918. lpPQ->uPos = sQrec.ulrecPrev;
  2919. lpPQ->dwPQVersion = vdwPQVersion;
  2920. }
  2921. else
  2922. {
  2923. lpPQ->hShadow = 0;
  2924. iRet = -1;
  2925. }
  2926. }
  2927. return (iRet);
  2928. }
  2929. int PUBLIC // ret
  2930. NextPriSHADOW(
  2931. LPPQPARAMS lpPQ
  2932. )
  2933. /*++
  2934. Routine Description:
  2935. Parameters:
  2936. Return Value:
  2937. Notes:
  2938. --*/
  2939. {
  2940. QREC sQrec;
  2941. int iRet=-1;
  2942. Assert(vfInShadowCrit != 0);
  2943. sQrec.uchType = 0;
  2944. if (lpPQ->uPos)
  2945. {
  2946. sQrec.ulrecNext = lpPQ->uPos;
  2947. iRet = SeqReadQ(lpPQ->uEnumCookie, &sQrec, &sQrec, Q_GETNEXT);
  2948. }
  2949. else
  2950. {
  2951. iRet = SeqReadQ(lpPQ->uEnumCookie, &sQrec, &sQrec, Q_GETFIRST);
  2952. }
  2953. if (iRet >=0)
  2954. {
  2955. // it is possible, that as the agent is traversing the PQ,
  2956. // the next inode he is trying to read may have already been
  2957. // deleted. In such a case, just fail, so he will start all
  2958. // over in due course
  2959. if(sQrec.uchType == REC_DATA)
  2960. {
  2961. lpPQ->hShare = sQrec.ulidShare;
  2962. lpPQ->hDir = sQrec.ulidDir;
  2963. lpPQ->hShadow = sQrec.ulidShadow;
  2964. lpPQ->ulStatus = (sQrec.usStatus);
  2965. if (FInodeIsFile(lpdbShadow, sQrec.ulidDir, sQrec.ulidShadow))
  2966. {
  2967. lpPQ->ulStatus |= SHADOW_IS_FILE;
  2968. }
  2969. lpPQ->ulRefPri = (ULONG)(sQrec.uchRefPri);
  2970. lpPQ->ulHintPri = (ULONG)(sQrec.uchHintPri);
  2971. lpPQ->ulHintFlags = (ULONG)(sQrec.uchHintFlags);
  2972. lpPQ->uPos = sQrec.ulrecNext;
  2973. lpPQ->dwPQVersion = vdwPQVersion;
  2974. }
  2975. else
  2976. {
  2977. lpPQ->hShadow = 0;
  2978. iRet = -1;
  2979. }
  2980. }
  2981. return (iRet);
  2982. }
  2983. int GetRenameAliasHSHADOW( HSHADOW hShadow,
  2984. HSHADOW hDir,
  2985. LPHSHADOW lphDirFrom,
  2986. LPHSHADOW lphShadowFrom
  2987. )
  2988. /*++
  2989. Routine Description:
  2990. Parameters:
  2991. Return Value:
  2992. Notes:
  2993. --*/
  2994. {
  2995. int iRet = SRET_ERROR;
  2996. LPFILERECEXT lpFR = NULL, lpFRUse;
  2997. PRIQREC sPQ;
  2998. if (InuseGlobalFRExt())
  2999. {
  3000. if (!(lpFR = (LPFILERECEXT)AllocMem(sizeof(FILERECEXT))))
  3001. goto bailout;
  3002. lpFRUse = lpFR;
  3003. }
  3004. else
  3005. {
  3006. UseGlobalFilerecExt();
  3007. lpFRUse = &vsFRExt;
  3008. }
  3009. *lphShadowFrom = *lphDirFrom = 0;
  3010. if(FindPriQRecord(lpdbShadow, hDir, hShadow, &sPQ) < 0)
  3011. {
  3012. goto bailout;
  3013. }
  3014. if(!CShadowFindFilerecFromInode(lpdbShadow, hDir, hShadow, &sPQ, lpFRUse))
  3015. goto bailout;
  3016. Assert(lpFRUse->sFR.ulidShadow == sPQ.ulidShadow);
  3017. *lphShadowFrom = lpFRUse->sFR.ulidShadowOrg;
  3018. if (*lphShadowFrom)
  3019. {
  3020. FindAncestorsFromInode(lpdbShadow, *lphShadowFrom, lphDirFrom, NULL);
  3021. }
  3022. iRet = SRET_OK;
  3023. bailout:
  3024. if (lpFR)
  3025. FreeMem(lpFR);
  3026. else
  3027. UnUseGlobalFilerecExt();
  3028. return iRet;
  3029. }
  3030. int
  3031. CopyHSHADOW(
  3032. HSHADOW hDir,
  3033. HSHADOW hShadow,
  3034. LPSTR lpszDestinationFile,
  3035. ULONG ulAttrib
  3036. )
  3037. /*++
  3038. Routine Description:
  3039. Parameters:
  3040. Return Value:
  3041. Notes:
  3042. --*/
  3043. {
  3044. return (CopyFileLocal(lpdbShadow, hShadow, lpszDestinationFile, ulAttrib));
  3045. }
  3046. int RenameDataHSHADOW(
  3047. ULONG ulidFrom,
  3048. ULONG ulidTo
  3049. )
  3050. {
  3051. return (RenameInode(lpdbShadow, ulidFrom, ulidTo));
  3052. }
  3053. int MetaMatchInit(
  3054. ULONG *lpuCookie
  3055. )
  3056. /*++
  3057. Routine Description:
  3058. Parameters:
  3059. Return Value:
  3060. Notes:
  3061. --*/
  3062. {
  3063. *lpuCookie = 1;
  3064. return(0);
  3065. }
  3066. int MetaMatch(
  3067. HSHADOW hDir,
  3068. LPFIND32 lpFind32,
  3069. ULONG *lpuCookie,
  3070. LPHSHADOW lphShadow,
  3071. ULONG *lpuStatus,
  3072. LPOTHERINFO lpOI,
  3073. METAMATCHPROC lpfnMMP,
  3074. LPVOID lpData
  3075. )
  3076. /*++
  3077. Routine Description:
  3078. Parameters:
  3079. Return Value:
  3080. Notes:
  3081. --*/
  3082. {
  3083. int iRet;
  3084. Assert(vfInShadowCrit != 0);
  3085. if (hDir)
  3086. iRet = MetaMatchDir(hDir, lpFind32, lpuCookie, lphShadow, lpuStatus, lpOI, lpfnMMP, lpData);
  3087. else
  3088. iRet = MetaMatchShare(hDir, lpFind32, lpuCookie, lphShadow, lpuStatus, lpOI, lpfnMMP, lpData);
  3089. return (iRet);
  3090. }
  3091. int MetaMatchShare(
  3092. HSHADOW hDir,
  3093. LPFIND32 lpFind32,
  3094. ULONG *lpuCookie,
  3095. LPHSHADOW lphShadow,
  3096. ULONG *lpuStatus,
  3097. LPOTHERINFO lpOI,
  3098. METAMATCHPROC lpfnMMP,
  3099. LPVOID lpData
  3100. )
  3101. /*++
  3102. Routine Description:
  3103. Parameters:
  3104. Return Value:
  3105. Notes:
  3106. --*/
  3107. {
  3108. int iRet = -1, iFound=-1;
  3109. GENERICHEADER sGH;
  3110. CSCHFILE hf = NULL;
  3111. ULONG uSize, ulrecPosFound = 0;
  3112. OTHERINFO sOI;
  3113. SHAREREC sSR;
  3114. BOOL fCached;
  3115. if (!(hf = OpenInodeFileAndCacheHandle(lpdbShadow, ULID_SHARE, ACCESS_READWRITE, &fCached)))
  3116. {
  3117. goto bailout;
  3118. }
  3119. if(ReadHeader(hf, &sGH, sizeof(FILEHEADER)) < 0)
  3120. {
  3121. goto bailout;
  3122. }
  3123. for (;*lpuCookie <=sGH.ulRecords;)
  3124. {
  3125. iRet = ReadRecord(hf, &sGH, *lpuCookie, (LPGENERICREC)&sSR);
  3126. if (iRet < 0)
  3127. goto bailout;
  3128. // bump the record pointer
  3129. *lpuCookie += iRet;
  3130. if (sSR.uchType != REC_DATA)
  3131. continue;
  3132. CopySharerecToFindInfo(&sSR, lpFind32);
  3133. CopySharerecToOtherInfo(&sSR, &sOI);
  3134. if (lpOI)
  3135. {
  3136. *lpOI = sOI;
  3137. }
  3138. *lpuStatus = (ULONG)(sSR.usStatus);
  3139. *lphShadow = sSR.ulidShadow;
  3140. iFound = (*lpfnMMP)(lpFind32, hDir, *lphShadow, *lpuStatus, &sOI, lpData);
  3141. if (iFound==MM_RET_FOUND_CONTINUE)
  3142. {
  3143. ulrecPosFound = *lpuCookie - iRet;
  3144. }
  3145. else if (iFound <= MM_RET_FOUND_BREAK)
  3146. {
  3147. break;
  3148. }
  3149. }
  3150. if (ulrecPosFound || (iFound==MM_RET_FOUND_BREAK))
  3151. {
  3152. if (ulrecPosFound)
  3153. {
  3154. ReadRecord(hf, &sGH, ulrecPosFound, (LPGENERICREC)&sSR);
  3155. CopySharerecToFindInfo(&sSR, lpFind32);
  3156. *lpuStatus = (ULONG)(sSR.usStatus);
  3157. *lphShadow = sSR.ulidShadow;
  3158. if (lpOI)
  3159. {
  3160. CopySharerecToOtherInfo(&sSR, lpOI);
  3161. }
  3162. }
  3163. }
  3164. else
  3165. {
  3166. *lpuStatus = *lphShadow = 0;
  3167. }
  3168. iRet = SRET_OK;
  3169. bailout:
  3170. if (hf && !fCached)
  3171. {
  3172. Assert(vfStopHandleCaching);
  3173. CloseFileLocal(hf);
  3174. }
  3175. else
  3176. {
  3177. Assert(!hf || !vfStopHandleCaching);
  3178. }
  3179. return (iRet);
  3180. }
  3181. int MetaMatchDir(
  3182. HSHADOW hDir,
  3183. LPFIND32 lpFind32,
  3184. ULONG *lpuCookie,
  3185. LPHSHADOW lphShadow,
  3186. ULONG *lpuStatus,
  3187. LPOTHERINFO lpOI,
  3188. METAMATCHPROC lpfnMMP,
  3189. LPVOID lpData
  3190. )
  3191. /*++
  3192. Routine Description:
  3193. Parameters:
  3194. Return Value:
  3195. Notes:
  3196. --*/
  3197. {
  3198. int iRet = SRET_ERROR, iFound=-1;
  3199. GENERICHEADER sGH;
  3200. CSCHFILE hf = NULL;
  3201. ULONG uSize, ulrecPosFound = 0;
  3202. OTHERINFO sOI;
  3203. LPFILERECEXT lpFR = NULL, lpFRUse;
  3204. BOOL fCached;
  3205. PRIQREC sPQ;
  3206. if (InuseGlobalFRExt())
  3207. {
  3208. if (!(lpFR = (LPFILERECEXT)AllocMem(sizeof(FILERECEXT))))
  3209. goto bailout;
  3210. lpFRUse = lpFR;
  3211. }
  3212. else
  3213. {
  3214. UseGlobalFilerecExt();
  3215. lpFRUse = &vsFRExt;
  3216. }
  3217. if (FInodeIsFile(lpdbShadow, 0, hDir))
  3218. {
  3219. SetLastErrorLocal(ERROR_INVALID_PARAMETER);
  3220. goto bailout;
  3221. }
  3222. if (!(hf = OpenInodeFileAndCacheHandle(lpdbShadow, hDir, ACCESS_READWRITE, &fCached)))
  3223. {
  3224. DWORD dwError;
  3225. dwError = GetLastErrorLocal();
  3226. if(FindPriQRecordInternal(lpdbShadow, hDir, &sPQ) < 0)
  3227. {
  3228. SetLastErrorLocal(ERROR_INVALID_PARAMETER);
  3229. }
  3230. else
  3231. {
  3232. SetCSCDatabaseErrorFlags(CSC_DATABASE_ERROR_MISSING_INODE);
  3233. SetLastErrorLocal(dwError);
  3234. }
  3235. goto bailout;
  3236. }
  3237. if(ReadHeader(hf, &sGH, sizeof(FILEHEADER)) < 0)
  3238. {
  3239. goto bailout;
  3240. }
  3241. for (;*lpuCookie <=sGH.ulRecords;)
  3242. {
  3243. iRet = ReadRecord(hf, &sGH, *lpuCookie, (LPGENERICREC)lpFRUse);
  3244. if (iRet < 0)
  3245. {
  3246. goto bailout;
  3247. }
  3248. // bump the record pointer
  3249. *lpuCookie += iRet;
  3250. if (lpFRUse->sFR.uchType != REC_DATA)
  3251. {
  3252. continue;
  3253. }
  3254. CopyFilerecToFindInfo(lpFRUse, lpFind32);
  3255. *lphShadow = lpFRUse->sFR.ulidShadow;
  3256. CopyFilerecToOtherInfo(lpFRUse, &sOI);
  3257. if (lpOI)
  3258. {
  3259. *lpOI = sOI;
  3260. }
  3261. *lpuStatus = (ULONG)(lpFRUse->sFR.uStatus);
  3262. iFound = (*lpfnMMP)(lpFind32, hDir, *lphShadow, *lpuStatus, &sOI, lpData);
  3263. if (iFound==MM_RET_FOUND_CONTINUE)
  3264. {
  3265. ulrecPosFound = *lpuCookie - iRet;
  3266. }
  3267. else if (iFound <= MM_RET_FOUND_BREAK)
  3268. {
  3269. break;
  3270. }
  3271. }
  3272. if (ulrecPosFound || (iFound==MM_RET_FOUND_BREAK))
  3273. {
  3274. if (ulrecPosFound)
  3275. {
  3276. ReadRecord(hf, &sGH, ulrecPosFound, (LPGENERICREC)lpFRUse);
  3277. CopyFilerecToFindInfo(lpFRUse, lpFind32);
  3278. *lpuStatus = (ULONG)(lpFRUse->sFR.uStatus);
  3279. *lphShadow = lpFRUse->sFR.ulidShadow;
  3280. if (lpOI)
  3281. {
  3282. CopyFilerecToOtherInfo(lpFRUse, lpOI);
  3283. }
  3284. }
  3285. }
  3286. else
  3287. {
  3288. *lpuStatus = *lphShadow = 0;
  3289. }
  3290. iRet = SRET_OK;
  3291. bailout:
  3292. if (hf && !fCached)
  3293. {
  3294. Assert(vfStopHandleCaching);
  3295. CloseFileLocal(hf);
  3296. }
  3297. else
  3298. {
  3299. Assert(!hf || !vfStopHandleCaching);
  3300. }
  3301. if (lpFR)
  3302. {
  3303. FreeMem(lpFR);
  3304. }
  3305. else
  3306. {
  3307. UnUseGlobalFilerecExt();
  3308. }
  3309. return (iRet);
  3310. }
  3311. int CreateHint(
  3312. HSHADOW hShadow,
  3313. LPFIND32 lpFind32,
  3314. ULONG ulHintFlags,
  3315. ULONG ulHintPri,
  3316. LPHSHADOW lphHint
  3317. )
  3318. /*++
  3319. Routine Description:
  3320. Parameters:
  3321. Return Value:
  3322. Notes:
  3323. --*/
  3324. {
  3325. int iRet=SRET_ERROR;
  3326. OTHERINFO sOI;
  3327. ULONG uStatus;
  3328. // This must be either a wildcard hint, or else it can't be without an Fsobj
  3329. if ((GetShadow(hShadow, lpFind32->cFileName, lphHint, lpFind32, &uStatus, &sOI)>=SRET_OK)
  3330. && (*lphHint))
  3331. {
  3332. Assert((FHasWildcard(lpFind32->cFileName, MAX_PATH) || !mNotFsobj(uStatus)));
  3333. if ((sOI.ulHintPri < MAX_HINT_PRI) &&
  3334. (ulHintPri < MAX_HINT_PRI)
  3335. )
  3336. {
  3337. sOI.ulHintPri += ulHintPri;
  3338. if (sOI.ulHintPri <= MAX_HINT_PRI)
  3339. {
  3340. sOI.ulHintFlags = ulHintFlags;
  3341. mClearBits(sOI.ulHintFlags, HINT_WILDCARD);
  3342. iRet = SetShadowInfoEx(hShadow, *lphHint, lpFind32, 0, SHADOW_FLAGS_OR, &sOI, NULL, NULL);
  3343. if (iRet>=SRET_OK)
  3344. {
  3345. iRet = SRET_OBJECT_HINT;
  3346. }
  3347. }
  3348. }
  3349. }
  3350. else
  3351. {
  3352. if (FHasWildcard(lpFind32->cFileName, MAX_PATH) && (ulHintPri <= MAX_HINT_PRI))
  3353. {
  3354. InitOtherInfo(&sOI);
  3355. sOI.ulHintFlags = ulHintFlags;
  3356. sOI.ulHintPri = ulHintPri;
  3357. // Tell him that we are creating a file shadow
  3358. lpFind32->dwFileAttributes = FILE_ATTRIBUTE_ARCHIVE;
  3359. iRet = CreateShadowInternal(hShadow, lpFind32, SHADOW_NOT_FSOBJ, &sOI, lphHint);
  3360. if (iRet>=SRET_OK)
  3361. {
  3362. iRet = SRET_WILDCARD_HINT;
  3363. }
  3364. }
  3365. }
  3366. return (iRet);
  3367. }
  3368. int DeleteHint(
  3369. HSHADOW hShadow,
  3370. USHORT *lpuHintName,
  3371. BOOL fClearAll
  3372. )
  3373. /*++
  3374. Routine Description:
  3375. Parameters:
  3376. Return Value:
  3377. Notes:
  3378. --*/
  3379. {
  3380. ULONG uStatus;
  3381. HSHADOW hChild;
  3382. int iRet=SRET_ERROR;
  3383. OTHERINFO sOI;
  3384. if (GetShadow(hShadow, lpuHintName, &hChild, NULL, &uStatus, &sOI)>=SRET_OK)
  3385. {
  3386. // Nuke if there is no filesystem object with it
  3387. if (mNotFsobj(uStatus))
  3388. {
  3389. iRet = DeleteShadowInternal(hShadow, hChild, TRUE);
  3390. if (iRet>=SRET_OK)
  3391. {
  3392. iRet = SRET_WILDCARD_HINT;
  3393. }
  3394. }
  3395. else
  3396. {
  3397. BOOL fDoit = TRUE;
  3398. if (fClearAll)
  3399. {
  3400. sOI.ulHintPri = 0;
  3401. sOI.ulHintFlags = 0;
  3402. }
  3403. else
  3404. {
  3405. if (sOI.ulHintPri > 0)
  3406. {
  3407. --sOI.ulHintPri;
  3408. }
  3409. else
  3410. {
  3411. fDoit = FALSE;
  3412. }
  3413. }
  3414. if (fDoit)
  3415. {
  3416. iRet = SetShadowInfoEx( hShadow,
  3417. hChild,
  3418. NULL,
  3419. uStatus,
  3420. SHADOW_FLAGS_ASSIGN,
  3421. &sOI,
  3422. NULL,
  3423. NULL
  3424. );
  3425. if (iRet>=SRET_OK)
  3426. {
  3427. iRet = SRET_OBJECT_HINT;
  3428. }
  3429. }
  3430. }
  3431. }
  3432. return (iRet);
  3433. }
  3434. int CreateGlobalHint(
  3435. USHORT *lpuName,
  3436. ULONG ulHintFlags,
  3437. ULONG ulHintPri
  3438. )
  3439. /*++
  3440. Routine Description:
  3441. Parameters:
  3442. Return Value:
  3443. Notes:
  3444. --*/
  3445. {
  3446. int iRet = SRET_ERROR;
  3447. SHAREREC sSR;
  3448. ULONG ulidShare, ulT;
  3449. #if 0
  3450. if (FindShareRecord(lpdbShadow, lpuName, &sSR))
  3451. {
  3452. if ((sSR.uchHintPri < MAX_HINT_PRI) &&
  3453. (ulHintPri < MAX_HINT_PRI)
  3454. )
  3455. {
  3456. ulT = (ULONG)sSR.uchHintPri + ulHintPri;
  3457. if (ulT <= MAX_HINT_PRI)
  3458. {
  3459. // Setting a hint on the root of the server
  3460. sSR.uchHintFlags = (UCHAR)(ulHintFlags);
  3461. sSR.uchHintPri = (UCHAR)(ulT);
  3462. mClearBits(sSR.uchHintFlags, HINT_WILDCARD);
  3463. Assert(FHasWildcard(lpuName, MAX_PATH) || !mNotFsobj(sSR.uStatus));
  3464. if(SetShareRecord(lpdbShadow, sSR.ulShare, &sSR) > 0)
  3465. {
  3466. iRet = SRET_OBJECT_HINT;
  3467. }
  3468. }
  3469. }
  3470. }
  3471. else
  3472. {
  3473. if (FHasWildcard(lpuName, MAX_SERVER_SHARE))
  3474. {
  3475. if (ulidShare = AllocShareRecord(lpdbShadow, lpuName))
  3476. {
  3477. //InitShareRec(lpuName, &sSR);
  3478. InitShareRec(&sSR, lpuName, 0);
  3479. sSR.ulShare = ulidShare;
  3480. sSR.ulidShadow = 0xffffffff; // Just to fool FindOpenHSHADOW
  3481. sSR.uchHintFlags = (UCHAR)ulHintFlags;
  3482. sSR.uchHintPri = (UCHAR)ulHintPri;
  3483. mSetBits(sSR.uStatus, SHADOW_NOT_FSOBJ);
  3484. if(AddShareRecord(lpdbShadow, &sSR) > 0)
  3485. {
  3486. iRet = SRET_WILDCARD_HINT;
  3487. }
  3488. }
  3489. }
  3490. }
  3491. #endif
  3492. return (iRet);
  3493. }
  3494. int DeleteGlobalHint(
  3495. USHORT *lpuName,
  3496. BOOL fClearAll
  3497. )
  3498. /*++
  3499. Routine Description:
  3500. Parameters:
  3501. Return Value:
  3502. Notes:
  3503. --*/
  3504. {
  3505. int iRet = SRET_ERROR;
  3506. SHAREREC sSR;
  3507. #if 0
  3508. if (FindShareRecord(lpdbShadow, lpuName, &sSR))
  3509. {
  3510. if (mNotFsobj(sSR.uStatus))
  3511. {
  3512. iRet = DeleteShareRecord(lpdbShadow, sSR.ulShare);
  3513. }
  3514. else
  3515. {
  3516. if (fClearAll)
  3517. {
  3518. sSR.uchHintPri = sSR.uchHintFlags = 0;
  3519. }
  3520. else
  3521. {
  3522. if (sSR.uchHintPri > 0)
  3523. {
  3524. --sSR.uchHintPri;
  3525. }
  3526. }
  3527. if(SetShareRecord(lpdbShadow, sSR.ulShare, &sSR) > 0)
  3528. {
  3529. iRet = SRET_OK;
  3530. }
  3531. }
  3532. }
  3533. #endif
  3534. return (iRet);
  3535. }
  3536. int CopyFilerecToOtherInfo(
  3537. LPFILERECEXT lpFR,
  3538. LPOTHERINFO lpOI
  3539. )
  3540. /*++
  3541. Routine Description:
  3542. Parameters:
  3543. Return Value:
  3544. Notes:
  3545. --*/
  3546. {
  3547. lpOI->ulRefPri = (ULONG)(lpFR->sFR.uchRefPri);
  3548. lpOI->ulIHPri = (ULONG)(lpFR->sFR.uchIHPri);
  3549. lpOI->ulHintFlags = (ULONG)(lpFR->sFR.uchHintFlags);
  3550. lpOI->ulHintPri = (ULONG)(lpFR->sFR.uchHintPri);
  3551. lpOI->ftOrgTime = lpFR->sFR.ftOrgTime;
  3552. lpOI->ftLastRefreshTime = IFSMgr_NetToWin32Time(lpFR->sFR.ulLastRefreshTime);
  3553. return(0);
  3554. }
  3555. int CopyOtherInfoToFilerec(
  3556. LPOTHERINFO lpOI,
  3557. LPFILERECEXT lpFR
  3558. )
  3559. /*++
  3560. Routine Description:
  3561. Parameters:
  3562. Return Value:
  3563. Notes:
  3564. --*/
  3565. {
  3566. if (lpOI->ulIHPri != RETAIN_VALUE)
  3567. {
  3568. lpFR->sFR.uchIHPri = (UCHAR)(lpOI->ulIHPri);
  3569. }
  3570. if (lpOI->ulHintPri != RETAIN_VALUE)
  3571. {
  3572. lpFR->sFR.uchHintPri = (UCHAR)(lpOI->ulHintPri);
  3573. }
  3574. if (lpOI->ulRefPri != RETAIN_VALUE)
  3575. {
  3576. lpFR->sFR.uchRefPri = (UCHAR)((lpOI->ulRefPri <= MAX_PRI)?lpOI->ulRefPri:MAX_PRI);
  3577. }
  3578. if (lpOI->ulHintFlags != RETAIN_VALUE)
  3579. {
  3580. lpFR->sFR.uchHintFlags = (UCHAR)(lpOI->ulHintFlags);
  3581. }
  3582. return(0);
  3583. }
  3584. int CopySharerecToOtherInfo(LPSHAREREC lpSR, LPOTHERINFO lpOI)
  3585. /*++
  3586. Routine Description:
  3587. Parameters:
  3588. Return Value:
  3589. Notes:
  3590. --*/
  3591. {
  3592. lpOI->ulRefPri = 0;
  3593. lpOI->ulRootStatus = (ULONG)(lpSR->usRootStatus);
  3594. lpOI->ulHintFlags = (ULONG)(lpSR->uchHintFlags);
  3595. lpOI->ulHintPri = (ULONG)(lpSR->uchHintPri);
  3596. return(0);
  3597. }
  3598. int CopyOtherInfoToSharerec(
  3599. LPOTHERINFO lpOI,
  3600. LPSHAREREC lpSR
  3601. )
  3602. /*++
  3603. Routine Description:
  3604. Parameters:
  3605. Return Value:
  3606. Notes:
  3607. --*/
  3608. {
  3609. if (lpOI->ulHintFlags != RETAIN_VALUE)
  3610. {
  3611. lpSR->uchHintFlags = (UCHAR)(lpOI->ulHintFlags);
  3612. }
  3613. if (lpOI->ulHintPri != RETAIN_VALUE)
  3614. {
  3615. lpSR->uchHintPri = (UCHAR)(lpOI->ulHintPri);
  3616. }
  3617. return(0);
  3618. }
  3619. int CopyPQToOtherInfo( LPPRIQREC lpPQ,
  3620. LPOTHERINFO lpOI)
  3621. /*++
  3622. Routine Description:
  3623. Parameters:
  3624. Return Value:
  3625. Notes:
  3626. --*/
  3627. {
  3628. lpOI->ulRefPri = (ULONG)(lpPQ->uchRefPri);
  3629. lpOI->ulIHPri = (ULONG)(lpPQ->uchIHPri);
  3630. lpOI->ulHintFlags = (ULONG)(lpPQ->uchHintFlags);
  3631. lpOI->ulHintPri = (ULONG)(lpPQ->uchHintPri);
  3632. return(0);
  3633. }
  3634. int CopyOtherInfoToPQ( LPOTHERINFO lpOI,
  3635. LPPRIQREC lpPQ)
  3636. /*++
  3637. Routine Description:
  3638. Parameters:
  3639. Return Value:
  3640. Notes:
  3641. --*/
  3642. {
  3643. if (lpOI->ulIHPri != RETAIN_VALUE)
  3644. {
  3645. lpPQ->uchIHPri = (UCHAR)(lpOI->ulIHPri);
  3646. }
  3647. if (lpOI->ulHintPri != RETAIN_VALUE)
  3648. {
  3649. lpPQ->uchHintPri = (UCHAR)(lpOI->ulHintPri);
  3650. }
  3651. if (lpOI->ulRefPri != RETAIN_VALUE)
  3652. {
  3653. lpPQ->uchRefPri = (UCHAR)((lpOI->ulRefPri <= MAX_PRI)?lpOI->ulRefPri:MAX_PRI);
  3654. }
  3655. if (lpOI->ulHintFlags != RETAIN_VALUE)
  3656. {
  3657. lpPQ->uchHintFlags = (UCHAR)(lpOI->ulHintFlags);
  3658. }
  3659. return(0);
  3660. }
  3661. int CopySharerecToFindInfo( LPSHAREREC lpSR,
  3662. LPFIND32 lpFind32
  3663. )
  3664. /*++
  3665. Routine Description:
  3666. Parameters:
  3667. Return Value:
  3668. Notes:
  3669. --*/
  3670. {
  3671. memset(lpFind32, 0, sizeof(WIN32_FIND_DATA));
  3672. // lpFind32->dwReserved0 = lpSR->ulShare;
  3673. // lpFind32->dwReserved1 = lpSR->ulidShadow;
  3674. lpFind32->dwFileAttributes = lpSR->dwFileAttrib & ~FILE_ATTRIBUTE_ENCRYPTED;
  3675. lpFind32->ftLastWriteTime = lpSR->ftLastWriteTime;
  3676. lpFind32->ftLastAccessTime = lpSR->ftOrgTime;
  3677. memset(lpFind32->cFileName, 0, sizeof(lpFind32->cFileName));
  3678. memcpy(lpFind32->cFileName, lpSR->rgPath, sizeof(lpSR->rgPath));
  3679. return(0);
  3680. }
  3681. int CopyFindInfoToSharerec(
  3682. LPFIND32 lpFind32,
  3683. LPSHAREREC lpSR
  3684. )
  3685. /*++
  3686. Routine Description:
  3687. Parameters:
  3688. Return Value:
  3689. Notes:
  3690. --*/
  3691. {
  3692. // be paranoid and or the directory attribute bit anyway
  3693. lpSR->dwFileAttrib = (lpFind32->dwFileAttributes | FILE_ATTRIBUTE_DIRECTORY);
  3694. lpSR->ftLastWriteTime = lpFind32->ftLastWriteTime;
  3695. return(0);
  3696. }
  3697. int
  3698. CopySharerecToShadowInfo(
  3699. LPSHAREREC lpSR,
  3700. LPSHADOWINFO lpSI
  3701. )
  3702. /*++
  3703. Routine Description:
  3704. Parameters:
  3705. Return Value:
  3706. Notes:
  3707. --*/
  3708. {
  3709. memset(lpSI, 0, sizeof(SHADOWINFO));
  3710. lpSI->hShare = lpSR->ulShare;
  3711. lpSI->hShadow = lpSR->ulidShadow;
  3712. lpSI->uStatus = (ULONG)(lpSR->uStatus);
  3713. lpSI->uRootStatus = (ULONG)(lpSR->usRootStatus);
  3714. lpSI->ulHintFlags = (ULONG)(lpSR->uchHintFlags);
  3715. lpSI->ulHintPri = (ULONG)(lpSR->uchHintPri);
  3716. return 0;
  3717. }
  3718. int CopyOtherInfoToShadowInfo(
  3719. LPOTHERINFO lpOI,
  3720. LPSHADOWINFO lpShadowInfo
  3721. )
  3722. /*++
  3723. Routine Description:
  3724. Parameters:
  3725. Return Value:
  3726. Notes:
  3727. --*/
  3728. {
  3729. lpShadowInfo->ulHintFlags = lpOI->ulHintFlags;
  3730. lpShadowInfo->ulHintPri = lpOI->ulHintPri;
  3731. lpShadowInfo->ftOrgTime = lpOI->ftOrgTime;
  3732. lpShadowInfo->ftLastRefreshTime = lpOI->ftLastRefreshTime;
  3733. lpShadowInfo->dwNameSpaceVersion = vdwCSCNameSpaceVersion;
  3734. return(0); //stop complaining about no return value
  3735. }
  3736. int InitOtherInfo(
  3737. LPOTHERINFO lpOI)
  3738. /*++
  3739. Routine Description:
  3740. Parameters:
  3741. Return Value:
  3742. Notes:
  3743. --*/
  3744. {
  3745. memset(lpOI, 0xff, sizeof(OTHERINFO));
  3746. return(0);
  3747. }
  3748. int PUBLIC // ret
  3749. FindOpenHSHADOW( //
  3750. LPFINDSHADOW lpFindShadow,
  3751. LPHSHADOW lphShadow,
  3752. LPFIND32 lpFind32,
  3753. ULONG far *lpuShadowStatus,
  3754. LPOTHERINFO lpOI
  3755. )
  3756. /*++
  3757. Routine Description:
  3758. Parameters:
  3759. Return Value:
  3760. Notes:
  3761. --*/
  3762. {
  3763. int iRet = SRET_ERROR;
  3764. MetaMatchInit(&(lpFindShadow->ulCookie));
  3765. if ((lpFindShadow->uSrchFlags & FLAG_FINDSHADOW_ALLOW_NORMAL)
  3766. && ((lpFindShadow->uAttrib & 0xff) == FILE_ATTRIBUTE_LABEL))
  3767. {
  3768. BCSToUni(lpFind32->cFileName, vszShadowVolume, strlen(vszShadowVolume), BCS_OEM);
  3769. iRet = 1;
  3770. }
  3771. else
  3772. {
  3773. if (MetaMatch(lpFindShadow->hDir, lpFind32
  3774. , &(lpFindShadow->ulCookie)
  3775. , lphShadow, lpuShadowStatus
  3776. , lpOI, lpFindShadow->lpfnMMProc
  3777. , (LPVOID)lpFindShadow)==SRET_OK)
  3778. {
  3779. iRet = (*lphShadow)?SRET_OK:SRET_ERROR;
  3780. }
  3781. }
  3782. return (iRet);
  3783. }
  3784. int PUBLIC FindNextHSHADOW( //
  3785. LPFINDSHADOW lpFindShadow,
  3786. LPHSHADOW lphShadow,
  3787. LPFIND32 lpFind32,
  3788. ULONG far *lpuShadowStatus,
  3789. LPOTHERINFO lpOI
  3790. )
  3791. /*++
  3792. Routine Description:
  3793. Parameters:
  3794. Return Value:
  3795. Notes:
  3796. --*/
  3797. {
  3798. int iRet = SRET_ERROR;
  3799. if ((lpFindShadow->uSrchFlags & FLAG_FINDSHADOW_ALLOW_NORMAL)
  3800. && ((lpFindShadow->uAttrib & 0xff) == FILE_ATTRIBUTE_LABEL))
  3801. {
  3802. BCSToUni(lpFind32->cFileName, vszShadowVolume, strlen(vszShadowVolume), BCS_OEM);
  3803. iRet = SRET_OK;
  3804. }
  3805. else
  3806. {
  3807. if (MetaMatch(lpFindShadow->hDir, lpFind32
  3808. , &(lpFindShadow->ulCookie), lphShadow
  3809. , lpuShadowStatus, lpOI
  3810. , lpFindShadow->lpfnMMProc
  3811. , (LPVOID)lpFindShadow)==SRET_OK)
  3812. {
  3813. iRet = (*lphShadow)?SRET_OK:SRET_ERROR;
  3814. }
  3815. }
  3816. return (iRet);
  3817. }
  3818. int PUBLIC // ret
  3819. FindCloseHSHADOW( //
  3820. LPFINDSHADOW lpFS
  3821. )
  3822. /*++
  3823. Routine Description:
  3824. Parameters:
  3825. Return Value:
  3826. Notes:
  3827. --*/
  3828. {
  3829. return SRET_OK;
  3830. }
  3831. // Callback function for MetaMatch,
  3832. // Return values: -1 => not found, stop; 0 => found, stop; 1 => keep going
  3833. int FsobjMMProc(
  3834. LPFIND32 lpFind32,
  3835. HSHADOW hDir,
  3836. HSHADOW hShadow,
  3837. ULONG uStatus,
  3838. LPOTHERINFO lpOI,
  3839. LPFINDSHADOW lpFSH
  3840. )
  3841. /*++
  3842. Routine Description:
  3843. Parameters:
  3844. Return Value:
  3845. Notes:
  3846. --*/
  3847. {
  3848. int matchSem, iRet;
  3849. BOOL fInvalid=FALSE, fIsDeleted, fIsSparse;
  3850. USHORT rgu83[11];
  3851. iRet = MM_RET_CONTINUE;
  3852. if (mNotFsobj(uStatus))
  3853. {
  3854. return (iRet);
  3855. }
  3856. #ifdef OFFLINE
  3857. if ((lpFSH->uSrchFlags & FLAG_FINDSHADOW_DONT_ALLOW_INSYNC)
  3858. && !mShadowOutofSync(uStatus))
  3859. return (iRet);
  3860. #endif //OFFLINE
  3861. // we are enumerating a directory
  3862. if (hDir && !(lpFSH->uSrchFlags & FLAG_FINDSHADOW_ALL))
  3863. {
  3864. fIsDeleted = mShadowDeleted(uStatus);
  3865. fIsSparse = (!mIsDir(lpFind32) && mShadowSparse(uStatus));
  3866. fInvalid = ((!(lpFSH->uSrchFlags & FLAG_FINDSHADOW_ALLOW_DELETED)&& fIsDeleted)
  3867. ||(!(lpFSH->uSrchFlags & FLAG_FINDSHADOW_ALLOW_SPARSE)&& fIsSparse)
  3868. ||(!(lpFSH->uSrchFlags & FLAG_FINDSHADOW_ALLOW_NORMAL) && (!fIsDeleted && !fIsSparse)));
  3869. }
  3870. /* If the call came from an NT style API we will use NT
  3871. semantics to match BOTH long names and short name with the
  3872. given pattern.
  3873. If it came from an old style API we will use NT style semantics
  3874. with the short name
  3875. */
  3876. if (lpFSH->uSrchFlags & FLAG_FINDSHADOW_NEWSTYLE)
  3877. matchSem = UFLG_NT;
  3878. else
  3879. matchSem = UFLG_DOS;
  3880. if (lpFSH->uSrchFlags & FLAG_FINDSHADOW_META)
  3881. matchSem |= UFLG_META;
  3882. if (lpFSH->uSrchFlags & FLAG_FINDSHADOW_NEWSTYLE)
  3883. {
  3884. if(IFSMgr_MetaMatch(lpFSH->lpPattern, lpFind32->cFileName, matchSem)||
  3885. (lpFind32->cAlternateFileName[0] && IFSMgr_MetaMatch(lpFSH->lpPattern, lpFind32->cAlternateFileName, matchSem)))
  3886. {
  3887. iRet = MM_RET_FOUND_BREAK;
  3888. }
  3889. }
  3890. else
  3891. {
  3892. // Check if there is an 83name. This can happen when in disconnected state
  3893. // we create an LFN object.
  3894. if (lpFind32->cAlternateFileName[0])
  3895. {
  3896. Conv83UniToFcbUni(lpFind32->cAlternateFileName, rgu83);
  3897. if(IFSMgr_MetaMatch(lpFSH->lpPattern, rgu83, matchSem))
  3898. {
  3899. // If this object has some attributes and they don't match with
  3900. // the search attributes passed in
  3901. if ((lpFind32->dwFileAttributes & FILE_ATTRIBUTE_EVERYTHING)
  3902. && !(lpFind32->dwFileAttributes & lpFSH->uAttrib))
  3903. {
  3904. // If this is not a metamatch
  3905. if (!(lpFSH->uSrchFlags & FLAG_FINDSHADOW_META))
  3906. {
  3907. // terminate search
  3908. iRet = MM_RET_BREAK;
  3909. }
  3910. else
  3911. {
  3912. // metamatching is going on, let us continue
  3913. Assert(iRet==MM_RET_CONTINUE);
  3914. }
  3915. }
  3916. else
  3917. {
  3918. iRet = MM_RET_FOUND_BREAK;
  3919. }
  3920. }
  3921. }
  3922. }
  3923. if ((iRet==MM_RET_FOUND_BREAK) && fInvalid)
  3924. {
  3925. // we found this object but it is invalid, as per the flags
  3926. // passed in
  3927. if (!(matchSem & UFLG_META))
  3928. {
  3929. // We are not doing metamatching
  3930. iRet = MM_RET_BREAK; // Say not found, and break
  3931. }
  3932. else
  3933. {
  3934. //we are doing metamatching.
  3935. iRet = MM_RET_CONTINUE; // ask him to keep going
  3936. }
  3937. }
  3938. return (iRet);
  3939. }
  3940. int GetShadowWithChecksProc(
  3941. LPFIND32 lpFind32,
  3942. HSHADOW hDir,
  3943. HSHADOW hShadow,
  3944. ULONG uStatus,
  3945. LPOTHERINFO lpOI,
  3946. LPSHADOWCHECK lpSC
  3947. )
  3948. /*++
  3949. Routine Description:
  3950. Parameters:
  3951. Return Value:
  3952. Notes:
  3953. --*/
  3954. {
  3955. int iRet = MM_RET_CONTINUE;
  3956. BOOL fHintMatch=FALSE, fObjMatch=FALSE;
  3957. ULONG ulHintFlagsThisLevel = HINT_EXCLUSION; // hint flags at this level
  3958. // Convert the patterns to uppercase, as demanded by metamatch
  3959. UniToUpper(lpFind32->cFileName, lpFind32->cFileName, sizeof(lpFind32->cFileName));
  3960. // This is a filesystem object and we haven't found our match yet
  3961. if (!mNotFsobj(uStatus) && !(lpSC->uFlagsOut & FLAG_OUT_SHADOWCHECK_FOUND))
  3962. {
  3963. // Is the source a name?
  3964. if (lpSC->uFlagsIn & FLAG_IN_SHADOWCHECK_NAME)
  3965. {
  3966. UniToUpper(lpFind32->cAlternateFileName, lpFind32->cAlternateFileName, sizeof(lpFind32->cFileName));
  3967. // check for normal name and it's alias
  3968. if((IFSMgr_MetaMatch(lpFind32->cFileName, lpSC->lpuName, UFLG_NT)||
  3969. //ACHTUNG UFLG_NT used even for short name because
  3970. // we are just checking from name coming down from ifsmgr as a path
  3971. // and it is never an FCB style name
  3972. IFSMgr_MetaMatch(lpFind32->cAlternateFileName, lpSC->lpuName, UFLG_NT)))
  3973. {
  3974. fObjMatch = TRUE;
  3975. }
  3976. }
  3977. else // The source is a shadow ID
  3978. {
  3979. fObjMatch = ((HSHADOW)(ULONG_PTR)(lpSC->lpuName)==hShadow);
  3980. }
  3981. if (fObjMatch)
  3982. {
  3983. if (lpSC->uFlagsIn & FLAG_IN_SHADOWCHECK_IGNOREHINTS)
  3984. {
  3985. // No hint checking needed, lets say we found it and stop
  3986. iRet = MM_RET_FOUND_BREAK;
  3987. }
  3988. else
  3989. {
  3990. // found it, mark it as being found.
  3991. lpSC->uFlagsOut |= FLAG_OUT_SHADOWCHECK_FOUND;
  3992. #ifdef MAYBE
  3993. lpSC->sOI = *lpOI;
  3994. #endif //MAYBE
  3995. if(fHintMatch = ((mIsHint(lpOI->ulHintFlags))!=0))
  3996. {
  3997. // Let this guy override all previous includes, because
  3998. // really speaking he is at a lower level in the hierarchy
  3999. // and by our logic, hints at lower level in the hierarchy
  4000. // dominate those coming from above
  4001. lpSC->ulHintPri = 0;
  4002. lpSC->ulHintFlags = 0;
  4003. iRet = MM_RET_FOUND_BREAK;
  4004. }
  4005. else
  4006. {
  4007. iRet = MM_RET_FOUND_CONTINUE;
  4008. }
  4009. }
  4010. }
  4011. }
  4012. else if (!(lpSC->uFlagsIn & FLAG_IN_SHADOWCHECK_IGNOREHINTS) // Don't ignore hints
  4013. && mNotFsobj(uStatus) // This IS a hint
  4014. && (!(lpSC->uFlagsIn & FLAG_IN_SHADOWCHECK_SUBTREE)
  4015. ||mHintSubtree(lpOI->ulHintFlags)))
  4016. {
  4017. // This is a pure hint and
  4018. // we are either at the end, so we can look at all kinds of hints
  4019. // or we can look at only subtree hints
  4020. if(IFSMgr_MetaMatch(lpFind32->cFileName, lpSC->lpuType, UFLG_NT|UFLG_META))
  4021. {
  4022. // The type matches with the hint
  4023. fHintMatch = TRUE;
  4024. }
  4025. }
  4026. if (fHintMatch)
  4027. {
  4028. if (mHintExclude(lpOI->ulHintFlags))
  4029. {
  4030. // Is this an exclusion hint, and the object has not
  4031. // been included by a previous hint at this level, set it
  4032. if (mHintExclude(ulHintFlagsThisLevel))
  4033. {
  4034. // Assert(lpOI->ulHintPri == 0);
  4035. // lpSC->ulHintPri = lpOI->ulHintPri;
  4036. lpSC->ulHintPri = 0;
  4037. ulHintFlagsThisLevel = lpSC->ulHintFlags = lpOI->ulHintFlags;
  4038. }
  4039. }
  4040. else
  4041. {
  4042. // Inclusion hint, override earlier excludes, or lower priority hints
  4043. if (mHintExclude(lpSC->ulHintFlags) ||
  4044. (lpSC->ulHintPri < lpOI->ulHintPri))
  4045. {
  4046. lpSC->ulHintPri = lpOI->ulHintPri;
  4047. ulHintFlagsThisLevel = lpSC->ulHintFlags = lpOI->ulHintFlags;
  4048. }
  4049. }
  4050. }
  4051. return (iRet);
  4052. }
  4053. int
  4054. FindCreateShare(
  4055. USHORT *lpShareName,
  4056. BOOL fCreate,
  4057. LPSHADOWINFO lpSI,
  4058. BOOL *lpfCreated
  4059. )
  4060. /*++
  4061. Routine Description:
  4062. Parameters:
  4063. Return Value:
  4064. Notes:
  4065. --*/
  4066. {
  4067. ULONG uShadowStatus, hShare;
  4068. BOOL fCreated = FALSE;
  4069. int iRet = SRET_ERROR;
  4070. Assert(vfInShadowCrit != 0);
  4071. if (!IsPathUNC(lpShareName, MAX_SERVER_SHARE_NAME_FOR_CSC))
  4072. {
  4073. CShadowKdPrint(ALWAYS,("FindCreateShare: Invalid share name %ws\r\n", lpShareName));
  4074. // Assert(FALSE);
  4075. return (iRet);
  4076. }
  4077. if (lpfCreated)
  4078. {
  4079. *lpfCreated = FALSE;
  4080. }
  4081. if (GetShareFromPath(lpShareName, lpSI) <= SRET_ERROR)
  4082. {
  4083. CShadowKdPrint(FINDCREATESHARE,("FindCreateShare: Error creating server\r\n"));
  4084. return SRET_ERROR;
  4085. }
  4086. if (lpSI->hShare)
  4087. {
  4088. iRet = SRET_OK;
  4089. }
  4090. else
  4091. {
  4092. if (fCreate)
  4093. {
  4094. if(hShare = HCreateShareObj(lpShareName, lpSI))
  4095. {
  4096. if (lpfCreated)
  4097. {
  4098. *lpfCreated = TRUE;
  4099. }
  4100. iRet = SRET_OK;
  4101. }
  4102. else
  4103. {
  4104. CShadowKdPrint(FINDCREATESHARE,("FindCreateShare: Couldn't create server object \r\n"));
  4105. }
  4106. }
  4107. }
  4108. return (iRet);
  4109. }
  4110. #ifdef CSC_RECORDMANAGER_WINNT
  4111. int FindCreateShareForNt(
  4112. PUNICODE_STRING lpShareName,
  4113. BOOL fCreate,
  4114. LPSHADOWINFO lpSI,
  4115. BOOL *lpfCreated
  4116. )
  4117. {
  4118. int iRet, lenName;
  4119. int ShareNameLengthInChars;
  4120. BOOL fIsLoopBack = FALSE;
  4121. Assert(vfInShadowCrit != 0);
  4122. ShareNameLengthInChars = lpShareName->Length / sizeof(WCHAR);
  4123. if ( ShareNameLengthInChars >= (sizeof(vsFRExt.sFR.rgwName)-1))
  4124. {
  4125. return SRET_ERROR;
  4126. }
  4127. UseGlobalFilerecExt();
  4128. // plug the extra slash.
  4129. vsFRExt.sFR.rgwName[0] = (USHORT)('\\');
  4130. // append the rest of the share name
  4131. memcpy(&(vsFRExt.sFR.rgwName[1]), lpShareName->Buffer, lpShareName->Length);
  4132. // put in a terminating NULL
  4133. vsFRExt.sFR.rgwName[ShareNameLengthInChars + 1] = 0;
  4134. if (MRxSmbCscIsLoopbackServer(vsFRExt.sFR.rgwName, &fIsLoopBack)==STATUS_SUCCESS) {
  4135. if (fIsLoopBack){
  4136. UnUseGlobalFilerecExt();
  4137. return SRET_ERROR;
  4138. }
  4139. }
  4140. iRet = FindCreateShare(vsFRExt.sFR.rgwName, fCreate, lpSI, lpfCreated);
  4141. UnUseGlobalFilerecExt();
  4142. return iRet;
  4143. }
  4144. #endif
  4145. int
  4146. CShadowFindFilerecFromInode(
  4147. LPVOID lpdbID,
  4148. HSHADOW hDir,
  4149. HSHADOW hShadow,
  4150. LPPRIQREC lpPQ,
  4151. LPFILERECEXT lpFRUse
  4152. )
  4153. /*++
  4154. Routine Description:
  4155. Parameters:
  4156. Return Value:
  4157. Notes:
  4158. --*/
  4159. {
  4160. int iRet = 0;
  4161. Assert(vfInShadowCrit != 0);
  4162. if(!FindFileRecFromInode(lpdbShadow, hDir, hShadow, lpPQ->ulrecDirEntry, lpFRUse))
  4163. {
  4164. SetCSCDatabaseErrorFlags(CSC_DATABASE_ERROR_MISSING_INODE);
  4165. SetLastErrorLocal(ERROR_FILE_NOT_FOUND);
  4166. CShadowKdPrint(ALWAYS,("ReadShadowInfo: !!! no filerec for pq entry Inode=%x\r\n",
  4167. hShadow));
  4168. // DeletePriQRecord(lpdbShadow, hDir, hShadow, lpPQ);
  4169. goto bailout;
  4170. }
  4171. if ((lpFRUse->sFR.ulidShadow != lpPQ->ulidShadow)||(lpFRUse->sFR.ulidShadow != hShadow))
  4172. {
  4173. CShadowKdPrint(ALWAYS,("ReadShadowInfo: !!! mismatched filerec for pq entry Inode=%x\r\n",
  4174. hShadow));
  4175. // try getting it the hard way.
  4176. if(!(lpPQ->ulrecDirEntry = FindFileRecFromInode(lpdbShadow, hDir, hShadow, INVALID_REC, lpFRUse)))
  4177. {
  4178. CShadowKdPrint(ALWAYS,("ReadShadowInfo: !!! no filerec for pq entry Inode=%x, deleting PQ entry\r\n",
  4179. hShadow));
  4180. // DeletePriQRecord(lpdbShadow, hDir, hShadow, lpPQ);
  4181. goto bailout;
  4182. }
  4183. else
  4184. {
  4185. // try updating this info.
  4186. // don't check for errors, if there is a problem we will fix it on the fly
  4187. // next time around
  4188. UpdatePriQRecord(lpdbShadow, hDir, hShadow, lpPQ);
  4189. }
  4190. }
  4191. iRet = lpPQ->ulrecDirEntry;
  4192. bailout:
  4193. return (iRet);
  4194. }
  4195. BOOL
  4196. CopySecurityContextToBuffer(
  4197. LPRECORDMANAGER_SECURITY_CONTEXT lpSecurityContext,
  4198. LPVOID lpSecurityBlob,
  4199. LPDWORD lpdwBlobSize
  4200. )
  4201. /*++
  4202. Routine Description:
  4203. Parameters:
  4204. Return Value:
  4205. Notes:
  4206. --*/
  4207. {
  4208. DWORD dwSizeCopied = 0;
  4209. if (lpdwBlobSize)
  4210. {
  4211. if (lpSecurityBlob)
  4212. {
  4213. dwSizeCopied = min(*lpdwBlobSize, sizeof(RECORDMANAGER_SECURITY_CONTEXT));
  4214. memcpy(lpSecurityBlob, lpSecurityContext, dwSizeCopied);
  4215. *lpdwBlobSize = dwSizeCopied;
  4216. }
  4217. else
  4218. {
  4219. // size needed
  4220. *lpdwBlobSize = sizeof(RECORDMANAGER_SECURITY_CONTEXT);
  4221. }
  4222. }
  4223. return ((lpSecurityBlob != NULL) && dwSizeCopied);
  4224. }
  4225. BOOL
  4226. CopyBufferToSecurityContext(
  4227. LPVOID lpSecurityBlob,
  4228. LPDWORD lpdwBlobSize,
  4229. LPRECORDMANAGER_SECURITY_CONTEXT lpSecurityContext
  4230. )
  4231. /*++
  4232. Routine Description:
  4233. Parameters:
  4234. Return Value:
  4235. Notes:
  4236. --*/
  4237. {
  4238. DWORD dwSizeCopied = 0;
  4239. if (lpdwBlobSize)
  4240. {
  4241. if (lpSecurityBlob)
  4242. {
  4243. dwSizeCopied = min(*lpdwBlobSize, sizeof(RECORDMANAGER_SECURITY_CONTEXT));
  4244. memcpy(lpSecurityContext, lpSecurityBlob, dwSizeCopied);
  4245. *lpdwBlobSize = dwSizeCopied;
  4246. }
  4247. else
  4248. {
  4249. // size copied
  4250. *lpdwBlobSize = 0;
  4251. }
  4252. }
  4253. // we have done some copying
  4254. return ((lpSecurityBlob != NULL) && dwSizeCopied);
  4255. }
  4256. int PathFromHShadow(
  4257. HSHADOW hDir,
  4258. HSHADOW hShadow,
  4259. USHORT *lpBuff,
  4260. int cBuff // # of WCHAR characters that lpBuff can fit
  4261. )
  4262. /*++
  4263. Routine Description:
  4264. Parameters:
  4265. Return Value:
  4266. Notes:
  4267. --*/
  4268. {
  4269. int cCount, cRemain, iRet=-1;
  4270. LPFIND32 lpFind32;
  4271. ULONG uShadowStatus;
  4272. HSHADOW hTmp;
  4273. Assert(vfInShadowCrit != 0);
  4274. Assert(cBuff > 1);
  4275. if (!(lpFind32 = (LPFIND32)AllocMem(sizeof(WIN32_FIND_DATA))))
  4276. {
  4277. KdPrint(("PathFromHSHADOW:Error Allocating memory\r\n"));
  4278. goto bailout;
  4279. }
  4280. memset(lpBuff, 0, cBuff * sizeof(USHORT));
  4281. cRemain = cBuff-1;
  4282. // special case the root
  4283. if (!hDir)
  4284. {
  4285. lpBuff[--cRemain] = (USHORT)('\\');
  4286. }
  4287. else
  4288. {
  4289. do
  4290. {
  4291. // If we are not dealing with the root
  4292. if (hDir)
  4293. {
  4294. if(GetShadowInfo(hDir, hShadow, lpFind32, &uShadowStatus, NULL) < SRET_OK)
  4295. goto bailout;
  4296. // Count of characters
  4297. cCount = wstrlen(lpFind32->cFileName);
  4298. // We need count+1 for prepending a backslash
  4299. if (cCount >= cRemain)
  4300. goto bailout;
  4301. // Save the ending byte which may be destroyed by UniToBCS
  4302. // Convert
  4303. // UniToBCS(lpBuff+cRemain-cCount, lpFind32->cFileName, sizeof(lpFind32->cFileName), cCount, BCS_WANSI);
  4304. memcpy(lpBuff+cRemain-cCount, lpFind32->cFileName, cCount * sizeof(USHORT));
  4305. cRemain -= cCount;
  4306. }
  4307. lpBuff[--cRemain] = (USHORT)('\\');
  4308. if(GetAncestorsHSHADOW(hDir, &hTmp, NULL) < SRET_OK)
  4309. goto bailout;
  4310. hShadow = hDir;
  4311. hDir = hTmp;
  4312. }
  4313. while (hDir);
  4314. }
  4315. // !!ACHTUNG!! this should work because the overlap is in the right way
  4316. iRet = cBuff-cRemain;
  4317. memcpy(lpBuff, lpBuff+cRemain, iRet * sizeof(USHORT));
  4318. bailout:
  4319. if (lpFind32)
  4320. FreeMem(lpFind32);
  4321. return (iRet);
  4322. }
  4323. int
  4324. GetSecurityInfosFromBlob(
  4325. LPVOID lpvBlob,
  4326. DWORD dwBlobSize,
  4327. LPSECURITYINFO lpSecInfo,
  4328. DWORD *lpdwBytes
  4329. )
  4330. /*++
  4331. Routine Description:
  4332. Given security blob, this routine returns the information in form of an array of
  4333. SECURITYINFO structures.
  4334. Arguments:
  4335. lpvBlob blob buffer that is obtained from GetShadowEx or GetShadowInfoEx
  4336. dwBlobSize blob buffer size obtained from GetShadowEx or GetShadowInfoEx
  4337. lpSecInfo Array of SECURITYINFO strucutres where to output the info
  4338. lpdwBytes
  4339. Return Value:
  4340. ERROR_SUCCESS if successful, otherwise appropriate error
  4341. --*/
  4342. {
  4343. PACCESS_RIGHTS pAccessRights = (PACCESS_RIGHTS)lpvBlob;
  4344. DWORD i, cnt;
  4345. cnt = *lpdwBytes/sizeof(ACCESS_RIGHTS);
  4346. cnt = min(cnt, CSC_MAXIMUM_NUMBER_OF_CACHED_SID_INDEXES);
  4347. if (!lpSecInfo)
  4348. {
  4349. *lpdwBytes = CSC_MAXIMUM_NUMBER_OF_CACHED_SID_INDEXES * sizeof(ACCESS_RIGHTS);
  4350. return 0;
  4351. }
  4352. for (i=0; i<cnt; ++i)
  4353. {
  4354. (lpSecInfo+i)->ulPrincipalID = (pAccessRights + i)->SidIndex;
  4355. (lpSecInfo+i)->ulPermissions = (pAccessRights + i)->MaximalRights;
  4356. }
  4357. return TRUE;
  4358. }
  4359. int
  4360. GetDatabaseLocation(
  4361. LPSTR lpszBuff
  4362. )
  4363. /*++
  4364. Routine Description:
  4365. Returns the current location of the database in ANSI string.
  4366. Arguments:
  4367. lpszBuff buffer, must be MAX_PATH
  4368. Return Value:
  4369. returns SRET_OK if successfull else returns SRET_ERROR
  4370. --*/
  4371. {
  4372. return(QueryRecDB(lpszBuff, NULL, NULL, NULL, NULL) >= SRET_OK);
  4373. }
  4374. #if 0
  4375. int PUBLIC CopyFile(
  4376. LPPATH lpSrc,
  4377. ULONG ulidDir,
  4378. ULONG ulidNew
  4379. )
  4380. {
  4381. LPSTR lpszName = NULL;
  4382. int iRet=-1;
  4383. HFREMOTE hfSrc= (HFREMOTE)NULL;
  4384. CSCHFILE hfDst= NULL;
  4385. ULONG pos;
  4386. LPVOID lpBuff=NULL;
  4387. if (OpenFileRemoteEx(lpSrc, ACCESS_READONLY, ACTION_OPENEXISTING, 0, &hfSrc))
  4388. {
  4389. CShadowKdPrint(BADERRORS,("CopyFile: Can't open remote file\r\n"));
  4390. goto bailout;
  4391. }
  4392. if (!(lpBuff = AllocMem(COPY_BUFF_SIZE)))
  4393. {
  4394. goto bailout;
  4395. }
  4396. lpszName = AllocMem(MAX_PATH);
  4397. if (!lpszName)
  4398. {
  4399. goto bailout;
  4400. }
  4401. if(GetLocalNameHSHADOW(ulidNew, lpszName, MAX_PATH, FALSE)!=SRET_OK)
  4402. {
  4403. goto bailout;
  4404. }
  4405. // If the original file existed it would be truncated
  4406. if ( !(hfDst = R0OpenFile(ACCESS_READWRITE, ACTION_CREATEALWAYS, lpszName)))
  4407. {
  4408. CShadowKdPrint(BADERRORS,("CopyFile: Can't create %s\r\n", lpszName));
  4409. goto bailout;
  4410. }
  4411. CShadowKdPrint(COPYFILE,("Copying...\r\n"));
  4412. pos = 0;
  4413. // Both the files are correctly positioned
  4414. while ((iRet = ReadFileRemote(hfSrc, LpIoreqFromFileInfo(hfSrc)
  4415. , pos, lpBuff, COPY_BUFF_SIZE))>0)
  4416. {
  4417. if (WriteFileLocal(hfDst, pos, lpBuff, iRet) < 0)
  4418. {
  4419. CShadowKdPrint(BADERRORS,("CopyFile: Write Error\r\n"));
  4420. goto bailout;
  4421. }
  4422. pos += iRet;
  4423. }
  4424. CShadowKdPrint(COPYFILE,("Copy Complete\r\n"));
  4425. iRet = 1;
  4426. bailout:
  4427. if (hfSrc)
  4428. CloseFileRemote(hfSrc, NULL);
  4429. if (hfDst)
  4430. CloseFileLocal(hfDst);
  4431. if (lpBuff)
  4432. FreeMem(lpBuff);
  4433. if ((iRet==-1) && hfDst)
  4434. {
  4435. DeleteFileLocal(lpszName, ATTRIB_DEL_ANY);
  4436. }
  4437. if (lpszName)
  4438. {
  4439. FreeMem(lpszName);
  4440. }
  4441. return iRet;
  4442. }
  4443. #endif
  4444. #ifdef DEBUG
  4445. int
  4446. ValidatePri(
  4447. LPFILERECEXT lpFR
  4448. )
  4449. {
  4450. if (!(lpFR->sFR.dwFileAttrib & FILE_ATTRIBUTE_DIRECTORY))
  4451. {
  4452. if((lpFR->sFR.uchRefPri != MAX_PRI))
  4453. {
  4454. CShadowKdPrint(ALWAYS,("Bad refpri %x %ws\r\n",
  4455. lpFR->sFR.uchRefPri,
  4456. lpFR->sFR.rgw83Name));
  4457. return 0;
  4458. }
  4459. }
  4460. else
  4461. {
  4462. if((lpFR->sFR.uchRefPri != MIN_PRI))
  4463. {
  4464. CShadowKdPrint(ALWAYS,("Bad refpri %x %ws\r\n",
  4465. lpFR->sFR.uchRefPri,
  4466. lpFR->sFR.rgw83Name));
  4467. return 0;
  4468. }
  4469. }
  4470. return 1;
  4471. }
  4472. #endif
  4473. int
  4474. GetHShareFromUNCString(
  4475. USHORT *lpServer,
  4476. int cbServer,
  4477. int lenSkip,
  4478. BOOL fIsShareName,
  4479. HSHARE *lphShare,
  4480. ULONG *lpulHintFlags
  4481. )
  4482. /*++
  4483. Routine Description:
  4484. Arguments:
  4485. Return Value:
  4486. This is the ONLY routine that is called from rdr2 code that expects the ciritcal section not to be held
  4487. because of deadlock with FAT during paging writes, if the net goes down.
  4488. See comments in rdr2\rdbss\smb.mrx\csc.nt5\transitn.c
  4489. --*/
  4490. {
  4491. int iRet = -1, i;
  4492. GENERICHEADER sGH;
  4493. CSCHFILE hf = NULL;
  4494. ULONG ulRec;
  4495. SHAREREC sSR;
  4496. BOOL fCached;
  4497. USHORT uchDelimiter=(USHORT)'\\';
  4498. *lphShare = 0;
  4499. *lpulHintFlags = 0;
  4500. if ((cbServer/sizeof(USHORT)+lenSkip)>= (sizeof(sSR.rgPath)/sizeof(USHORT)))
  4501. {
  4502. return iRet;
  4503. }
  4504. if (fIsShareName)
  4505. {
  4506. uchDelimiter = 0;
  4507. }
  4508. if (!(hf = OpenInodeFileAndCacheHandle(lpdbShadow, ULID_SHARE, ACCESS_READWRITE, &fCached)))
  4509. {
  4510. goto bailout;
  4511. }
  4512. if(ReadHeader(hf, &sGH, sizeof(FILEHEADER)) < 0)
  4513. {
  4514. goto bailout;
  4515. }
  4516. for (ulRec=1; ulRec<=sGH.ulRecords; ulRec++)
  4517. {
  4518. if(ReadRecord(hf, &sGH, ulRec, (LPGENERICREC)&sSR) < 0)
  4519. {
  4520. goto bailout;
  4521. }
  4522. if (sSR.uchType != REC_DATA)
  4523. {
  4524. continue;
  4525. }
  4526. // 0 return means it matched
  4527. if(!wstrnicmp(lpServer, sSR.rgPath + lenSkip, cbServer))
  4528. {
  4529. Assert(sSR.ulShare);
  4530. if (sSR.rgPath[lenSkip+cbServer/sizeof(USHORT)] == uchDelimiter)
  4531. {
  4532. *lphShare = sSR.ulShare;
  4533. *lpulHintFlags = (ULONG)(sSR.uchHintFlags);
  4534. iRet = SRET_OK;
  4535. break;
  4536. }
  4537. }
  4538. }
  4539. iRet = SRET_OK;
  4540. bailout:
  4541. if (hf && !fCached)
  4542. {
  4543. Assert(vfStopHandleCaching);
  4544. CloseFileLocal(hf);
  4545. }
  4546. else
  4547. {
  4548. Assert(!hf || !vfStopHandleCaching);
  4549. }
  4550. return (iRet);
  4551. }
  4552. BOOL
  4553. EnableHandleCaching(
  4554. BOOL fEnable
  4555. )
  4556. /*++
  4557. Routine Description:
  4558. Arguments:
  4559. Return Value:
  4560. returns previous handlecaching value
  4561. --*/
  4562. {
  4563. BOOL fT, fT1;
  4564. Assert(vfInShadowCrit != 0);
  4565. fT = EnableHandleCachingSidFile(fEnable);
  4566. fT1 = EnableHandleCachingInodeFile(fEnable);
  4567. Assert(fT == fT1);
  4568. return (fT1);
  4569. }
  4570. int
  4571. RecreateHSHADOW(
  4572. HSHADOW hDir,
  4573. HSHADOW hShadow,
  4574. ULONG ulAttrib
  4575. )
  4576. /*++
  4577. Routine Description:
  4578. This routine recreates an inode data file. This is so that when the CSC directory is
  4579. marked for encryption/decryption, the newly created inode file will get encrypted.
  4580. Arguments:
  4581. hDir Inode directory
  4582. hShadow Inode whose file needs to be recreated
  4583. ulAttrib recreate with given attributes
  4584. Return Value:
  4585. --*/
  4586. {
  4587. return (RecreateInode(lpdbShadow, hShadow, ulAttrib));
  4588. }
  4589. VOID
  4590. AdjustSparseStaleDetectionCount(
  4591. ULONG hShare,
  4592. LPFILERECEXT lpFRUse
  4593. )
  4594. /*++
  4595. Routine Description:
  4596. This routine deals with a monotonically increasing (that is untill it wraps around), counter
  4597. that is essentially a tick count that indicates when was the last time the cshadow interface
  4598. created/set a sparse or a stale file.
  4599. This is used by the agent to decide whether to enumerate the priority Q or not.
  4600. Added code to also check if we're creating a file on a manually-cached share, and
  4601. if so then to start the agent so it will clean this file up later.
  4602. Arguments:
  4603. lpFRUse record for the file/dir
  4604. Return Value:
  4605. None
  4606. --*/
  4607. {
  4608. ULONG cStatus;
  4609. SHAREREC sSR = {0};
  4610. LONG iRet = SRET_ERROR;
  4611. // DbgPrint("AdjustSparseStaleDetectionCount(hShare=0x%x)\n", hShare);
  4612. //
  4613. // if this is a file and is stale or sparse
  4614. //
  4615. if (IsFile(lpFRUse->sFR.dwFileAttrib) &&
  4616. (lpFRUse->sFR.uStatus & (SHADOW_STALE|SHADOW_SPARSE))) {
  4617. ++vdwSparseStaleDetecionCount;
  4618. // DbgPrint("####Pulsing agent #2 (1)\n");
  4619. MRxSmbCscSignalFillAgent(NULL, 0);
  4620. goto AllDone;
  4621. }
  4622. if (hShare != 0) {
  4623. //
  4624. // If we're creating a file on a manually-cached share, let the agent know
  4625. //
  4626. if (IsFile(lpFRUse->sFR.dwFileAttrib)) {
  4627. iRet = GetShareRecord(lpdbShadow, hShare, &sSR);
  4628. if (iRet < SRET_OK) {
  4629. // DbgPrint("AdjustSparseStaleDetectionCount exit (1) iRet = %d\n", iRet);
  4630. goto AllDone;
  4631. }
  4632. }
  4633. cStatus = sSR.uStatus & FLAG_CSC_SHARE_STATUS_CACHING_MASK;
  4634. // DbgPrint("AdjustSparseStaleDetectionCount cStatus=0x%x\n", cStatus);
  4635. if (cStatus == FLAG_CSC_SHARE_STATUS_MANUAL_REINT) {
  4636. ++vdwManualFileDetectionCount;
  4637. // DbgPrint("####Pulsing agent #2 (2)\n");
  4638. MRxSmbCscSignalFillAgent(NULL, 0);
  4639. }
  4640. }
  4641. AllDone:
  4642. return;
  4643. }
  4644. VOID
  4645. QuerySparseStaleDetectionCount(
  4646. LPDWORD lpcnt
  4647. )
  4648. /*++
  4649. Routine Description:
  4650. Arguments:
  4651. lpcnt for returning the count
  4652. Return Value:
  4653. None
  4654. --*/
  4655. {
  4656. *lpcnt = vdwSparseStaleDetecionCount;
  4657. }
  4658. VOID
  4659. QueryManualFileDetectionCount(
  4660. LPDWORD lpcnt
  4661. )
  4662. /*++
  4663. Routine Description:
  4664. Arguments:
  4665. lpcnt for returning the count
  4666. Return Value:
  4667. None
  4668. --*/
  4669. {
  4670. *lpcnt = vdwManualFileDetectionCount;
  4671. }
  4672. ULONG
  4673. QueryDatabaseErrorFlags(
  4674. VOID
  4675. )
  4676. /*++
  4677. Routine Description:
  4678. Arguments:
  4679. Return Value:
  4680. None
  4681. --*/
  4682. {
  4683. return GetCSCDatabaseErrorFlags();
  4684. }
  4685. int
  4686. HasDescendentsHShadow(
  4687. HSHADOW hDir,
  4688. HSHADOW hShadow,
  4689. BOOLEAN *lpfDescendents
  4690. )
  4691. /*++
  4692. Routine Description:
  4693. Arguments:
  4694. Return Value:
  4695. None
  4696. --*/
  4697. {
  4698. *lpfDescendents = (!FInodeIsFile(lpdbShadow, hDir, hShadow) &&
  4699. HasDescendents(lpdbShadow, 0, hShadow));
  4700. return 0;
  4701. }
  4702. int PUBLIC AddStoreData(
  4703. LPTSTR lpdbID,
  4704. LPSTOREDATA lpSD
  4705. )
  4706. /*++
  4707. Routine Description:
  4708. Adds space and file/dir count to the database. This is used for purging
  4709. unpinned data.
  4710. Parameters:
  4711. Return Value:
  4712. Notes:
  4713. --*/
  4714. {
  4715. CSCHFILE hf;
  4716. SHAREHEADER sSH;
  4717. int iRet = -1;
  4718. BOOL fCached;
  4719. hf = OpenInodeFileAndCacheHandle(lpdbID, ULID_SHARE, ACCESS_READWRITE, &fCached);
  4720. if (!hf)
  4721. {
  4722. return -1;
  4723. }
  4724. if (lpSD->ulSize)
  4725. {
  4726. // RecordKdPrint(STOREDATA,("Adding %ld \r\n", lpSD->ulSize));
  4727. }
  4728. if ((iRet = ReadHeader(hf, (LPVOID)&sSH, sizeof(SHAREHEADER)))> 0)
  4729. {
  4730. if (lpSD->ulSize)
  4731. {
  4732. // RecordKdPrint(STOREDATA,("AddStoreData Before: %ld \r\n", sSH.sCur.ulSize));
  4733. }
  4734. sSH.sCur.ulSize += lpSD->ulSize;
  4735. sSH.sCur.ucntDirs += lpSD->ucntDirs;
  4736. sSH.sCur.ucntFiles += lpSD->ucntFiles;
  4737. // ensure that the data is always in clustersizes
  4738. Assert(!(lpSD->ulSize%(vdwClusterSizeMinusOne+1)));
  4739. if ((iRet = WriteHeader(hf, (LPVOID)&sSH, sizeof(SHAREHEADER))) < 0)
  4740. Assert(FALSE);
  4741. if (lpSD->ulSize)
  4742. {
  4743. // RecordKdPrint(STOREDATA,("AddStoreData After: %ld \r\n", sSH.sCur.ulSize));
  4744. }
  4745. //
  4746. // If we are at the full cache size, kick the agent so he'll
  4747. // free up some space.
  4748. //
  4749. if (sSH.sCur.ulSize > sSH.sMax.ulSize) {
  4750. // DbgPrint("Full cache, notifying agent...\n");
  4751. CscNotifyAgentOfFullCacheIfRequired();
  4752. }
  4753. }
  4754. if (hf && !fCached)
  4755. {
  4756. Assert(vfStopHandleCaching);
  4757. CloseFileLocal(hf);
  4758. }
  4759. else
  4760. {
  4761. Assert(!hf || !vfStopHandleCaching);
  4762. }
  4763. return iRet;
  4764. }
  4765. int PUBLIC SubtractStoreData(
  4766. LPTSTR lpdbID,
  4767. LPSTOREDATA lpSD
  4768. )
  4769. /*++
  4770. Routine Description:
  4771. Parameters:
  4772. Return Value:
  4773. Notes:
  4774. --*/
  4775. {
  4776. CSCHFILE hf;
  4777. SHAREHEADER sSH;
  4778. int iRet = -1;
  4779. BOOL fCached;
  4780. hf = OpenInodeFileAndCacheHandle(lpdbID, ULID_SHARE, ACCESS_READWRITE, &fCached);
  4781. if (!hf)
  4782. {
  4783. return -1;
  4784. }
  4785. if (lpSD->ulSize)
  4786. {
  4787. // RecordKdPrint(STOREDATA,("Subtracting %ld \r\n", lpSD->ulSize));
  4788. }
  4789. if ((iRet = ReadHeader(hf, (LPVOID)&sSH, sizeof(SHAREHEADER)))> 0)
  4790. {
  4791. // RecordKdPrint(STOREDATA,("SubtractStoreData Before: %ld \r\n", sSH.sCur.ulSize));
  4792. if (sSH.sCur.ulSize >lpSD->ulSize)
  4793. {
  4794. sSH.sCur.ulSize -= lpSD->ulSize;
  4795. }
  4796. else
  4797. {
  4798. sSH.sCur.ulSize = 0;
  4799. }
  4800. if (sSH.sCur.ucntDirs > lpSD->ucntDirs)
  4801. {
  4802. sSH.sCur.ucntDirs -= lpSD->ucntDirs;
  4803. }
  4804. else
  4805. {
  4806. sSH.sCur.ucntDirs = 0;
  4807. }
  4808. if (sSH.sCur.ucntFiles > lpSD->ucntFiles)
  4809. {
  4810. sSH.sCur.ucntFiles -= lpSD->ucntFiles;
  4811. }
  4812. else
  4813. {
  4814. sSH.sCur.ucntFiles = 0;
  4815. }
  4816. // ensure that the data is always in clustersizes
  4817. Assert(!(lpSD->ulSize%(vdwClusterSizeMinusOne+1)));
  4818. if ((iRet = WriteHeader(hf, (LPVOID)&sSH, sizeof(SHAREHEADER)))<0)
  4819. Assert(FALSE);
  4820. // RecordKdPrint(STOREDATA,("SubtractStoreData After: %ld \r\n", sSH.sCur.ulSize));
  4821. }
  4822. if (hf && !fCached)
  4823. {
  4824. Assert(vfStopHandleCaching);
  4825. CloseFileLocal(hf);
  4826. }
  4827. else
  4828. {
  4829. Assert(!hf || !vfStopHandleCaching);
  4830. }
  4831. return iRet;
  4832. }