233 lines
5.1 KiB
C
233 lines
5.1 KiB
C
|
/*++
|
|||
|
|
|||
|
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 );
|
|||
|
}
|
|||
|
|