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)
27 NTAPI
/* ReactOS Change: GCC Does not support STDCALL by default */
36 This is the main FSP thread routine that is executed to receive
37 and dispatch IRP requests. Each FSP thread begins its execution here.
38 There is one thread created at system initialization time and subsequent
39 threads created as needed.
43 IrpContext - IrpContext for a request to process.
52 THREAD_CONTEXT ThreadContext
= {0};
53 PIRP_CONTEXT IrpContext
= Context
;
56 PIRP Irp
= IrpContext
->Irp
;
57 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation( Irp
);
59 PVOLUME_DEVICE_OBJECT VolDo
= NULL
;
62 // If this request has an associated volume device object, remember it.
65 if (IrpSp
->FileObject
!= NULL
) {
67 VolDo
= CONTAINING_RECORD( IrpSp
->DeviceObject
,
73 // Now case on the function code. For each major function code,
74 // either call the appropriate worker routine. This routine that
75 // we call is responsible for completing the IRP, and not us.
76 // That way the routine can complete the IRP and then continue
77 // post processing as required. For example, a read can be
78 // satisfied right away and then read can be done.
80 // We'll do all of the work within an exception handler that
81 // will be invoked if ever some underlying operation gets into
88 // Set all the flags indicating we are in the Fsp.
91 SetFlag( IrpContext
->Flags
, IRP_CONTEXT_FSP_FLAGS
);
93 FsRtlEnterFileSystem();
95 CdSetThreadContext( IrpContext
, &ThreadContext
);
102 // Reinitialize for the next try at completing this
107 IrpContext
->ExceptionStatus
= STATUS_SUCCESS
;
110 // Initialize the Io status field in the Irp.
113 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
114 Irp
->IoStatus
.Information
= 0;
117 // Case on the major irp code.
120 switch (IrpContext
->MajorFunction
) {
124 CdCommonCreate( IrpContext
, Irp
);
134 CdCommonRead( IrpContext
, Irp
);
137 case IRP_MJ_QUERY_INFORMATION
:
139 CdCommonQueryInfo( IrpContext
, Irp
);
142 case IRP_MJ_SET_INFORMATION
:
144 CdCommonSetInfo( IrpContext
, Irp
);
147 case IRP_MJ_QUERY_VOLUME_INFORMATION
:
149 CdCommonQueryVolInfo( IrpContext
, Irp
);
152 case IRP_MJ_DIRECTORY_CONTROL
:
154 CdCommonDirControl( IrpContext
, Irp
);
157 case IRP_MJ_FILE_SYSTEM_CONTROL
:
159 CdCommonFsControl( IrpContext
, Irp
);
162 case IRP_MJ_DEVICE_CONTROL
:
164 CdCommonDevControl( IrpContext
, Irp
);
167 case IRP_MJ_LOCK_CONTROL
:
169 CdCommonLockControl( IrpContext
, Irp
);
172 case IRP_MJ_CLEANUP
:
174 CdCommonCleanup( IrpContext
, Irp
);
180 CdCommonPnp( IrpContext
, Irp
);
185 Status
= STATUS_INVALID_DEVICE_REQUEST
;
186 CdCompleteRequest( IrpContext
, Irp
, Status
);
189 } _SEH2_EXCEPT( CdExceptionFilter( IrpContext
, _SEH2_GetExceptionInformation() )) {
191 Status
= CdProcessException( IrpContext
, Irp
, _SEH2_GetExceptionCode() );
195 // Break out of the loop if we didn't get CANT_WAIT.
198 if (Status
!= STATUS_CANT_WAIT
) { break; }
201 // We are retrying this request. Cleanup the IrpContext for the retry.
204 SetFlag( IrpContext
->Flags
, IRP_CONTEXT_FLAG_MORE_PROCESSING
);
205 CdCleanupIrpContext( IrpContext
, FALSE
);
208 FsRtlExitFileSystem();
211 // If there are any entries on this volume's overflow queue, service
221 // We have a volume device object so see if there is any work
222 // left to do in its overflow queue.
225 KeAcquireSpinLock( &VolDo
->OverflowQueueSpinLock
, &SavedIrql
);
227 if (VolDo
->OverflowQueueCount
> 0) {
230 // There is overflow work to do in this volume so we'll
231 // decrement the Overflow count, dequeue the IRP, and release
235 VolDo
->OverflowQueueCount
-= 1;
237 Entry
= RemoveHeadList( &VolDo
->OverflowQueue
);
241 VolDo
->PostedRequestCount
-= 1;
246 KeReleaseSpinLock( &VolDo
->OverflowQueueSpinLock
, SavedIrql
);
249 // There wasn't an entry, break out of the loop and return to
250 // the Ex Worker thread.
259 // Extract the IrpContext , Irp, set wait to TRUE, and loop.
262 IrpContext
= CONTAINING_RECORD( Entry
,
264 WorkQueueItem
.List
);
266 Irp
= IrpContext
->Irp
;
267 IrpSp
= IoGetCurrentIrpStackLocation( Irp
);
268 __analysis_assert( IrpSp
!= 0 );