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.

1575 lines
43 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. infocach.c
  5. Abstract:
  6. This module implements the name cache for file basic and standard information.
  7. Author:
  8. Yun Lin [YunLin] 13-Feburary-2001
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #include "webdav.h"
  14. #ifdef ALLOC_PRAGMA
  15. #pragma alloc_text(PAGE, MRxDAVCacheFileNotFound)
  16. #pragma alloc_text(PAGE, MRxDAVCacheFileNotFoundWithName)
  17. #pragma alloc_text(PAGE, MRxDAVIsFileNotFoundCached)
  18. #pragma alloc_text(PAGE, MRxDAVIsFileNotFoundCachedWithName)
  19. #pragma alloc_text(PAGE, MRxDAVCreateFileInfoCache)
  20. #pragma alloc_text(PAGE, MRxDAVCreateFileInfoCacheWithName)
  21. #pragma alloc_text(PAGE, MRxDAVIsFileInfoCacheFound)
  22. #pragma alloc_text(PAGE, MRxDAVInvalidateFileInfoCache)
  23. #pragma alloc_text(PAGE, MRxDAVInvalidateFileInfoCacheWithName)
  24. #pragma alloc_text(PAGE, MRxDAVUpdateBasicFileInfoCache)
  25. #pragma alloc_text(PAGE, MRxDAVCreateBasicFileInfoCache)
  26. #pragma alloc_text(PAGE, MRxDAVCreateBasicFileInfoCacheWithName)
  27. #pragma alloc_text(PAGE, MRxDAVUpdateFileInfoCacheStatus)
  28. #pragma alloc_text(PAGE, MRxDAVCreateStandardFileInfoCache)
  29. #pragma alloc_text(PAGE, MRxDAVCreateStandardFileInfoCacheWithName)
  30. #pragma alloc_text(PAGE, MRxDAVUpdateFileInfoCacheFileSize)
  31. #pragma alloc_text(PAGE, MRxDAVUpdateStandardFileInfoCache)
  32. #pragma alloc_text(PAGE, MRxDAVInvalidateFileNotFoundCache)
  33. #pragma alloc_text(PAGE, MRxDAVUpdateBasicFileInfoCacheAll)
  34. #pragma alloc_text(PAGE, MRxDAVInvalidateBasicFileInfoCache)
  35. #pragma alloc_text(PAGE, MRxDAVInvalidateBasicFileInfoCacheWithName)
  36. #pragma alloc_text(PAGE, MRxDAVUpdateBasicFileInfoCacheStatus)
  37. #pragma alloc_text(PAGE, MRxDAVInvalidateStandardFileInfoCache)
  38. #pragma alloc_text(PAGE, MRxDAVInvalidateStandardFileInfoCacheWithName)
  39. #pragma alloc_text(PAGE, MRxDAVUpdateStandardFileInfoCacheStatus)
  40. #endif
  41. extern FAST_MUTEX MRxDAVFileInfoCacheLock;
  42. MRX_DAV_STATISTICS MRxDAVStatistics;
  43. VOID
  44. MRxDAVCreateFileInfoCache(
  45. PRX_CONTEXT RxContext,
  46. PDAV_USERMODE_CREATE_RETURNED_FILEINFO FileInfo,
  47. NTSTATUS Status
  48. )
  49. /*++
  50. Routine Description:
  51. This routine creates name cache entry for both file basic and standard information.
  52. Arguments:
  53. RxContext - the RDBSS context
  54. FileInfo - the file information package including basic and standard information
  55. Status - the status returned from server response of query file information
  56. Return Value:
  57. none
  58. --*/
  59. {
  60. PAGED_CODE();
  61. MRxDAVCreateBasicFileInfoCache(RxContext,&FileInfo->BasicInformation,Status);
  62. MRxDAVCreateStandardFileInfoCache(RxContext,&FileInfo->StandardInformation,Status);
  63. DavDbgTrace(DAV_TRACE_INFOCACHE,
  64. ("MRxDAVCreateFileInfoCache %wZ\n",GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext)));
  65. }
  66. VOID
  67. MRxDAVCreateFileInfoCacheWithName(
  68. PUNICODE_STRING FileName,
  69. PMRX_NET_ROOT NetRoot,
  70. PFILE_BASIC_INFORMATION Basic,
  71. PFILE_STANDARD_INFORMATION Standard,
  72. NTSTATUS Status
  73. )
  74. /*++
  75. Routine Description:
  76. This routine creates name cache entry for both file basic and standard information.
  77. Arguments:
  78. RxContext - the RDBSS context
  79. FileInfo - the file information package including basic and standard information
  80. Status - the status returned from server response of query file information
  81. Return Value:
  82. none
  83. --*/
  84. {
  85. PAGED_CODE();
  86. MRxDAVCreateBasicFileInfoCacheWithName(FileName,NetRoot,Basic,Status);
  87. MRxDAVCreateStandardFileInfoCacheWithName(FileName,NetRoot,Standard,Status);
  88. DavDbgTrace(DAV_TRACE_INFOCACHE,
  89. ("MRxDAVCreateFileInfoCacheWithName %wZ\n",FileName));
  90. }
  91. VOID
  92. MRxDAVCreateBasicFileInfoCache(
  93. PRX_CONTEXT RxContext,
  94. PFILE_BASIC_INFORMATION Basic,
  95. NTSTATUS Status
  96. )
  97. /*++
  98. Routine Description:
  99. This routine creates name cache entry for the file basic information.
  100. Arguments:
  101. RxContext - the RDBSS context
  102. Basic - the file basic information package
  103. Status - the status returned from server response of query file information
  104. Return Value:
  105. none
  106. --*/
  107. {
  108. RxCaptureFcb;
  109. PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
  110. PMRX_NET_ROOT NetRoot;
  111. PAGED_CODE();
  112. if (RxContext->MajorFunction == IRP_MJ_CREATE) {
  113. NetRoot = RxContext->Create.pNetRoot;
  114. } else {
  115. ASSERT(capFcb != NULL);
  116. NetRoot = capFcb->pNetRoot;
  117. }
  118. MRxDAVCreateBasicFileInfoCacheWithName(OriginalFileName,NetRoot,Basic,Status);
  119. }
  120. VOID
  121. MRxDAVCreateBasicFileInfoCacheWithName(
  122. PUNICODE_STRING OriginalFileName,
  123. PMRX_NET_ROOT NetRoot,
  124. PFILE_BASIC_INFORMATION Basic,
  125. NTSTATUS Status
  126. )
  127. /*++
  128. Routine Description:
  129. This routine creates name cache entry for the file basic information.
  130. Arguments:
  131. OriginalFileName - the name of the file to cache the basic information
  132. NetRoot - the Net Root that the file belongs to
  133. Basic - the file basic information package
  134. Status - the status returned from server response of query file information
  135. Return Value:
  136. none
  137. --*/
  138. {
  139. PNAME_CACHE NameCache = NULL;
  140. PWEBDAV_NET_ROOT DavNetRoot;
  141. PNAME_CACHE_CONTROL NameCacheCtl;
  142. PFILE_BASIC_INFORMATION FileInfoCache = NULL;
  143. PAGED_CODE();
  144. DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context;
  145. NameCacheCtl = &DavNetRoot->NameCacheCtlGFABasic;
  146. ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
  147. NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
  148. if (NameCache == NULL) {
  149. NameCache = RxNameCacheCreateEntry (
  150. NameCacheCtl,
  151. OriginalFileName,
  152. TRUE); // case insensitive match
  153. }
  154. if (NameCache != NULL) {
  155. FileInfoCache = (PFILE_BASIC_INFORMATION)NameCache->ContextExtension;
  156. *FileInfoCache = *Basic;
  157. NameCache->PriorStatus = Status;
  158. if (FileInfoCache->FileAttributes & ~FILE_ATTRIBUTE_NORMAL) {
  159. FileInfoCache->FileAttributes &= ~FILE_ATTRIBUTE_NORMAL;
  160. }
  161. RxNameCacheActivateEntry(
  162. NameCacheCtl,
  163. NameCache,
  164. FileInformationCacheLifeTimeInSec,
  165. MRxDAVStatistics.SmbsReceived.LowPart);
  166. DavDbgTrace(DAV_TRACE_INFOCACHE,
  167. (" Create File Attrib cache : %x %wZ\n",Basic->FileAttributes,OriginalFileName));
  168. DavDbgTrace(DAV_TRACE_INFOCACHE,
  169. (" Create File Attrib cache : %I64X %I64X %wZ\n",Basic->CreationTime,Basic->LastAccessTime,OriginalFileName));
  170. }
  171. ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
  172. }
  173. VOID
  174. MRxDAVCreateStandardFileInfoCache(
  175. PRX_CONTEXT RxContext,
  176. PFILE_STANDARD_INFORMATION Standard,
  177. NTSTATUS Status
  178. )
  179. /*++
  180. Routine Description:
  181. This routine creates name cache entry for the file standard information.
  182. Arguments:
  183. RxContext - the RDBSS context
  184. Standard - the file standard information package
  185. Status - the status returned from server response of query file information
  186. Return Value:
  187. none
  188. --*/
  189. {
  190. RxCaptureFcb;
  191. PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
  192. PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
  193. PAGED_CODE();
  194. MRxDAVCreateStandardFileInfoCacheWithName(OriginalFileName,NetRoot,Standard,Status);
  195. }
  196. VOID
  197. MRxDAVCreateStandardFileInfoCacheWithName(
  198. PUNICODE_STRING OriginalFileName,
  199. PMRX_NET_ROOT NetRoot,
  200. PFILE_STANDARD_INFORMATION Standard,
  201. NTSTATUS Status
  202. )
  203. /*++
  204. Routine Description:
  205. This routine creates name cache entry for the file standard information.
  206. Arguments:
  207. RxContext - the RDBSS context
  208. Standard - the file standard information package
  209. Status - the status returned from server response of query file information
  210. Return Value:
  211. none
  212. --*/
  213. {
  214. PNAME_CACHE NameCache = NULL;
  215. PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context;
  216. PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFAStandard;
  217. PFILE_STANDARD_INFORMATION FileInfoCache = NULL;
  218. PAGED_CODE();
  219. ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
  220. NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
  221. if (NameCache == NULL) {
  222. NameCache = RxNameCacheCreateEntry (
  223. NameCacheCtl,
  224. OriginalFileName,
  225. TRUE); // case insensitive match
  226. }
  227. if (NameCache != NULL) {
  228. FileInfoCache = (PFILE_STANDARD_INFORMATION)NameCache->ContextExtension;
  229. *FileInfoCache = *Standard;
  230. NameCache->PriorStatus = Status;
  231. RxNameCacheActivateEntry(
  232. NameCacheCtl,
  233. NameCache,
  234. FileInformationCacheLifeTimeInSec,
  235. MRxDAVStatistics.SmbsReceived.LowPart);
  236. DavDbgTrace(DAV_TRACE_INFOCACHE,
  237. (" Create Standard cache : %I64x %I64x %I64x %wZ\n",
  238. ((PFILE_STANDARD_INFORMATION)NameCache->ContextExtension)->EndOfFile,
  239. Standard->AllocationSize,
  240. Standard->EndOfFile,
  241. OriginalFileName));
  242. }
  243. ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
  244. }
  245. VOID
  246. MRxDAVUpdateFileInfoCacheFromDelete(
  247. PRX_CONTEXT RxContext
  248. )
  249. /*++
  250. Routine Description:
  251. This routine updates the status of the name cache entry as STATUS_OBJECT_NAME_NOT_FOUND
  252. for both file basic and standard information.
  253. Arguments:
  254. RxContext - the RDBSS context
  255. Return Value:
  256. none
  257. --*/
  258. {
  259. MRxDAVUpdateBasicFileInfoCacheStatus(RxContext,STATUS_OBJECT_NAME_NOT_FOUND);
  260. MRxDAVUpdateStandardFileInfoCacheStatus(RxContext,STATUS_OBJECT_NAME_NOT_FOUND);
  261. }
  262. VOID
  263. MRxDAVUpdateFileInfoCacheStatus(
  264. PRX_CONTEXT RxContext,
  265. NTSTATUS Status
  266. )
  267. /*++
  268. Routine Description:
  269. This routine updates the status of the name cache entry for both file basic and standard information.
  270. Arguments:
  271. RxContext - the RDBSS context
  272. Status - the status needs to be put on the cache
  273. Return Value:
  274. none
  275. --*/
  276. {
  277. MRxDAVUpdateBasicFileInfoCacheStatus(RxContext,Status);
  278. MRxDAVUpdateStandardFileInfoCacheStatus(RxContext,Status);
  279. }
  280. VOID
  281. MRxDAVUpdateBasicFileInfoCacheStatus(
  282. PRX_CONTEXT RxContext,
  283. NTSTATUS Status
  284. )
  285. /*++
  286. Routine Description:
  287. This routine updates the status of the name cache entry for the file basic information.
  288. Arguments:
  289. RxContext - the RDBSS context
  290. Status - the status needs to be put on the cache
  291. Return Value:
  292. none
  293. --*/
  294. {
  295. RxCaptureFcb;
  296. PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
  297. PNAME_CACHE NameCache = NULL;
  298. PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
  299. PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context;
  300. PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFABasic;
  301. PAGED_CODE();
  302. ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
  303. NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
  304. if (NameCache != NULL) {
  305. NameCache->PriorStatus = Status;
  306. RxNameCacheActivateEntry(NameCacheCtl,
  307. NameCache,
  308. 0,
  309. 0);
  310. DavDbgTrace(DAV_TRACE_INFOCACHE,
  311. ("Update status basic : %x %wZ\n",Status,OriginalFileName));
  312. }
  313. ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
  314. }
  315. VOID
  316. MRxDAVUpdateStandardFileInfoCacheStatus(
  317. PRX_CONTEXT RxContext,
  318. NTSTATUS Status
  319. )
  320. /*++
  321. Routine Description:
  322. This routine updates the status of the name cache entry for the file standard information.
  323. Arguments:
  324. RxContext - the RDBSS context
  325. Status - the status needs to be put on the cache
  326. Return Value:
  327. none
  328. --*/
  329. {
  330. RxCaptureFcb;
  331. PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
  332. PNAME_CACHE NameCache = NULL;
  333. PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
  334. PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context;
  335. PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFAStandard;
  336. PAGED_CODE();
  337. ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
  338. NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
  339. if (NameCache != NULL) {
  340. NameCache->PriorStatus = Status;
  341. RxNameCacheActivateEntry(NameCacheCtl,
  342. NameCache,
  343. 0,
  344. 0);
  345. }
  346. ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
  347. }
  348. VOID
  349. MRxDAVInvalidateFileInfoCache(
  350. PRX_CONTEXT RxContext
  351. )
  352. /*++
  353. Routine Description:
  354. This routine invalidates the name cache entry for both file basic and standard information.
  355. Arguments:
  356. RxContext - the RDBSS context
  357. Return Value:
  358. none
  359. --*/
  360. {
  361. PAGED_CODE();
  362. MRxDAVInvalidateBasicFileInfoCache(RxContext);
  363. MRxDAVInvalidateStandardFileInfoCache(RxContext);
  364. }
  365. VOID
  366. MRxDAVInvalidateFileInfoCacheWithName(
  367. PUNICODE_STRING OriginalFileName,
  368. PMRX_NET_ROOT NetRoot
  369. )
  370. /*++
  371. Routine Description:
  372. This routine invalidates the name cache entry for both file basic and standard information.
  373. Arguments:
  374. RxContext - the RDBSS context
  375. Return Value:
  376. none
  377. --*/
  378. {
  379. PAGED_CODE();
  380. MRxDAVInvalidateBasicFileInfoCacheWithName(OriginalFileName,NetRoot);
  381. MRxDAVInvalidateStandardFileInfoCacheWithName(OriginalFileName,NetRoot);
  382. }
  383. VOID
  384. MRxDAVInvalidateBasicFileInfoCache(
  385. PRX_CONTEXT RxContext
  386. )
  387. /*++
  388. Routine Description:
  389. This routine invalidates the name cache entry for file basic information.
  390. Arguments:
  391. RxContext - the RDBSS context
  392. Return Value:
  393. none
  394. --*/
  395. {
  396. RxCaptureFcb;
  397. PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
  398. PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
  399. PAGED_CODE();
  400. MRxDAVInvalidateBasicFileInfoCacheWithName(OriginalFileName,NetRoot);
  401. }
  402. VOID
  403. MRxDAVInvalidateBasicFileInfoCacheWithName(
  404. PUNICODE_STRING OriginalFileName,
  405. PMRX_NET_ROOT NetRoot
  406. )
  407. /*++
  408. Routine Description:
  409. This routine invalidates the name cache entry for file basic information.
  410. Arguments:
  411. RxContext - the RDBSS context
  412. Return Value:
  413. none
  414. --*/
  415. {
  416. PNAME_CACHE NameCache = NULL;
  417. PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context;
  418. PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFABasic;
  419. PAGED_CODE();
  420. ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
  421. NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
  422. if (NameCache != NULL) {
  423. RxNameCacheExpireEntry(NameCacheCtl, NameCache);
  424. DavDbgTrace(DAV_TRACE_INFOCACHE,
  425. ("Invalid Baisc cache : %wZ\n",OriginalFileName));
  426. }
  427. ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
  428. }
  429. VOID
  430. MRxDAVInvalidateStandardFileInfoCache(
  431. PRX_CONTEXT RxContext
  432. )
  433. /*++
  434. Routine Description:
  435. This routine invalidates the name cache entry for the file standard information.
  436. Arguments:
  437. RxContext - the RDBSS context
  438. Return Value:
  439. none
  440. --*/
  441. {
  442. RxCaptureFcb;
  443. PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
  444. PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
  445. PAGED_CODE();
  446. MRxDAVInvalidateStandardFileInfoCacheWithName(OriginalFileName,NetRoot);
  447. }
  448. VOID
  449. MRxDAVInvalidateStandardFileInfoCacheWithName(
  450. PUNICODE_STRING OriginalFileName,
  451. PMRX_NET_ROOT NetRoot
  452. )
  453. /*++
  454. Routine Description:
  455. This routine invalidates the name cache entry for the file standard information.
  456. Arguments:
  457. RxContext - the RDBSS context
  458. Return Value:
  459. none
  460. --*/
  461. {
  462. PNAME_CACHE NameCache = NULL;
  463. PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context;
  464. PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFAStandard;
  465. PAGED_CODE();
  466. ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
  467. NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
  468. if (NameCache != NULL) {
  469. RxNameCacheExpireEntry(NameCacheCtl, NameCache);
  470. DavDbgTrace(DAV_TRACE_INFOCACHE,
  471. ("Invalid Standard cache : %I64x %wZ\n",((PFILE_STANDARD_INFORMATION)NameCache->ContextExtension)->EndOfFile,OriginalFileName));
  472. }
  473. ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
  474. }
  475. VOID
  476. MRxDAVUpdateFileInfoCacheFileSize(
  477. PRX_CONTEXT RxContext,
  478. PLARGE_INTEGER FileSize
  479. )
  480. /*++
  481. Routine Description:
  482. This routine updates file size on the name cache entry for the file standard information.
  483. Arguments:
  484. RxContext - the RDBSS context
  485. Return Value:
  486. none
  487. --*/
  488. {
  489. RxCaptureFcb;
  490. PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
  491. PNAME_CACHE NameCache = NULL;
  492. PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
  493. PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context;
  494. PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFAStandard;
  495. PFILE_STANDARD_INFORMATION FileInfoCache = NULL;
  496. PAGED_CODE();
  497. ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
  498. NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
  499. if (NameCache != NULL) {
  500. FileInfoCache = (PFILE_STANDARD_INFORMATION)NameCache->ContextExtension;
  501. FileInfoCache->AllocationSize.QuadPart = FileSize->QuadPart;
  502. FileInfoCache->EndOfFile.QuadPart = FileSize->QuadPart;
  503. RxNameCacheActivateEntry(NameCacheCtl,
  504. NameCache,
  505. 0,
  506. 0);
  507. DavDbgTrace(DAV_TRACE_INFOCACHE,
  508. ("Update File size cache : %I64x %wZ\n",((PFILE_STANDARD_INFORMATION)NameCache->ContextExtension)->EndOfFile,OriginalFileName));
  509. }
  510. ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
  511. }
  512. VOID
  513. MRxDAVUpdateBasicFileInfoCache(
  514. PRX_CONTEXT RxContext,
  515. ULONG FileAttributes,
  516. PLARGE_INTEGER pLastWriteTime
  517. )
  518. /*++
  519. Routine Description:
  520. This routine updates file attributs and last write time on the name cache entry
  521. for the file basic information.
  522. Arguments:
  523. RxContext - the RDBSS context
  524. FileAttributes - new file attributes
  525. pLastWriteTime - address of file last write time
  526. Return Value:
  527. none
  528. --*/
  529. {
  530. FILE_BASIC_INFORMATION Basic;
  531. Basic.ChangeTime.QuadPart = 0;
  532. Basic.CreationTime.QuadPart = 0;
  533. Basic.LastWriteTime.QuadPart = 0;
  534. Basic.LastAccessTime.QuadPart = 0;
  535. if (pLastWriteTime != NULL && pLastWriteTime->QuadPart != 0) {
  536. Basic.LastWriteTime = *pLastWriteTime;
  537. }
  538. Basic.FileAttributes = FileAttributes;
  539. MRxDAVUpdateBasicFileInfoCacheAll(RxContext,&Basic);
  540. }
  541. VOID
  542. MRxDAVUpdateBasicFileInfoCacheAll(
  543. PRX_CONTEXT RxContext,
  544. PFILE_BASIC_INFORMATION Basic
  545. )
  546. /*++
  547. Routine Description:
  548. This routine updates the name cache entry for the file basic information.
  549. Arguments:
  550. RxContext - the RDBSS context
  551. Basic - file basic information
  552. Return Value:
  553. none
  554. --*/
  555. {
  556. RxCaptureFcb;
  557. PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
  558. PNAME_CACHE NameCache = NULL;
  559. PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
  560. PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context;
  561. PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFABasic;
  562. PFILE_BASIC_INFORMATION BasicFileInfoCache = NULL;
  563. PAGED_CODE();
  564. ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
  565. NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
  566. if (NameCache != NULL) {
  567. BasicFileInfoCache = (PFILE_BASIC_INFORMATION)NameCache->ContextExtension;
  568. if (Basic->CreationTime.QuadPart != 0) {
  569. BasicFileInfoCache->CreationTime = Basic->CreationTime;
  570. }
  571. if (Basic->LastAccessTime.QuadPart != 0) {
  572. BasicFileInfoCache->LastAccessTime = Basic->LastAccessTime;
  573. }
  574. if (Basic->LastWriteTime.QuadPart != 0) {
  575. BasicFileInfoCache->LastWriteTime = Basic->LastWriteTime;
  576. }
  577. DavDbgTrace(DAV_TRACE_INFOCACHE,
  578. ("Update File Attrib cache 2: %x %wZ\n",BasicFileInfoCache->FileAttributes,OriginalFileName));
  579. BasicFileInfoCache->FileAttributes = Basic->FileAttributes;
  580. if (BasicFileInfoCache->FileAttributes & ~FILE_ATTRIBUTE_NORMAL) {
  581. BasicFileInfoCache->FileAttributes &= ~FILE_ATTRIBUTE_NORMAL;
  582. }
  583. RxNameCacheActivateEntry(NameCacheCtl,
  584. NameCache,
  585. 0,
  586. 0);
  587. DavDbgTrace(DAV_TRACE_INFOCACHE,
  588. ("Update File Attrib cache 3: %x %wZ\n",BasicFileInfoCache->FileAttributes,OriginalFileName));
  589. DavDbgTrace(DAV_TRACE_INFOCACHE,
  590. ("Update File Attrib cache : %I64X %I64X %wZ\n",BasicFileInfoCache->CreationTime,BasicFileInfoCache->LastAccessTime,OriginalFileName));
  591. }
  592. ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
  593. }
  594. VOID
  595. MRxDAVUpdateStandardFileInfoCache(
  596. PRX_CONTEXT RxContext,
  597. PFILE_STANDARD_INFORMATION Standard,
  598. BOOLEAN IsDirectory
  599. )
  600. /*++
  601. Routine Description:
  602. This routine updates the name cache entry for the file standard information.
  603. Arguments:
  604. RxContext - the RDBSS context
  605. Standard - file standard information
  606. IsDirectory - file is a directory
  607. Return Value:
  608. none
  609. --*/
  610. {
  611. RxCaptureFcb;
  612. PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
  613. PNAME_CACHE NameCache = NULL;
  614. PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
  615. PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context;
  616. PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFAStandard;
  617. PFILE_STANDARD_INFORMATION StandardFileInfoCache = NULL;
  618. PAGED_CODE();
  619. ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
  620. NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
  621. if (NameCache != NULL) {
  622. StandardFileInfoCache = (PFILE_STANDARD_INFORMATION)NameCache->ContextExtension;
  623. if (Standard != NULL) {
  624. *StandardFileInfoCache = *Standard;
  625. } else {
  626. StandardFileInfoCache->Directory = IsDirectory;
  627. }
  628. RxNameCacheActivateEntry(NameCacheCtl,
  629. NameCache,
  630. 0,
  631. 0);
  632. DavDbgTrace(DAV_TRACE_INFOCACHE,
  633. (" Update Standard cache : %I64x %wZ\n",((PFILE_STANDARD_INFORMATION)NameCache->ContextExtension)->EndOfFile,OriginalFileName));
  634. }
  635. ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
  636. }
  637. BOOLEAN
  638. MRxDAVIsFileInfoCacheFound(
  639. PRX_CONTEXT RxContext,
  640. PDAV_USERMODE_CREATE_RETURNED_FILEINFO FileInfo,
  641. NTSTATUS *Status,
  642. PUNICODE_STRING OriginalFileName
  643. )
  644. /*++
  645. Routine Description:
  646. This routine looks for the name cache entry of both file basic and standard information.
  647. Arguments:
  648. RxContext - the RDBSS context
  649. FileInfo - buffer to return file basic and standard information
  650. Status - status retured on the last reponse from server
  651. Return Value:
  652. BOOLEAN - name cache found
  653. --*/
  654. {
  655. BOOLEAN CacheFound = FALSE;
  656. if (MRxDAVIsBasicFileInfoCacheFound(RxContext,&FileInfo->BasicInformation,Status,OriginalFileName)) {
  657. if (*Status == STATUS_SUCCESS) {
  658. if (MRxDAVIsStandardFileInfoCacheFound(RxContext,&FileInfo->StandardInformation,Status,OriginalFileName)) {
  659. CacheFound = TRUE;
  660. }
  661. } else {
  662. // if an error stored on the file basic information cache, return cache found
  663. CacheFound = TRUE;
  664. }
  665. }
  666. DavDbgTrace(DAV_TRACE_INFOCACHE,
  667. ("MRxDAVIsFileInfoCacheFound %x %x %wZ\n",*Status,CacheFound,GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext)));
  668. return CacheFound;
  669. }
  670. BOOLEAN
  671. MRxDAVIsBasicFileInfoCacheFound(
  672. PRX_CONTEXT RxContext,
  673. PFILE_BASIC_INFORMATION Basic,
  674. NTSTATUS *Status,
  675. PUNICODE_STRING OriginalFileName
  676. )
  677. /*++
  678. Routine Description:
  679. This routine looks for the name cache entry of the file basic information.
  680. Arguments:
  681. RxContext - the RDBSS context
  682. Basic - buffer to return file basic information
  683. Status - status retured on the last reponse from server
  684. Return Value:
  685. BOOLEAN - name cache found
  686. --*/
  687. {
  688. RxCaptureFcb;
  689. PNAME_CACHE NameCache = NULL;
  690. PMRX_NET_ROOT NetRoot;
  691. PWEBDAV_NET_ROOT DavNetRoot;
  692. PNAME_CACHE_CONTROL NameCacheCtl;
  693. RX_NC_CHECK_STATUS NameCacheStatus;
  694. BOOLEAN CacheFound = FALSE;
  695. BOOLEAN RootFound = FALSE;
  696. ULONG RootAttributes = 0;
  697. NTSTATUS RootStatus = STATUS_SUCCESS;
  698. PAGED_CODE();
  699. if (OriginalFileName == NULL) {
  700. OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
  701. }
  702. if (RxContext->MajorFunction == IRP_MJ_CREATE) {
  703. NetRoot = RxContext->Create.pNetRoot;
  704. } else {
  705. ASSERT(capFcb != NULL);
  706. NetRoot = capFcb->pNetRoot;
  707. }
  708. DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context;
  709. NameCacheCtl = &DavNetRoot->NameCacheCtlGFABasic;
  710. ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
  711. NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
  712. if (NameCache != NULL) {
  713. //
  714. // Found it. Now check entry for not expired.
  715. // Note - The NameCache entry has been pulled off the active list.
  716. //
  717. NameCacheStatus = RxNameCacheCheckEntry(
  718. NameCache,
  719. NameCache->Context);
  720. if (NameCacheStatus == RX_NC_SUCCESS &&
  721. (!RootFound || *Status == RootStatus)) {
  722. // The name cache matches if it is not expired and the attributes matches the one of
  723. // the root file if it is a stream file. If this is a match, return the old status,
  724. // file info and reactivate the entry but leave expiration time unchanged.
  725. *Status = NameCache->PriorStatus;
  726. RxNameCacheOpSaved(NameCacheCtl);
  727. *Basic = *((PFILE_BASIC_INFORMATION)NameCache->ContextExtension);
  728. CacheFound = TRUE;
  729. // put the entry back to the active list without changing the expire time
  730. RxNameCacheActivateEntry(NameCacheCtl, NameCache, 0, 0);
  731. DavDbgTrace(DAV_TRACE_INFOCACHE,
  732. (" Found Basic cache : %x %wZ\n",Basic->FileAttributes,OriginalFileName));
  733. DavDbgTrace(DAV_TRACE_INFOCACHE,
  734. (" Get File Attrib cache : %I64X %I64X %wZ\n",Basic->CreationTime,Basic->LastAccessTime,OriginalFileName));
  735. } else {
  736. // put the entry back to the expire list
  737. RxNameCacheExpireEntry(NameCacheCtl, NameCache);
  738. }
  739. } else {
  740. DavDbgTrace(DAV_TRACE_INFOCACHE,
  741. (" No Basic cache : %wZ\n",OriginalFileName));
  742. }
  743. ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
  744. return CacheFound;
  745. }
  746. BOOLEAN
  747. MRxDAVIsStandardFileInfoCacheFound(
  748. PRX_CONTEXT RxContext,
  749. PFILE_STANDARD_INFORMATION Standard,
  750. NTSTATUS *Status,
  751. PUNICODE_STRING OriginalFileName
  752. )
  753. /*++
  754. Routine Description:
  755. This routine looks for the name cache entry of the file standard information.
  756. Arguments:
  757. RxContext - the RDBSS context
  758. Standard - buffer to return file standard information
  759. Status - status retured on the last reponse from server
  760. Return Value:
  761. BOOLEAN - name cache found
  762. --*/
  763. {
  764. RxCaptureFcb;
  765. RxCaptureFobx;
  766. PNAME_CACHE NameCache = NULL;
  767. PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
  768. PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context;
  769. PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFAStandard;
  770. RX_NC_CHECK_STATUS NameCacheStatus;
  771. BOOLEAN CacheFound = FALSE;
  772. BOOLEAN RootFound = FALSE;
  773. NTSTATUS RootStatus = STATUS_SUCCESS;
  774. PAGED_CODE();
  775. if (OriginalFileName == NULL) {
  776. OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
  777. }
  778. ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
  779. NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
  780. if (NameCache != NULL) {
  781. //
  782. // Found it. Now check entry for not expired.
  783. // Note - The NameCache entry has been pulled off the active list.
  784. //
  785. NameCacheStatus = RxNameCacheCheckEntry(
  786. NameCache,
  787. NameCache->Context);
  788. if (NameCacheStatus == RX_NC_SUCCESS &&
  789. (!RootFound || *Status == RootStatus)) {
  790. // The name cache matches if it is not expired and the status matches the one of
  791. // the root file if it is a stream file. If this is a match, return the old status,
  792. // file info and reactivate the entry but leave expiration time unchanged.
  793. *Status = NameCache->PriorStatus;
  794. RxNameCacheOpSaved(NameCacheCtl);
  795. *Standard = *((PFILE_STANDARD_INFORMATION)NameCache->ContextExtension);
  796. CacheFound = TRUE;
  797. // put the entry back to the active list without changing the expire time
  798. RxNameCacheActivateEntry(NameCacheCtl, NameCache, 0, 0);
  799. DavDbgTrace(DAV_TRACE_INFOCACHE,
  800. (" Get Standard cache : %I64x %wZ\n",((PFILE_STANDARD_INFORMATION)NameCache->ContextExtension)->EndOfFile,OriginalFileName));
  801. } else {
  802. // put the entry back to the expire list
  803. RxNameCacheExpireEntry(NameCacheCtl, NameCache);
  804. }
  805. }
  806. ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
  807. return CacheFound;
  808. }
  809. NTSTATUS
  810. MRxDAVGetFileInfoCacheStatus(
  811. PRX_CONTEXT RxContext
  812. )
  813. /*++
  814. Routine Description:
  815. This routine looks for the status of the name cache entry of either file basic or standard information.
  816. Arguments:
  817. RxContext - the RDBSS context
  818. Return Value:
  819. NTSTATUS - statu of the name cache if found, otherwise, STATUS_SUCCESS
  820. --*/
  821. {
  822. RxCaptureFcb;
  823. PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
  824. PNAME_CACHE NameCache = NULL;
  825. PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
  826. PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context;
  827. PNAME_CACHE_CONTROL NameCacheCtlBasic = &DavNetRoot->NameCacheCtlGFABasic;
  828. PNAME_CACHE_CONTROL NameCacheCtlStandard = &DavNetRoot->NameCacheCtlGFAStandard;
  829. NTSTATUS Status = STATUS_MORE_PROCESSING_REQUIRED;
  830. PAGED_CODE();
  831. ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
  832. NameCache = RxNameCacheFetchEntry(NameCacheCtlBasic,OriginalFileName);
  833. if (NameCache != NULL) {
  834. RX_NC_CHECK_STATUS NameCacheStatus;
  835. //
  836. // Found it. Now check entry for not expired
  837. //
  838. NameCacheStatus = RxNameCacheCheckEntry(NameCache,NameCache->Context);
  839. if (NameCacheStatus == RX_NC_SUCCESS) {
  840. //
  841. // If the cache has not expired, return the previous status.
  842. //
  843. Status = NameCache->PriorStatus;
  844. RxNameCacheOpSaved(NameCacheCtlBasic);
  845. // put the entry back to the active list without changing the expire time
  846. RxNameCacheActivateEntry(NameCacheCtlBasic, NameCache, 0, 0);
  847. DavDbgTrace(DAV_TRACE_INFOCACHE,
  848. (" Get Basic Status : %x %wZ\n",Status,OriginalFileName));
  849. } else {
  850. // put the entry back to the expire list
  851. RxNameCacheExpireEntry(NameCacheCtlBasic, NameCache);
  852. }
  853. } else {
  854. NameCache = RxNameCacheFetchEntry(NameCacheCtlStandard,OriginalFileName);
  855. if (NameCache != NULL) {
  856. RX_NC_CHECK_STATUS NameCacheStatus;
  857. //
  858. // Found it. Now check entry for not expired
  859. //
  860. NameCacheStatus = RxNameCacheCheckEntry(NameCache,NameCache->Context);
  861. if (NameCacheStatus == RX_NC_SUCCESS) {
  862. //
  863. // If the cache has not expired, return the previous status.
  864. //
  865. Status = NameCache->PriorStatus;
  866. RxNameCacheOpSaved(NameCacheCtlStandard);
  867. // put the entry back to the active list without changing the expire time
  868. RxNameCacheActivateEntry(NameCacheCtlStandard, NameCache, 0, 0);
  869. } else {
  870. // put the entry back to the expire list
  871. RxNameCacheExpireEntry(NameCacheCtlStandard, NameCache);
  872. }
  873. }
  874. }
  875. ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
  876. return Status;
  877. }
  878. BOOLEAN
  879. MRxDAVIsFileNotFoundCached(
  880. PRX_CONTEXT RxContext
  881. )
  882. /*++
  883. Routine Description:
  884. This routine checks if the name cache entry exists as File Not Found.
  885. Arguments:
  886. RxContext - the RDBSS context
  887. Return Value:
  888. BOOLEAN - name cache found
  889. --*/
  890. {
  891. RxCaptureFcb;
  892. PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
  893. PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
  894. PAGED_CODE();
  895. return MRxDAVIsFileNotFoundCachedWithName(OriginalFileName,NetRoot);
  896. }
  897. BOOLEAN
  898. MRxDAVIsFileNotFoundCachedWithName(
  899. PUNICODE_STRING OriginalFileName,
  900. PMRX_NET_ROOT NetRoot
  901. )
  902. /*++
  903. Routine Description:
  904. This routine checks if the name cache entry exists as File Not Found.
  905. Arguments:
  906. RxContext - the RDBSS context
  907. Return Value:
  908. BOOLEAN - name cache found
  909. --*/
  910. {
  911. PNAME_CACHE NameCache = NULL;
  912. PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context;
  913. PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlFNF;
  914. BOOLEAN CacheFound = FALSE;
  915. PAGED_CODE();
  916. ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
  917. NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
  918. if (NameCache != NULL) {
  919. RX_NC_CHECK_STATUS NameCacheStatus;
  920. //
  921. // Found it. Now check entry for not expired.
  922. // Note - The NameCache entry has been pulled off the active list.
  923. //
  924. NameCacheStatus = RxNameCacheCheckEntry(
  925. NameCache,
  926. //MRxDAVStatistics.SmbsReceived.LowPart
  927. NameCache->Context);
  928. if ((NameCacheStatus == RX_NC_SUCCESS) &&
  929. (NameCache->PriorStatus == STATUS_OBJECT_NAME_NOT_FOUND)) {
  930. //
  931. // This is a match. Return the old status, file info and
  932. // reactivate the entry but leave expiration time unchanged.
  933. //
  934. CacheFound = TRUE;
  935. DavDbgTrace(DAV_TRACE_INFOCACHE,
  936. ("MRxDAVIsFileNotFoundCached %wZ\n",OriginalFileName));
  937. // put the entry back to the active list without changing the expire time
  938. RxNameCacheActivateEntry(NameCacheCtl, NameCache, 0, 0);
  939. } else {
  940. // put the entry back to the expire list
  941. RxNameCacheExpireEntry(NameCacheCtl, NameCache);
  942. }
  943. }
  944. ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
  945. return CacheFound;
  946. }
  947. VOID
  948. MRxDAVCacheFileNotFound(
  949. PRX_CONTEXT RxContext
  950. )
  951. /*++
  952. Routine Description:
  953. This routine creates the name cache entry for File Not Found.
  954. Arguments:
  955. RxContext - the RDBSS context
  956. Return Value:
  957. BOOLEAN - name cache found
  958. --*/
  959. {
  960. RxCaptureFcb;
  961. PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
  962. PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
  963. PAGED_CODE();
  964. MRxDAVCacheFileNotFoundWithName(OriginalFileName,NetRoot);
  965. }
  966. VOID
  967. MRxDAVCacheFileNotFoundWithName(
  968. PUNICODE_STRING OriginalFileName,
  969. PMRX_NET_ROOT NetRoot
  970. )
  971. /*++
  972. Routine Description:
  973. This routine creates the name cache entry for File Not Found.
  974. Arguments:
  975. RxContext - the RDBSS context
  976. Return Value:
  977. BOOLEAN - name cache found
  978. --*/
  979. {
  980. PNAME_CACHE NameCache = NULL;
  981. PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context;
  982. PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlFNF;
  983. PAGED_CODE();
  984. ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
  985. NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
  986. if (NameCache != NULL) {
  987. NameCache->PriorStatus = STATUS_OBJECT_NAME_NOT_FOUND;
  988. RxNameCacheActivateEntry(
  989. NameCacheCtl,
  990. NameCache,
  991. FileNotFoundCacheLifeTimeInSec,
  992. MRxDAVStatistics.SmbsReceived.LowPart);
  993. } else {
  994. NameCache = RxNameCacheCreateEntry (
  995. NameCacheCtl,
  996. OriginalFileName,
  997. TRUE); // case insensitive match
  998. if (NameCache != NULL) {
  999. NameCache->PriorStatus = STATUS_OBJECT_NAME_NOT_FOUND;
  1000. RxNameCacheActivateEntry(
  1001. NameCacheCtl,
  1002. NameCache,
  1003. FileNotFoundCacheLifeTimeInSec,
  1004. MRxDAVStatistics.SmbsReceived.LowPart);
  1005. }
  1006. }
  1007. ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
  1008. DavDbgTrace(DAV_TRACE_INFOCACHE,
  1009. ("MRxDAVCacheFileNotFound %wZ\n",OriginalFileName));
  1010. }
  1011. VOID
  1012. MRxDAVCacheFileNotFoundFromQueryDirectory(
  1013. PRX_CONTEXT RxContext
  1014. )
  1015. /*++
  1016. Routine Description:
  1017. This routine creates the name cache entry for File Not Found.
  1018. Arguments:
  1019. RxContext - the RDBSS context
  1020. Return Value:
  1021. BOOLEAN - name cache found
  1022. --*/
  1023. {
  1024. RxCaptureFcb;
  1025. RxCaptureFobx;
  1026. PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
  1027. PUNICODE_STRING Template = &capFobx->UnicodeQueryTemplate;
  1028. UNICODE_STRING FileName;
  1029. PNAME_CACHE NameCache = NULL;
  1030. PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
  1031. PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context;
  1032. PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlFNF;
  1033. PAGED_CODE();
  1034. ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
  1035. NameCache = RxNameCacheFetchEntry(NameCacheCtl,&FileName);
  1036. if (NameCache != NULL) {
  1037. if ((NameCache == NULL) &&
  1038. (OriginalFileName->Length > sizeof(WCHAR))) {
  1039. //
  1040. // Do lookup now since we may have skipped it at entry.
  1041. //
  1042. NameCache = RxNameCacheFetchEntry(NameCacheCtl,&FileName);
  1043. if (NameCache == NULL) {
  1044. NameCache = RxNameCacheCreateEntry (
  1045. NameCacheCtl,
  1046. OriginalFileName,
  1047. TRUE); // case insensitive match
  1048. }
  1049. }
  1050. if (NameCache != NULL) {
  1051. NameCache->PriorStatus = STATUS_OBJECT_NAME_NOT_FOUND;
  1052. RxNameCacheActivateEntry(
  1053. NameCacheCtl,
  1054. NameCache,
  1055. FileNotFoundCacheLifeTimeInSec,
  1056. MRxDAVStatistics.SmbsReceived.LowPart);
  1057. }
  1058. }
  1059. ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
  1060. }
  1061. VOID
  1062. MRxDAVInvalidateFileNotFoundCache(
  1063. PRX_CONTEXT RxContext
  1064. )
  1065. /*++
  1066. Routine Description:
  1067. This routine invalidates the name cache entry as File Not Found.
  1068. Arguments:
  1069. RxContext - the RDBSS context
  1070. Return Value:
  1071. BOOLEAN - name cache found
  1072. --*/
  1073. {
  1074. RxCaptureFcb;
  1075. PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
  1076. PNAME_CACHE NameCache = NULL;
  1077. PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
  1078. PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context;
  1079. PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlFNF;
  1080. PAGED_CODE();
  1081. ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
  1082. NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
  1083. if (NameCache != NULL) {
  1084. RxNameCacheExpireEntry(NameCacheCtl, NameCache);
  1085. }
  1086. ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
  1087. DavDbgTrace(DAV_TRACE_INFOCACHE,
  1088. ("MRxDAVInvalidateFileNotFoundCache %wZ\n",OriginalFileName));
  1089. }
  1090. VOID
  1091. MRxDAVInvalidateFileNotFoundCacheForRename(
  1092. PRX_CONTEXT RxContext
  1093. )
  1094. /*++
  1095. Routine Description:
  1096. This routine invalidates the name cache entry as File Not Found.
  1097. Arguments:
  1098. RxContext - the RDBSS context
  1099. Return Value:
  1100. BOOLEAN - name cache found
  1101. --*/
  1102. {
  1103. RxCaptureFcb;
  1104. UNICODE_STRING RenameName;
  1105. PNAME_CACHE NameCache = NULL;
  1106. PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
  1107. PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context;
  1108. PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlFNF;
  1109. PFILE_RENAME_INFORMATION RenameInformation = RxContext->Info.Buffer;
  1110. RenameName.Buffer = &RenameInformation->FileName[0];
  1111. RenameName.Length = (USHORT)RenameInformation->FileNameLength;
  1112. DavDbgTrace(DAV_TRACE_DETAIL,
  1113. ("Invalidate FNF cache from rename %wZ\n", &RenameName));
  1114. PAGED_CODE();
  1115. ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
  1116. NameCache = RxNameCacheFetchEntry(NameCacheCtl,&RenameName);
  1117. if (NameCache != NULL) {
  1118. RxNameCacheExpireEntry(NameCacheCtl, NameCache);
  1119. }
  1120. ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
  1121. }