diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/cdfs/fspdisp.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/ntos/cdfs/fspdisp.c')
-rw-r--r-- | private/ntos/cdfs/fspdisp.c | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/private/ntos/cdfs/fspdisp.c b/private/ntos/cdfs/fspdisp.c new file mode 100644 index 000000000..09a563eb4 --- /dev/null +++ b/private/ntos/cdfs/fspdisp.c @@ -0,0 +1,280 @@ +/*++ + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + FspDisp.c + +Abstract: + + This module implements the main dispatch procedure/thread for the Cdfs + Fsp + +Author: + + Brian Andrew [BrianAn] 02-Jan-1991 + +Revision History: + +--*/ + +#include "CdProcs.h" + +// +// The Bug check file id for this module +// + +#define BugCheckFileId (CDFS_BUG_CHECK_FSPDISP) + +#ifdef ALLOC_PRAGMA +#pragma alloc_text(PAGE, CdFspDispatch) +#endif + + +VOID +CdFspDispatch ( + IN PIRP_CONTEXT IrpContext + ) + +/*++ + +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: + + IrpContext - IrpContext for a request to process. + +Return Value: + + None + +--*/ + +{ + THREAD_CONTEXT ThreadContext; + NTSTATUS Status; + + PIRP Irp = IrpContext->Irp; + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); + + PVOLUME_DEVICE_OBJECT VolDo = NULL; + + // + // If this request has an associated volume device object, remember it. + // + + if (IrpSp->FileObject != NULL) { + + VolDo = CONTAINING_RECORD( IrpSp->DeviceObject, + VOLUME_DEVICE_OBJECT, + DeviceObject ); + } + + // + // Now case on the function code. For each major function code, + // either call the appropriate worker routine. This 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. + // + + while ( TRUE ) { + + // + // Set all the flags indicating we are in the Fsp. + // + + SetFlag( IrpContext->Flags, IRP_CONTEXT_FSP_FLAGS ); + + FsRtlEnterFileSystem(); + + CdSetThreadContext( IrpContext, &ThreadContext ); + + while (TRUE) { + + try { + + // + // Reinitialize for the next try at completing this + // request. + // + + Status = + IrpContext->ExceptionStatus = STATUS_SUCCESS; + + // + // Initialize the Io status field in the Irp. + // + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + + // + // Case on the major irp code. + // + + switch (IrpContext->MajorFunction) { + + case IRP_MJ_CREATE : + + CdCommonCreate( IrpContext, Irp ); + break; + + case IRP_MJ_CLOSE : + + ASSERT( FALSE ); + break; + + case IRP_MJ_READ : + + CdCommonRead( IrpContext, Irp ); + break; + + case IRP_MJ_QUERY_INFORMATION : + + CdCommonQueryInfo( IrpContext, Irp ); + break; + + case IRP_MJ_SET_INFORMATION : + + CdCommonQueryInfo( IrpContext, Irp ); + break; + + case IRP_MJ_QUERY_VOLUME_INFORMATION : + + CdCommonQueryVolInfo( IrpContext, Irp ); + break; + + case IRP_MJ_DIRECTORY_CONTROL : + + CdCommonDirControl( IrpContext, Irp ); + break; + + case IRP_MJ_FILE_SYSTEM_CONTROL : + + CdCommonFsControl( IrpContext, Irp ); + break; + + case IRP_MJ_DEVICE_CONTROL : + + CdCommonDevControl( IrpContext, Irp ); + break; + + case IRP_MJ_LOCK_CONTROL : + + CdCommonLockControl( IrpContext, Irp ); + break; + + case IRP_MJ_CLEANUP : + + CdCommonCleanup( IrpContext, Irp ); + break; + + default : + + Status = STATUS_INVALID_DEVICE_REQUEST; + CdCompleteRequest( IrpContext, Irp, Status ); + } + + } except( CdExceptionFilter( IrpContext, GetExceptionInformation() )) { + + Status = CdProcessException( IrpContext, Irp, GetExceptionCode() ); + } + + // + // Break out of the loop if we didn't get CANT_WAIT. + // + + if (Status != STATUS_CANT_WAIT) { break; } + + // + // We are retrying this request. Cleanup the IrpContext for the retry. + // + + SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING ); + CdCleanupIrpContext( IrpContext, FALSE ); + } + + FsRtlExitFileSystem(); + + // + // If there are any entries on this volume's overflow queue, service + // them. + // + + if (VolDo != NULL) { + + KIRQL SavedIrql; + PVOID Entry = NULL; + + // + // We have a volume device object so see if there is any work + // left to do in its overflow queue. + // + + KeAcquireSpinLock( &VolDo->OverflowQueueSpinLock, &SavedIrql ); + + if (VolDo->OverflowQueueCount > 0) { + + // + // There is overflow work to do in this volume so we'll + // decrement the Overflow count, dequeue the IRP, and release + // the Event + // + + VolDo->OverflowQueueCount -= 1; + + Entry = RemoveHeadList( &VolDo->OverflowQueue ); + } + + KeReleaseSpinLock( &VolDo->OverflowQueueSpinLock, SavedIrql ); + + // + // There wasn't an entry, break out of the loop and return to + // the Ex Worker thread. + // + + if (Entry == NULL) { break; } + + // + // Extract the IrpContext , Irp, set wait to TRUE, and loop. + // + + IrpContext = CONTAINING_RECORD( Entry, + IRP_CONTEXT, + WorkQueueItem.List ); + + Irp = IrpContext->Irp; + IrpSp = IoGetCurrentIrpStackLocation( Irp ); + + continue; + } + + break; + } + + // + // Decrement the PostedRequestCount if there was a volume device object. + // + + if (VolDo) { + + InterlockedDecrement( &VolDo->PostedRequestCount ); + } + + return; +} + + + |