Source code of Windows XP (NT5)
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.

237 lines
5.9 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. cache.c
  5. Abstract:
  6. This module implements the cache management routines for the Rx
  7. FSD and FSP, by calling the Common Cache Manager.
  8. Author:
  9. JoeLinn Created.
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. //
  15. // The Bug check file id for this module
  16. //
  17. #define BugCheckFileId (RDBSS_BUG_CHECK_CACHESUP)
  18. //
  19. // Local debug trace level
  20. //
  21. #define Dbg (DEBUG_TRACE_CACHESUP)
  22. BOOLEAN
  23. RxLockEnumerator (
  24. IN OUT struct _MRX_SRV_OPEN_ * SrvOpen,
  25. IN OUT PVOID *ContinuationHandle,
  26. OUT PLARGE_INTEGER FileOffset,
  27. OUT PLARGE_INTEGER LockRange,
  28. OUT PBOOLEAN IsLockExclusive
  29. );
  30. #ifdef ALLOC_PRAGMA
  31. #pragma alloc_text(PAGE, RxCompleteMdl)
  32. //#pzragma alloc_text(PAGE, RxZeroData)
  33. #pragma alloc_text(PAGE, RxSyncUninitializeCacheMap)
  34. #pragma alloc_text(PAGE, RxLockEnumerator)
  35. #endif
  36. // we can't use the Io system exported form of this because he does it on a file object. during a state
  37. // change, we don't know which fileobject it applies to (altho, i suppose we could walk the list and
  38. // find out). so we need to apply this to the fcb instead.
  39. #define RxIsFcbOpenedExclusively(FCB) ( ((FCB)->ShareAccess.SharedRead \
  40. + (FCB)->ShareAccess.SharedWrite \
  41. + (FCB)->ShareAccess.SharedDelete) == 0 )
  42. NTSTATUS
  43. RxCompleteMdl (
  44. IN PRX_CONTEXT RxContext
  45. )
  46. /*++
  47. Routine Description:
  48. This routine performs the function of completing Mdl read and write
  49. requests. It should be called only from RxFsdRead and RxFsdWrite.
  50. Arguments:
  51. RxContext - the Rx Context
  52. Return Value:
  53. RXSTATUS - Will always be RxStatus(PENDING) or STATUS_SUCCESS.
  54. --*/
  55. {
  56. RxCaptureParamBlock;
  57. RxCaptureFileObject;
  58. RxCaptureRequestPacket;
  59. PAGED_CODE();
  60. RxDbgTrace(+1, Dbg, ("RxCompleteMdl\n", 0 ));
  61. RxDbgTrace( 0, Dbg, ("RxContext = %08lx\n", RxContext ));
  62. RxDbgTrace( 0, Dbg, ("Irp = %08lx\n", capReqPacket ));
  63. switch( RxContext->MajorFunction ) {
  64. case IRP_MJ_READ:
  65. CcMdlReadComplete( capFileObject, capReqPacket->MdlAddress );
  66. break;
  67. case IRP_MJ_WRITE:
  68. ASSERT( FlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT ));
  69. CcMdlWriteComplete( capFileObject, &capPARAMS->Parameters.Write.ByteOffset, capReqPacket->MdlAddress );
  70. capReqPacket->IoStatus.Status = STATUS_SUCCESS;
  71. break;
  72. default:
  73. RxDbgTrace( 0, (DEBUG_TRACE_ERROR), ("Illegal Mdl Complete.\n", 0));
  74. RxBugCheck( RxContext->MajorFunction, 0, 0 );
  75. }
  76. //
  77. // Mdl is now deallocated.
  78. //
  79. capReqPacket->MdlAddress = NULL;
  80. //
  81. // Complete the request and exit right away.
  82. //
  83. RxCompleteRequest( RxContext, STATUS_SUCCESS );
  84. RxDbgTrace(-1, Dbg, ("RxCompleteMdl -> RxStatus(SUCCESS\n)", 0 ));
  85. return STATUS_SUCCESS;
  86. }
  87. VOID
  88. RxSyncUninitializeCacheMap (
  89. IN PRX_CONTEXT RxContext,
  90. IN PFILE_OBJECT FileObject
  91. )
  92. /*++
  93. Routine Description:
  94. The routine performs a CcUnitializeCacheMap to LargeZero synchronously. That
  95. is it waits on the Cc event. This call is useful when we want to be certain
  96. when a close will actually some in.
  97. Return Value:
  98. None.
  99. --*/
  100. {
  101. CACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent;
  102. NTSTATUS WaitStatus;
  103. PAGED_CODE();
  104. KeInitializeEvent( &UninitializeCompleteEvent.Event,
  105. SynchronizationEvent,
  106. FALSE);
  107. CcUninitializeCacheMap( FileObject,
  108. &RxLargeZero,
  109. &UninitializeCompleteEvent );
  110. //
  111. // Now wait for the cache manager to finish purging the file.
  112. // This will garentee that Mm gets the purge before we
  113. // delete the Vcb.
  114. //
  115. WaitStatus = KeWaitForSingleObject( &UninitializeCompleteEvent.Event,
  116. Executive,
  117. KernelMode,
  118. FALSE,
  119. NULL);
  120. ASSERT (NT_SUCCESS(WaitStatus));
  121. }
  122. BOOLEAN
  123. RxLockEnumerator (
  124. IN OUT struct _MRX_SRV_OPEN_ * SrvOpen,
  125. IN OUT PVOID *ContinuationHandle,
  126. OUT PLARGE_INTEGER FileOffset,
  127. OUT PLARGE_INTEGER LockRange,
  128. OUT PBOOLEAN IsLockExclusive
  129. )
  130. /*++
  131. Routine Description:
  132. This routine is called from a minirdr to enumerate the filelocks on an FCB; it gets
  133. one lock on each call. currently, we just pass thru to the fsrtl routine which is very funky
  134. because it keeps the enumeration state internally; as a result, only one enumeration can be in progress
  135. at any time. we can change over to something better if it's ever required.
  136. Arguments:
  137. SrvOpen - a srvopen on the fcb to be enumerated.
  138. ContinuationHandle - a handle passed back and forth representing the state of the enumeration.
  139. if a NULL is passed in, then we are to start at the beginning.
  140. FileOffset,LockRange,IsLockExclusive - the description of the returned lock
  141. Return Value:
  142. a BOOLEAN. FALSE means you've reached the end of the list; TRUE means the returned lock data is valid
  143. --*/
  144. {
  145. PFILE_LOCK_INFO p;
  146. ULONG LockNumber;
  147. PFCB Fcb = (PFCB)(SrvOpen->pFcb);
  148. PAGED_CODE();
  149. RxDbgTrace(0,Dbg,("FCB (%lx) LOCK Enumeration Buffering Flags(%lx)\n",Fcb,Fcb->FcbState));
  150. if (!FlagOn(Fcb->FcbState,FCB_STATE_LOCK_BUFFERING_ENABLED)) {
  151. return FALSE;
  152. }
  153. LockNumber = PtrToUlong(*ContinuationHandle);
  154. p = FsRtlGetNextFileLock( &Fcb->Specific.Fcb.FileLock, (BOOLEAN)(LockNumber==0) );
  155. LockNumber++;
  156. if (p==NULL) {
  157. return(FALSE);
  158. }
  159. RxDbgTrace(0, Dbg, ("Rxlockenum %08lx\n", LockNumber ));
  160. *FileOffset = p->StartingByte;
  161. *LockRange = p->Length;
  162. *IsLockExclusive = p->ExclusiveLock;
  163. *ContinuationHandle = LongToPtr(LockNumber);
  164. return(TRUE);
  165. }