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 );
|
||
}
|
||
|