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.

232 lines
5.1 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. FspDisp.c
  5. Abstract:
  6. This module implements the main dispatch procedure/thread for the NetWare
  7. Fsp
  8. Author:
  9. Colin Watson [ColinW] 15-Dec-1992
  10. Revision History:
  11. --*/
  12. #include "Procs.h"
  13. //
  14. // Define our local debug trace level
  15. //
  16. #define Dbg (DEBUG_TRACE_FSP_DISPATCHER)
  17. #ifdef ALLOC_PRAGMA
  18. #pragma alloc_text( PAGE, NwFspDispatch )
  19. #endif
  20. #if 0 // Not pageable
  21. NwPostToFsp
  22. #endif
  23. VOID
  24. NwFspDispatch (
  25. IN PVOID Context
  26. )
  27. /*++
  28. Routine Description:
  29. This is the main FSP thread routine that is executed to receive
  30. and dispatch IRP requests. Each FSP thread begins its execution here.
  31. There is one thread created at system initialization time and subsequent
  32. threads created as needed.
  33. Arguments:
  34. Context - Supplies the thread id.
  35. Return Value:
  36. None - This routine never exits
  37. --*/
  38. {
  39. PIRP Irp;
  40. PIRP_CONTEXT IrpContext;
  41. PIO_STACK_LOCATION IrpSp;
  42. NTSTATUS Status;
  43. PPOST_PROCESSOR PostProcessRoutine;
  44. BOOLEAN TopLevel;
  45. IrpContext = (PIRP_CONTEXT)Context;
  46. Irp = IrpContext->pOriginalIrp;
  47. ClearFlag( IrpContext->Flags, IRP_FLAG_IN_FSD );
  48. //
  49. // Now case on the function code. For each major function code,
  50. // either call the appropriate FSP routine or case on the minor
  51. // function and then call the FSP routine. The FSP routine that
  52. // we call is responsible for completing the IRP, and not us.
  53. // That way the routine can complete the IRP and then continue
  54. // post processing as required. For example, a read can be
  55. // satisfied right away and then read can be done.
  56. //
  57. // We'll do all of the work within an exception handler that
  58. // will be invoked if ever some underlying operation gets into
  59. // trouble (e.g., if NwReadSectorsSync has trouble).
  60. //
  61. DebugTrace(0, Dbg, "NwFspDispatch: Irp = 0x%08lx\n", Irp);
  62. FsRtlEnterFileSystem();
  63. TopLevel = NwIsIrpTopLevel( Irp );
  64. try {
  65. //
  66. // If we have a run routine for this IRP context, then run it,
  67. // if not fall through to the IRP handler.
  68. //
  69. if ( IrpContext->PostProcessRoutine != NULL ) {
  70. PostProcessRoutine = IrpContext->PostProcessRoutine;
  71. //
  72. // Clear the run routine so that we don't run it again.
  73. //
  74. IrpContext->PostProcessRoutine = NULL;
  75. Status = PostProcessRoutine( IrpContext );
  76. } else {
  77. IrpSp = IoGetCurrentIrpStackLocation( Irp );
  78. switch ( IrpSp->MajorFunction ) {
  79. //
  80. // For File System Control operations,
  81. //
  82. case IRP_MJ_FILE_SYSTEM_CONTROL:
  83. Status = NwCommonFileSystemControl( IrpContext );
  84. break;
  85. //
  86. // For any other major operations, return an invalid
  87. // request.
  88. //
  89. default:
  90. Status = STATUS_INVALID_DEVICE_REQUEST;
  91. break;
  92. }
  93. }
  94. //
  95. // We're done with this request. Dequeue the IRP context from
  96. // SCB and complete the request.
  97. //
  98. if ( Status != STATUS_PENDING ) {
  99. NwDequeueIrpContext( IrpContext, FALSE );
  100. }
  101. NwCompleteRequest( IrpContext, Status );
  102. } except(NwExceptionFilter( Irp, GetExceptionInformation() )) {
  103. //
  104. // We had some trouble trying to perform the requested
  105. // operation, so we'll abort the I/O request with
  106. // the error status that we get back from the
  107. // execption code.
  108. //
  109. (VOID) NwProcessException( IrpContext, GetExceptionCode() );
  110. }
  111. if ( TopLevel ) {
  112. NwSetTopLevelIrp( NULL );
  113. }
  114. FsRtlExitFileSystem();
  115. return;
  116. }
  117. NTSTATUS
  118. NwPostToFsp (
  119. IN PIRP_CONTEXT IrpContext,
  120. IN BOOLEAN MarkIrpPending
  121. )
  122. /*++
  123. Routine Description:
  124. This routine post an IRP context to an executive worker thread
  125. for FSP level processing.
  126. *** WARNING: After calling this routine, the caller may no
  127. longer access IrpContext. This routine passes
  128. the IrpContext to the FSP which may run and free
  129. the IrpContext before this routine returns to the
  130. caller.
  131. Arguments:
  132. IrpContext - Supplies the Irp being processed.
  133. MarkIrpPending - If true, mark the IRP pending.
  134. Return Value:
  135. STATUS_PENDING.
  136. --*/
  137. {
  138. PIRP Irp = IrpContext->pOriginalIrp;
  139. DebugTrace(0, Dbg, "NwPostToFsp: IrpContext = %X\n", IrpContext );
  140. DebugTrace(0, Dbg, "PostProcessRoutine = %X\n", IrpContext->PostProcessRoutine );
  141. if ( MarkIrpPending ) {
  142. //
  143. // Mark this I/O request as being pending.
  144. //
  145. IoMarkIrpPending( Irp );
  146. }
  147. //
  148. // Queue to IRP context to an ex worker thread.
  149. //
  150. ExInitializeWorkItem( &IrpContext->WorkQueueItem, NwFspDispatch, IrpContext );
  151. ExQueueWorkItem( &IrpContext->WorkQueueItem, DelayedWorkQueue );
  152. return( STATUS_PENDING );
  153. }