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

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
FspDisp.c
Abstract:
This module implements the main dispatch procedure/thread for the NetWare
Fsp
Author:
Colin Watson [ColinW] 15-Dec-1992
Revision History:
--*/
#include "Procs.h"
//
// Define our local debug trace level
//
#define Dbg (DEBUG_TRACE_FSP_DISPATCHER)
#ifdef ALLOC_PRAGMA
#pragma alloc_text( PAGE, NwFspDispatch )
#endif
#if 0 // Not pageable
NwPostToFsp
#endif
VOID
NwFspDispatch (
IN PVOID Context
)
/*++
Routine Description:
This is the main FSP thread routine that is executed to receive
and dispatch IRP requests. Each FSP thread begins its execution here.
There is one thread created at system initialization time and subsequent
threads created as needed.
Arguments:
Context - Supplies the thread id.
Return Value:
None - This routine never exits
--*/
{
PIRP Irp;
PIRP_CONTEXT IrpContext;
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
PPOST_PROCESSOR PostProcessRoutine;
BOOLEAN TopLevel;
IrpContext = (PIRP_CONTEXT)Context;
Irp = IrpContext->pOriginalIrp;
ClearFlag( IrpContext->Flags, IRP_FLAG_IN_FSD );
//
// Now case on the function code. For each major function code,
// either call the appropriate FSP routine or case on the minor
// function and then call the FSP routine. The FSP routine that
// we call is responsible for completing the IRP, and not us.
// That way the routine can complete the IRP and then continue
// post processing as required. For example, a read can be
// satisfied right away and then read can be done.
//
// We'll do all of the work within an exception handler that
// will be invoked if ever some underlying operation gets into
// trouble (e.g., if NwReadSectorsSync has trouble).
//
DebugTrace(0, Dbg, "NwFspDispatch: Irp = 0x%08lx\n", Irp);
FsRtlEnterFileSystem();
TopLevel = NwIsIrpTopLevel( Irp );
try {
//
// If we have a run routine for this IRP context, then run it,
// if not fall through to the IRP handler.
//
if ( IrpContext->PostProcessRoutine != NULL ) {
PostProcessRoutine = IrpContext->PostProcessRoutine;
//
// Clear the run routine so that we don't run it again.
//
IrpContext->PostProcessRoutine = NULL;
Status = PostProcessRoutine( IrpContext );
} else {
IrpSp = IoGetCurrentIrpStackLocation( Irp );
switch ( IrpSp->MajorFunction ) {
//
// For File System Control operations,
//
case IRP_MJ_FILE_SYSTEM_CONTROL:
Status = NwCommonFileSystemControl( IrpContext );
break;
//
// For any other major operations, return an invalid
// request.
//
default:
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
}
//
// We're done with this request. Dequeue the IRP context from
// SCB and complete the request.
//
if ( Status != STATUS_PENDING ) {
NwDequeueIrpContext( IrpContext, FALSE );
}
NwCompleteRequest( IrpContext, Status );
} except(NwExceptionFilter( Irp, GetExceptionInformation() )) {
//
// We had some trouble trying to perform the requested
// operation, so we'll abort the I/O request with
// the error status that we get back from the
// execption code.
//
(VOID) NwProcessException( IrpContext, GetExceptionCode() );
}
if ( TopLevel ) {
NwSetTopLevelIrp( NULL );
}
FsRtlExitFileSystem();
return;
}
NTSTATUS
NwPostToFsp (
IN PIRP_CONTEXT IrpContext,
IN BOOLEAN MarkIrpPending
)
/*++
Routine Description:
This routine post an IRP context to an executive worker thread
for FSP level processing.
*** WARNING: After calling this routine, the caller may no
longer access IrpContext. This routine passes
the IrpContext to the FSP which may run and free
the IrpContext before this routine returns to the
caller.
Arguments:
IrpContext - Supplies the Irp being processed.
MarkIrpPending - If true, mark the IRP pending.
Return Value:
STATUS_PENDING.
--*/
{
PIRP Irp = IrpContext->pOriginalIrp;
DebugTrace(0, Dbg, "NwPostToFsp: IrpContext = %X\n", IrpContext );
DebugTrace(0, Dbg, "PostProcessRoutine = %X\n", IrpContext->PostProcessRoutine );
if ( MarkIrpPending ) {
//
// Mark this I/O request as being pending.
//
IoMarkIrpPending( Irp );
}
//
// Queue to IRP context to an ex worker thread.
//
ExInitializeWorkItem( &IrpContext->WorkQueueItem, NwFspDispatch, IrpContext );
ExQueueWorkItem( &IrpContext->WorkQueueItem, DelayedWorkQueue );
return( STATUS_PENDING );
}