3 Copyright (c) 1989-2000 Microsoft Corporation
11 This module implements the main dispatch procedure/thread for the Cdfs
20 // The Bug check file id for this module
23 #define BugCheckFileId (CDFS_BUG_CHECK_FSPDISP)
28 IN PIRP_CONTEXT IrpContext
35 This is the main FSP thread routine that is executed to receive
36 and dispatch IRP requests. Each FSP thread begins its execution here.
37 There is one thread created at system initialization time and subsequent
38 threads created as needed.
42 IrpContext - IrpContext for a request to process.
51 THREAD_CONTEXT ThreadContext
;
54 PIRP Irp
= IrpContext
->Irp
;
55 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation( Irp
);
57 PVOLUME_DEVICE_OBJECT VolDo
= NULL
;
60 // If this request has an associated volume device object, remember it.
63 if (IrpSp
->FileObject
!= NULL
) {
65 VolDo
= CONTAINING_RECORD( IrpSp
->DeviceObject
,
71 // Now case on the function code. For each major function code,
72 // either call the appropriate worker routine. This routine that
73 // we call is responsible for completing the IRP, and not us.
74 // That way the routine can complete the IRP and then continue
75 // post processing as required. For example, a read can be
76 // satisfied right away and then read can be done.
78 // We'll do all of the work within an exception handler that
79 // will be invoked if ever some underlying operation gets into
86 // Set all the flags indicating we are in the Fsp.
89 SetFlag( IrpContext
->Flags
, IRP_CONTEXT_FSP_FLAGS
);
91 FsRtlEnterFileSystem();
93 CdSetThreadContext( IrpContext
, &ThreadContext
);
100 // Reinitialize for the next try at completing this
105 IrpContext
->ExceptionStatus
= STATUS_SUCCESS
;
108 // Initialize the Io status field in the Irp.
111 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
112 Irp
->IoStatus
.Information
= 0;
115 // Case on the major irp code.
118 switch (IrpContext
->MajorFunction
) {
122 CdCommonCreate( IrpContext
, Irp
);
132 CdCommonRead( IrpContext
, Irp
);
135 case IRP_MJ_QUERY_INFORMATION
:
137 CdCommonQueryInfo( IrpContext
, Irp
);
140 case IRP_MJ_SET_INFORMATION
:
142 CdCommonSetInfo( IrpContext
, Irp
);
145 case IRP_MJ_QUERY_VOLUME_INFORMATION
:
147 CdCommonQueryVolInfo( IrpContext
, Irp
);
150 case IRP_MJ_DIRECTORY_CONTROL
:
152 CdCommonDirControl( IrpContext
, Irp
);
155 case IRP_MJ_FILE_SYSTEM_CONTROL
:
157 CdCommonFsControl( IrpContext
, Irp
);
160 case IRP_MJ_DEVICE_CONTROL
:
162 CdCommonDevControl( IrpContext
, Irp
);
165 case IRP_MJ_LOCK_CONTROL
:
167 CdCommonLockControl( IrpContext
, Irp
);
170 case IRP_MJ_CLEANUP
:
172 CdCommonCleanup( IrpContext
, Irp
);
178 CdCommonPnp( IrpContext
, Irp
);
183 Status
= STATUS_INVALID_DEVICE_REQUEST
;
184 CdCompleteRequest( IrpContext
, Irp
, Status
);
187 } except( CdExceptionFilter( IrpContext
, GetExceptionInformation() )) {
189 Status
= CdProcessException( IrpContext
, Irp
, GetExceptionCode() );
193 // Break out of the loop if we didn't get CANT_WAIT.
196 if (Status
!= STATUS_CANT_WAIT
) { break; }
199 // We are retrying this request. Cleanup the IrpContext for the retry.
202 SetFlag( IrpContext
->Flags
, IRP_CONTEXT_FLAG_MORE_PROCESSING
);
203 CdCleanupIrpContext( IrpContext
, FALSE
);
206 FsRtlExitFileSystem();
209 // If there are any entries on this volume's overflow queue, service
219 // We have a volume device object so see if there is any work
220 // left to do in its overflow queue.
223 KeAcquireSpinLock( &VolDo
->OverflowQueueSpinLock
, &SavedIrql
);
225 if (VolDo
->OverflowQueueCount
> 0) {
228 // There is overflow work to do in this volume so we'll
229 // decrement the Overflow count, dequeue the IRP, and release
233 VolDo
->OverflowQueueCount
-= 1;
235 Entry
= RemoveHeadList( &VolDo
->OverflowQueue
);
238 KeReleaseSpinLock( &VolDo
->OverflowQueueSpinLock
, SavedIrql
);
241 // There wasn't an entry, break out of the loop and return to
242 // the Ex Worker thread.
245 if (Entry
== NULL
) { break; }
248 // Extract the IrpContext , Irp, set wait to TRUE, and loop.
251 IrpContext
= CONTAINING_RECORD( Entry
,
253 WorkQueueItem
.List
);
255 Irp
= IrpContext
->Irp
;
256 IrpSp
= IoGetCurrentIrpStackLocation( Irp
);
265 // Decrement the PostedRequestCount if there was a volume device object.
270 InterlockedDecrement( &VolDo
->PostedRequestCount
);