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.

265 lines
7.2 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. querydir.c
  5. Abstract:
  6. This module implements the mini redirector call down routines pertaining to query directory.
  7. Author:
  8. joelinn [joelinn] 01-02-97
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. //
  14. // The local debug trace level
  15. //
  16. #define Dbg (DEBUG_TRACE_DIRCTRL)
  17. //
  18. // External declartions
  19. //
  20. NTSTATUS
  21. MRxProxyQueryDirOrFlushContinuation(
  22. MRXPROXY_ASYNCENGINE_ARGUMENT_SIGNATURE
  23. );
  24. RXDT_DefineCategory(DIRCTRL);
  25. #define Dbg (DEBUG_TRACE_DIRCTRL)
  26. ULONG MRxProxyStopOnLoudCompletion = TRUE;
  27. NTSTATUS
  28. MRxProxyQueryDirectory(
  29. IN PRX_CONTEXT RxContext
  30. )
  31. /*++
  32. Routine Description:
  33. This routine handles network querydir requests.
  34. Arguments:
  35. RxContext - the RDBSS context
  36. Return Value:
  37. RXSTATUS - The return status for the operation
  38. --*/
  39. {
  40. NTSTATUS Status = STATUS_SUCCESS;
  41. RxCaptureFcb; RxCaptureFobx;
  42. PAGED_CODE();
  43. RxDbgTrace(+1, Dbg, ("MRxProxyQueryDir %08lx\n", RxContext ));
  44. ASSERT( NodeType(capFobx->pSrvOpen) == RDBSS_NTC_SRVOPEN );
  45. MRxProxySetLoud("QueryDir ",RxContext,&(capFobx->UnicodeQueryTemplate));
  46. Status = MRxProxyAsyncEngineOuterWrapper(
  47. RxContext,
  48. MRXPROXY_ASYNCENG_CTX_FROM_QUERYDIR,
  49. MRxProxyQueryDirOrFlushContinuation,
  50. "MRxProxyQueryDir",
  51. TRUE, //loudprocessing
  52. (BOOLEAN)MRxProxyStopOnLoudCompletion
  53. );
  54. RxDbgTrace(-1, Dbg, ("MRxProxyQueryDir %08lx exit with status=%08lx\n", RxContext, Status ));
  55. return(Status);
  56. } // MRxProxyQueryDir
  57. NTSTATUS
  58. MRxProxyFlush(
  59. IN PRX_CONTEXT RxContext
  60. )
  61. /*++
  62. Routine Description:
  63. This routine handles flush requests.
  64. Arguments:
  65. RxContext - the RDBSS context
  66. Return Value:
  67. RXSTATUS - The return status for the operation
  68. --*/
  69. {
  70. NTSTATUS Status = STATUS_SUCCESS;
  71. RxCaptureFcb; RxCaptureFobx;
  72. PAGED_CODE();
  73. RxDbgTrace(+1, Dbg, ("MRxProxyFlush %08lx\n", RxContext ));
  74. ASSERT( NodeType(capFobx->pSrvOpen) == RDBSS_NTC_SRVOPEN );
  75. //MRxProxySetLoud("QueryDir ",RxContext,&(capFobx->UnicodeQueryTemplate));
  76. Status = MRxProxyAsyncEngineOuterWrapper(
  77. RxContext,
  78. MRXPROXY_ASYNCENG_CTX_FROM_FLUSH,
  79. MRxProxyQueryDirOrFlushContinuation,
  80. "MRxProxyFlush",
  81. TRUE, //loudprocessing
  82. (BOOLEAN)MRxProxyStopOnLoudCompletion
  83. );
  84. RxDbgTrace(-1, Dbg, ("MRxProxyFlush %08lx exit with status=%08lx\n", RxContext, Status ));
  85. return(Status);
  86. } // MRxProxyFlush
  87. NTSTATUS
  88. MRxProxyQueryDirOrFlushContinuation(
  89. MRXPROXY_ASYNCENGINE_ARGUMENT_SIGNATURE
  90. )
  91. /*++
  92. Routine Description:
  93. This is the start routine for query directiry.
  94. Arguments:
  95. Return Value:
  96. RXSTATUS - The return status for the operation
  97. --*/
  98. {
  99. NTSTATUS Status; //this is initialized to proxybufstatus on a reenter
  100. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  101. ULONG ContinueEntryCount;
  102. RxCaptureFcb; RxCaptureFobx;
  103. PMRX_SRV_OPEN SrvOpen = capFobx->pSrvOpen;
  104. BOOLEAN SynchronousIo =
  105. !BooleanFlagOn(RxContext->Flags,RX_CONTEXT_FLAG_ASYNC_OPERATION);
  106. PAGED_CODE();
  107. RxDbgTrace(+1, Dbg, ("MRxProxyQueryDirOrFlushContinuation\n", 0 ));
  108. ASSERT_ASYNCENG_CONTEXT(AsyncEngineContext);
  109. AsyncEngineContext->ContinueEntryCount++;
  110. ContinueEntryCount = AsyncEngineContext->ContinueEntryCount;
  111. IF_DEBUG {
  112. if (AsyncEngineContext->EntryPoint == MRXPROXY_ASYNCENG_CTX_FROM_QUERYDIR) {
  113. if (RxContext->LoudCompletionString) {
  114. PMRX_PROXY_SRV_OPEN proxySrvOpen = MRxProxyGetSrvOpenExtension(capFobx->pSrvOpen);
  115. ULONG t = InterlockedIncrement(&proxySrvOpen->NumberOfQueryDirectories);
  116. ASSERT(t==1);
  117. }
  118. }
  119. }
  120. for (;;) {
  121. //
  122. // Case on the current state
  123. //
  124. switch (AsyncEngineContext->OpSpecificState) {
  125. case MRxProxyAsyncEngOEInnerIoStates_Initial:
  126. AsyncEngineContext->OpSpecificState = MRxProxyAsyncEngOEInnerIoStates_ReadyToSend;
  127. //
  128. // If not a synchronous querydir, then continue here when resumed
  129. //
  130. //CODE.IMPROVEMENT why don't we just use the flag in the rxcontext??
  131. if (!SynchronousIo) {
  132. SetFlag(AsyncEngineContext->Flags,MRXPROXY_ASYNCENG_CTX_FLAG_ASYNC_OPERATION);
  133. }
  134. ASSERT( AsyncEngineContext->Continuation == MRxProxyQueryDirOrFlushContinuation);
  135. //lack of break is intentional
  136. case MRxProxyAsyncEngOEInnerIoStates_ReadyToSend:
  137. AsyncEngineContext->OpSpecificState = MRxProxyAsyncEngOEInnerIoStates_OperationOutstanding;
  138. Status = MRxProxyBuildAsynchronousRequest(
  139. RxContext, // IN PVOID Context
  140. MRxProxyAsyncEngineCalldownIrpCompletion // IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL,
  141. );
  142. if (Status != STATUS_SUCCESS) {
  143. goto FINALLY;
  144. }
  145. Status = MRxProxySubmitAsyncEngRequest(
  146. MRXPROXY_ASYNCENGINE_ARGUMENTS,
  147. (AsyncEngineContext->EntryPoint == MRXPROXY_ASYNCENG_CTX_FROM_QUERYDIR)
  148. ?MRXPROXY_ASYNCENG_AECTXTYPE_QUERYDIR
  149. :MRXPROXY_ASYNCENG_AECTXTYPE_FLUSH
  150. );
  151. //
  152. // If the status is PENDING, then we're done for now. We must
  153. // wait until we're re-entered when the receive happens.
  154. //
  155. if (Status==(STATUS_PENDING)) {
  156. ASSERT(FALSE); //shouldn't be coming thru here now........
  157. ASSERT(!SynchronousIo);
  158. goto FINALLY;
  159. }
  160. if ((Status!=STATUS_SUCCESS) && (RxContext->LoudCompletionString)) {
  161. DbgPrint("LoudFailure %08lx on %wZ\n",Status,RxContext->LoudCompletionString);
  162. if (MRxProxyStopOnLoudCompletion) {
  163. DbgBreakPoint();
  164. }
  165. }
  166. AsyncEngineContext->Status = Status;
  167. //lack of break is intentional
  168. case MRxProxyAsyncEngOEInnerIoStates_OperationOutstanding:
  169. AsyncEngineContext->OpSpecificState = MRxProxyAsyncEngOEInnerIoStates_ReadyToSend;
  170. Status = AsyncEngineContext->Status;
  171. //RxContext->InformationToReturn += AsyncEngineContext->Information;
  172. if (!NT_ERROR(Status)) {
  173. RxContext->Info.LengthRemaining -= AsyncEngineContext->CalldownIrp->IoStatus.Information;
  174. }
  175. goto FINALLY;
  176. break;
  177. }
  178. }
  179. FINALLY:
  180. //CODE.IMPROVEMENT QueryDirOrFlush_start and write_start and locks_start should be combined.....we use this
  181. //macro until then to keep the async stuff identical
  182. if ( Status != (STATUS_PENDING) ) {
  183. MRxProxyAsyncEngAsyncCompletionIfNecessary(AsyncEngineContext,RxContext);
  184. }
  185. RxDbgTrace(-1, Dbg, ("MRxProxyQueryDirOrFlushContinuation exit w %08lx\n", Status ));
  186. return Status;
  187. }
  188.