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.

368 lines
11 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. write.c
  5. Abstract:
  6. This module implements the mini redirector call down routines pertaining
  7. to write of file system objects.
  8. Author:
  9. Balan Sethu Raman [SethuR] 7-March-1995
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. //
  15. // The local debug trace level
  16. //
  17. #define Dbg (DEBUG_TRACE_WRITE)
  18. //
  19. // External declartions
  20. //
  21. NTSTATUS
  22. MRxProxyWriteContinuation(
  23. MRXPROXY_ASYNCENGINE_ARGUMENT_SIGNATURE
  24. );
  25. NTSTATUS
  26. MRxProxyWrite(
  27. IN PRX_CONTEXT RxContext
  28. )
  29. /*++
  30. Routine Description:
  31. This routine handles network read requests.
  32. Arguments:
  33. RxContext - the RDBSS context
  34. Return Value:
  35. RXSTATUS - The return status for the operation
  36. --*/
  37. {
  38. NTSTATUS Status = STATUS_SUCCESS;
  39. //RxCaptureFcb; RxCaptureFobx;
  40. //PMRXPROXY_ASYNCENGINE_CONTEXT AsyncEngineContext;
  41. PAGED_CODE();
  42. RxDbgTrace(+1, Dbg, ("MRxProxyWrite\n", 0 ));
  43. //in outerwrapper ASSERT( NodeType(capFobx->pSrvOpen) == RDBSS_NTC_SRVOPEN );
  44. Status = MRxProxyAsyncEngineOuterWrapper(
  45. RxContext,
  46. MRXPROXY_ASYNCENG_CTX_FROM_WRITE,
  47. MRxProxyWriteContinuation,
  48. "MRxProxyWrite",
  49. FALSE, //loudprocessing
  50. FALSE
  51. );
  52. RxDbgTrace(-1, Dbg, ("MRxProxyWrite exit with status=%08lx\n", Status ));
  53. return(Status);
  54. } // MRxProxyWrite
  55. NTSTATUS
  56. MRxProxyWriteContinuation(
  57. MRXPROXY_ASYNCENGINE_ARGUMENT_SIGNATURE
  58. )
  59. /*++
  60. Routine Description:
  61. This is the start routine for read.
  62. Arguments:
  63. Return Value:
  64. RXSTATUS - The return status for the operation
  65. --*/
  66. {
  67. NTSTATUS Status; //this is initialized to proxybufstatus on a reenter
  68. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  69. ULONG ContinueEntryCount;
  70. RxCaptureFcb; RxCaptureFobx;
  71. //PMRX_SRV_OPEN SrvOpen = capFobx->pSrvOpen;
  72. //PMRX_PROXY_SRV_OPEN proxySrvOpen = MRxProxyGetSrvOpenExtension(SrvOpen);
  73. PMRX_PROXY_FCB proxyFcb = MRxProxyGetFcbExtension(capFcb);
  74. BOOLEAN SynchronousIo =
  75. !BooleanFlagOn(RxContext->Flags,RX_CONTEXT_FLAG_ASYNC_OPERATION);
  76. BOOLEAN PagingIo =
  77. BooleanFlagOn(LowIoContext->ParamsFor.ReadWrite.Flags,LOWIO_READWRITEFLAG_PAGING_IO);
  78. PAGED_CODE();
  79. RxDbgTrace(+1, Dbg, ("MRxProxyWriteContinuation\n", 0 ));
  80. ASSERT_ASYNCENG_CONTEXT(AsyncEngineContext);
  81. AsyncEngineContext->ContinueEntryCount++;
  82. ContinueEntryCount = AsyncEngineContext->ContinueEntryCount;
  83. for (;;) {
  84. //
  85. // Case on the current state
  86. //
  87. switch (AsyncEngineContext->OpSpecificState) {
  88. case MRxProxyAsyncEngOEInnerIoStates_Initial:
  89. AsyncEngineContext->OpSpecificState = MRxProxyAsyncEngOEInnerIoStates_ReadyToSend;
  90. //
  91. // If not a synchronous write, then continue here when resumed
  92. //
  93. // CODE.IMPROVEMENT don't use presense of continuation as the async marker...use a flag
  94. if (!SynchronousIo) {
  95. SetFlag(AsyncEngineContext->Flags,MRXPROXY_ASYNCENG_CTX_FLAG_ASYNC_OPERATION);
  96. AsyncEngineContext->Continuation = MRxProxyWriteContinuation;
  97. }
  98. //lack of break is intentional
  99. case MRxProxyAsyncEngOEInnerIoStates_ReadyToSend:
  100. AsyncEngineContext->OpSpecificState = MRxProxyAsyncEngOEInnerIoStates_OperationOutstanding;
  101. if (PagingIo) {
  102. if (TRUE) {
  103. RxLog(("PageWrite: rx/offset/len %lx/%lx/%lx",
  104. RxContext,
  105. (ULONG)(LowIoContext->ParamsFor.ReadWrite.ByteOffset),
  106. LowIoContext->ParamsFor.ReadWrite.ByteCount
  107. ));
  108. }
  109. }
  110. Status = MRxProxyBuildAsynchronousRequest(
  111. RxContext, // IN PVOID Context
  112. MRxProxyAsyncEngineCalldownIrpCompletion // IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL,
  113. );
  114. if (Status != STATUS_SUCCESS) {
  115. goto FINALLY;
  116. }
  117. Status = MRxProxySubmitAsyncEngRequest(
  118. MRXPROXY_ASYNCENGINE_ARGUMENTS,
  119. MRXPROXY_ASYNCENG_AECTXTYPE_WRITE
  120. );
  121. //
  122. // If the status is PENDING, then we're done for now. We must
  123. // wait until we're re-entered when the receive happens.
  124. //
  125. if (Status==(STATUS_PENDING)) {
  126. ASSERT(!SynchronousIo);
  127. goto FINALLY;
  128. }
  129. AsyncEngineContext->Status = Status;
  130. //lack of break is intentional
  131. case MRxProxyAsyncEngOEInnerIoStates_OperationOutstanding:
  132. AsyncEngineContext->OpSpecificState = MRxProxyAsyncEngOEInnerIoStates_ReadyToSend;
  133. Status = AsyncEngineContext->Status;
  134. RxContext->InformationToReturn += AsyncEngineContext->Information;
  135. goto FINALLY;
  136. break;
  137. }
  138. }
  139. FINALLY:
  140. //CODE.IMPROVEMENT read_start and write_start and locks_start should be combined.....we use this
  141. //macro until then to keep the async stuff identical
  142. if ( Status != (STATUS_PENDING) ) {
  143. MRxProxyAsyncEngAsyncCompletionIfNecessary(AsyncEngineContext,RxContext);
  144. }
  145. RxDbgTrace(-1, Dbg, ("MRxProxyWriteContinuation exit w %08lx\n", Status ));
  146. return Status;
  147. } // ProxyPseExchangeStart_Write
  148. NTSTATUS
  149. MRxProxyExtendForCache(
  150. IN OUT PRX_CONTEXT RxContext,
  151. IN OUT PLARGE_INTEGER pNewFileSize,
  152. OUT PLARGE_INTEGER pNewAllocationSize
  153. )
  154. /*++
  155. Routine Description:
  156. This routine extends the file allocation so that the we can do a copywrite. the fcb lock
  157. is exclusive here; we will take the opportunity to find out the actual allocation so that
  158. we'll get the fast path. another minirdr might want to guess instead since it might be actual net ios
  159. otherwise.
  160. Arguments:
  161. RxContext - the RDBSS context
  162. Return Value:
  163. RXSTATUS - Returns the status for the set file allocation...could be an error if disk full
  164. --*/
  165. {
  166. NTSTATUS Status = STATUS_SUCCESS;
  167. //PMRXPROXY_RX_CONTEXT pMRxProxyContext = MRxProxyGetMinirdrContext(RxContext);
  168. RxCaptureFcb; RxCaptureFobx;
  169. //PMRX_PROXY_FOBX proxyFobx = MRxProxyGetFileObjectExtension(capFobx);
  170. PMRX_SRV_OPEN SrvOpen = capFobx->pSrvOpen;
  171. PMRX_PROXY_SRV_OPEN proxySrvOpen = MRxProxyGetSrvOpenExtension(SrvOpen);
  172. //PMRX_PROXY_FCB proxyFcb = MRxProxyGetFcbExtension(capFcb);
  173. PFILE_OBJECT UnderlyingFileObject = proxySrvOpen->UnderlyingFileObject;
  174. PFILE_ALLOCATION_INFORMATION Buffer;
  175. FILE_ALLOCATION_INFORMATION FileAllocationInformationBuffer;
  176. ULONG Length = sizeof(FILE_ALLOCATION_INFORMATION);
  177. PAGED_CODE();
  178. RxDbgTrace(+1, Dbg, ("MRxProxyExtendForNonCache %08lx %08lx %08lx %08lx\n",
  179. capFcb->Header.FileSize.LowPart,
  180. capFcb->Header.AllocationSize.LowPart,
  181. pNewFileSize->LowPart,
  182. pNewAllocationSize->LowPart
  183. ));
  184. Buffer = &FileAllocationInformationBuffer;
  185. ASSERT (UnderlyingFileObject);
  186. //don't need this!!!
  187. //if (capFcb->Header.AllocationSize.QuadPart >= *pNewFileSize) {
  188. // Status = RxStatus(SUCCESS);
  189. // RxDbgTrace(-1, Dbg, (" PlentyAllocation = %08lx\n", Status));
  190. // return(Status);
  191. //}
  192. //pNewAllocationSize->QuadPart = pNewFileSize->QuadPart;
  193. { LONGLONG CurrentExtend = pNewFileSize->QuadPart - capFcb->Header.AllocationSize.QuadPart;
  194. Buffer->AllocationSize.QuadPart = capFcb->Header.AllocationSize.QuadPart
  195. + 32 * CurrentExtend;
  196. }
  197. RxDbgTrace( 0, Dbg, (" Extending to %08lx from %08lx!\n",
  198. Buffer->AllocationSize.LowPart,
  199. capFcb->Header.AllocationSize.LowPart));
  200. Status = MRxProxySyncXxxInformation(
  201. RxContext, //IN OUT PRX_CONTEXT RxContext,
  202. IRP_MJ_SET_INFORMATION, //IN UCHAR MajorFunction,
  203. UnderlyingFileObject, //IN PFILE_OBJECT FileObject,
  204. FileAllocationInformation, //IN ULONG InformationClass,
  205. Length, //IN ULONG Length,
  206. Buffer, //OUT PVOID Information,
  207. NULL //OUT PULONG ReturnedLength OPTIONAL
  208. );
  209. //CODE.IMPROVEMENT here we should now read it back and see what we actually got;
  210. // for smallio we will be seeing subcluster extension when, in fact, we get a
  211. // cluster at a time. we could just round it up.
  212. if (Status == STATUS_SUCCESS) {
  213. *pNewAllocationSize = Buffer->AllocationSize;
  214. RxDbgTrace(-1, Dbg, (" ---->Status (extend1) = %08lx\n", Status));
  215. return(Status);
  216. }
  217. RxDbgTrace( 0, Dbg, (" EXTEND1 FAILED!!!!!!%c\n", '!'));
  218. //try for exactly what we need
  219. Buffer->AllocationSize.QuadPart = pNewFileSize->QuadPart;
  220. Status = MRxProxySyncXxxInformation(
  221. RxContext, //IN OUT PRX_CONTEXT RxContext,
  222. IRP_MJ_SET_INFORMATION, //IN UCHAR MajorFunction,
  223. UnderlyingFileObject, //IN PFILE_OBJECT FileObject,
  224. FileAllocationInformation, //IN ULONG InformationClass,
  225. Length, //IN ULONG Length,
  226. Buffer, //OUT PVOID Information,
  227. NULL //OUT PULONG ReturnedLength OPTIONAL
  228. );
  229. if (Status == STATUS_SUCCESS) {
  230. *pNewAllocationSize = Buffer->AllocationSize;
  231. RxDbgTrace(-1, Dbg, (" ---->Status (extend2) = %08lx\n", Status));
  232. return(Status);
  233. }
  234. RxDbgTrace( 0, Dbg, (" EXTEND2 FAILED!!!!!!%c\n", '!'));
  235. RxDbgTrace(-1, Dbg, (" ---->Status (notextended) = %08lx\n", Status));
  236. return(Status);
  237. }
  238. NTSTATUS
  239. MRxProxyExtendForNonCache(
  240. IN OUT PRX_CONTEXT RxContext,
  241. IN OUT PLARGE_INTEGER pNewFileSize,
  242. OUT PLARGE_INTEGER pNewAllocationSize
  243. )
  244. /*++
  245. Routine Description:
  246. This routine handles requests to extend the file for noncached IO. we just let the write extend the file
  247. so we don't do anything here.
  248. Arguments:
  249. RxContext - the RDBSS context
  250. Return Value:
  251. RXSTATUS - The return status for the operation
  252. --*/
  253. {
  254. NTSTATUS Status = STATUS_SUCCESS;
  255. RxCaptureFcb; RxCaptureFobx;
  256. RxDbgTrace(+1, Dbg, ("MRxProxyExtendForNonCache %08lx %08lx %08lx %08lx\n",
  257. capFcb->Header.FileSize.LowPart,
  258. capFcb->Header.AllocationSize.LowPart,
  259. pNewFileSize->LowPart,
  260. pNewAllocationSize->LowPart
  261. ));
  262. pNewAllocationSize->QuadPart = pNewFileSize->QuadPart;
  263. RxDbgTrace(-1, Dbg, ("MRxProxyExtendForCache exit with status=%08lx %08lx %08lx\n",
  264. Status, pNewFileSize->LowPart, pNewAllocationSize->LowPart));
  265. return(Status);
  266. }
  267.