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.

254 lines
7.4 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: FSPDISP.C
  4. //
  5. // Contents: This module implements the main dispatch procedure
  6. // for the Dsfs FSP.
  7. //
  8. // Functions: DfsFsdPostRequest - post an IRP request to the FSP
  9. // DfsFspDispatch - Dispatch IRP requests from FSP thread
  10. //
  11. // History: 12 Nov 1991 AlanW Created from CDFS souce.
  12. // 25 Apr 1993 Alanw Updated to use Ex worker threads
  13. //
  14. //-----------------------------------------------------------------------------
  15. #include "dfsprocs.h"
  16. #include "dnr.h"
  17. //
  18. // Define our local debug trace level
  19. //
  20. #define Dbg (DEBUG_TRACE_FSP_DISPATCHER)
  21. #ifdef ALLOC_PRAGMA
  22. #pragma alloc_text( PAGE, DfsFspDispatch )
  23. //
  24. // DfsFsdPostRequest cannot be paged since it is called from
  25. // DnrCompleteFileOpen
  26. //
  27. // DfsFsdPostRequest
  28. //
  29. #endif // ALLOC_PRAGMA
  30. //+-------------------------------------------------------------------
  31. //
  32. // Function: DfsFsdPostRequest, public
  33. //
  34. // Synopsis: This routine enqueues the request packet specified by
  35. // IrpContext to the work queue associated with the
  36. // FileSysDeviceObject. This is a FSD routine.
  37. //
  38. // Arguments: [IrpContext] -- Pointer to the IrpContext to be queued to
  39. // the Fsp
  40. // [Irp] -- I/O Request Packet, or NULL if it has already been
  41. // completed.
  42. //
  43. // Returns: STATUS_PENDING
  44. //
  45. //--------------------------------------------------------------------
  46. NTSTATUS
  47. DfsFsdPostRequest(
  48. IN PIRP_CONTEXT IrpContext,
  49. IN PIRP Irp
  50. ) {
  51. DfsDbgTrace(0, Dbg, "DfsFsdPostRequest: Irp = %08lx\n", Irp);
  52. ASSERT( ARGUMENT_PRESENT(Irp) &&
  53. IrpContext->OriginatingIrp == Irp );
  54. //
  55. // Verify our assumptions about not needing DfsPrePostIrp processing.
  56. //
  57. ASSERT((IrpContext->MajorFunction != IRP_MJ_READ) &&
  58. (IrpContext->MajorFunction != IRP_MJ_WRITE) &&
  59. (IrpContext->MajorFunction != IRP_MJ_DIRECTORY_CONTROL) &&
  60. (IrpContext->MajorFunction != IRP_MJ_QUERY_EA) &&
  61. (IrpContext->MajorFunction != IRP_MJ_SET_EA));
  62. //
  63. // Mark that we've already returned pending to the user
  64. //
  65. IoMarkIrpPending( Irp );
  66. //
  67. // Send the IRP_CONTEXT off to an Ex worker thread.
  68. //
  69. ExInitializeWorkItem( &IrpContext->WorkQueueItem,
  70. DfsFspDispatch,
  71. IrpContext );
  72. ExQueueWorkItem( &IrpContext->WorkQueueItem, CriticalWorkQueue );
  73. //
  74. // And return to our caller
  75. //
  76. return STATUS_PENDING;
  77. }
  78. //+-------------------------------------------------------------------
  79. //
  80. // Function: DfsFspDispatch, public
  81. //
  82. // Synopsis: This is the main FSP thread routine that is executed to receive
  83. // and dispatch IRP requests. Each FSP requst begins its
  84. // execution here.
  85. //
  86. // Arguments: [Context] -- Supplies a pointer to a DFS IRP context record.
  87. //
  88. // Returns: Nonthing
  89. //
  90. // Notes:
  91. //
  92. //--------------------------------------------------------------------
  93. VOID
  94. DfsFspDispatch (
  95. IN PVOID Context
  96. ) {
  97. // PFS_DEVICE_OBJECT FileSysDeviceObject = Context;
  98. PIRP Irp;
  99. PIRP_CONTEXT IrpContext = Context;
  100. Irp = IrpContext->OriginatingIrp;
  101. //
  102. // Now because we are the Fsp we will force the IrpContext to
  103. // indicate true on Wait.
  104. //
  105. IrpContext->Flags |= IRP_CONTEXT_FLAG_WAIT;
  106. IrpContext->Flags &= ~IRP_CONTEXT_FLAG_IN_FSD;
  107. //
  108. // Now we'll loop forever, reading a new IRP request and dispatching
  109. // on the IRP function
  110. //
  111. while (TRUE) {
  112. DfsDbgTrace(0, Dbg, "DfsFspDispatch: Irp = %08lx\n", Irp);
  113. ASSERT (Irp != NULL && Irp->IoStatus.Status != STATUS_VERIFY_REQUIRED);
  114. //
  115. // Now case on the function code. For each major function code,
  116. // either call the appropriate FSP routine or case on the minor
  117. // function and then call the FSP routine. The FSP routine that
  118. // we call is responsible for completing the IRP, and not us.
  119. // That way the routine can complete the IRP and then continue
  120. // post processing as required. For example, a read can be
  121. // satisfied right away and then read-ahead can be done.
  122. //
  123. // We'll do all of the work within an exception handler that
  124. // will be invoked if ever some underlying operation gets into
  125. // trouble.
  126. //
  127. FsRtlEnterFileSystem();
  128. try {
  129. switch (IrpContext->MajorFunction) {
  130. //
  131. // For Create/Open operations, we post a workitem only
  132. // to resume DNR after a call to IoCallDriver.
  133. //
  134. //
  135. case IRP_MJ_CREATE:
  136. case IRP_MJ_CREATE_NAMED_PIPE:
  137. case IRP_MJ_CREATE_MAILSLOT:
  138. ASSERT(IrpContext->Context != NULL);
  139. ASSERT( ((PDNR_CONTEXT)IrpContext->Context)->NodeTypeCode ==
  140. DSFS_NTC_DNR_CONTEXT );
  141. DnrNameResolve( (PDNR_CONTEXT)IrpContext->Context );
  142. PsAssignImpersonationToken(PsGetCurrentThread(),NULL);
  143. break;
  144. //
  145. // For close operations
  146. //
  147. case IRP_MJ_CLOSE:
  148. DfsFspClose( IrpContext, Irp );
  149. break;
  150. //
  151. // For Set Information operations,
  152. //
  153. case IRP_MJ_SET_INFORMATION:
  154. DfsFspSetInformation( IrpContext, Irp );
  155. break;
  156. //
  157. // For Query Volume Information operations,
  158. //
  159. case IRP_MJ_QUERY_VOLUME_INFORMATION:
  160. DfsFspQueryVolumeInformation( IrpContext, Irp );
  161. break;
  162. //
  163. // For Set Volume Information operations,
  164. //
  165. case IRP_MJ_SET_VOLUME_INFORMATION:
  166. DfsFspSetVolumeInformation( IrpContext, Irp );
  167. break;
  168. //
  169. // For File System Control operations,
  170. //
  171. case IRP_MJ_FILE_SYSTEM_CONTROL:
  172. DfsFspFileSystemControl( IrpContext, Irp );
  173. break;
  174. //
  175. // For any other major operations, return an invalid
  176. // request.
  177. //
  178. default:
  179. DfsDbgTrace(0, Dbg, "DfsFspDispatch: Unhandled request, MajorFunction = %08lx\n", IrpContext->MajorFunction);
  180. DfsCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST );
  181. break;
  182. }
  183. } except( DfsExceptionFilter( IrpContext, GetExceptionCode(), GetExceptionInformation() )) {
  184. DfsProcessException( IrpContext, Irp, GetExceptionCode() );
  185. }
  186. FsRtlExitFileSystem();
  187. //
  188. // NOTE: If we were to process an overflow device queue, we would
  189. // do it here. Instead, we'll just return to the worker
  190. // thread.
  191. //
  192. break;
  193. }
  194. return;
  195. }