ReactOS  0.4.14-dev-606-g14ebc0b
fspdisp.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1989-2000 Microsoft Corporation
4 
5 Module Name:
6 
7  FspDisp.c
8 
9 Abstract:
10 
11  This module implements the main dispatch procedure/thread for the Cdfs
12  Fsp
13 
14 
15 --*/
16 
17 #include "cdprocs.h"
18 
19 //
20 // The Bug check file id for this module
21 //
22 
23 #define BugCheckFileId (CDFS_BUG_CHECK_FSPDISP)
24 
25 
26 VOID
27 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
30  )
31 
32 /*++
33 
34 Routine Description:
35 
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.
40 
41 Arguments:
42 
43  IrpContext - IrpContext for a request to process.
44 
45 Return Value:
46 
47  None
48 
49 --*/
50 
51 {
52  THREAD_CONTEXT ThreadContext = {0};
53  PIRP_CONTEXT IrpContext = Context;
55 
56  PIRP Irp = IrpContext->Irp;
58 
60 
61  //
62  // If this request has an associated volume device object, remember it.
63  //
64 
65  if (IrpSp->FileObject != NULL) {
66 
69  DeviceObject );
70  }
71 
72  //
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.
79  //
80  // We'll do all of the work within an exception handler that
81  // will be invoked if ever some underlying operation gets into
82  // trouble.
83  //
84 
85  while ( TRUE ) {
86 
87  //
88  // Set all the flags indicating we are in the Fsp.
89  //
90 
91  SetFlag( IrpContext->Flags, IRP_CONTEXT_FSP_FLAGS );
92 
94 
95  CdSetThreadContext( IrpContext, &ThreadContext );
96 
97  while (TRUE) {
98 
99  _SEH2_TRY {
100 
101  //
102  // Reinitialize for the next try at completing this
103  // request.
104  //
105 
106  Status =
107  IrpContext->ExceptionStatus = STATUS_SUCCESS;
108 
109  //
110  // Initialize the Io status field in the Irp.
111  //
112 
113  Irp->IoStatus.Status = STATUS_SUCCESS;
114  Irp->IoStatus.Information = 0;
115 
116  //
117  // Case on the major irp code.
118  //
119 
120  switch (IrpContext->MajorFunction) {
121 
122  case IRP_MJ_CREATE :
123 
124  CdCommonCreate( IrpContext, Irp );
125  break;
126 
127  case IRP_MJ_CLOSE :
128 
129  NT_ASSERT( FALSE );
130  break;
131 
132  case IRP_MJ_READ :
133 
134  CdCommonRead( IrpContext, Irp );
135  break;
136 
138 
139  CdCommonQueryInfo( IrpContext, Irp );
140  break;
141 
143 
144  CdCommonSetInfo( IrpContext, Irp );
145  break;
146 
148 
149  CdCommonQueryVolInfo( IrpContext, Irp );
150  break;
151 
153 
154  CdCommonDirControl( IrpContext, Irp );
155  break;
156 
158 
159  CdCommonFsControl( IrpContext, Irp );
160  break;
161 
162  case IRP_MJ_DEVICE_CONTROL :
163 
164  CdCommonDevControl( IrpContext, Irp );
165  break;
166 
167  case IRP_MJ_LOCK_CONTROL :
168 
169  CdCommonLockControl( IrpContext, Irp );
170  break;
171 
172  case IRP_MJ_CLEANUP :
173 
174  CdCommonCleanup( IrpContext, Irp );
175  break;
176 
177  case IRP_MJ_PNP :
178 
179  NT_ASSERT( FALSE );
180  CdCommonPnp( IrpContext, Irp );
181  break;
182 
183  default :
184 
186  CdCompleteRequest( IrpContext, Irp, Status );
187  }
188 
190 
191  Status = CdProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
192  } _SEH2_END;
193 
194  //
195  // Break out of the loop if we didn't get CANT_WAIT.
196  //
197 
198  if (Status != STATUS_CANT_WAIT) { break; }
199 
200  //
201  // We are retrying this request. Cleanup the IrpContext for the retry.
202  //
203 
204  SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING );
205  CdCleanupIrpContext( IrpContext, FALSE );
206  }
207 
209 
210  //
211  // If there are any entries on this volume's overflow queue, service
212  // them.
213  //
214 
215  if (VolDo != NULL) {
216 
217  KIRQL SavedIrql;
218  PVOID Entry = NULL;
219 
220  //
221  // We have a volume device object so see if there is any work
222  // left to do in its overflow queue.
223  //
224 
225  KeAcquireSpinLock( &VolDo->OverflowQueueSpinLock, &SavedIrql );
226 
227  if (VolDo->OverflowQueueCount > 0) {
228 
229  //
230  // There is overflow work to do in this volume so we'll
231  // decrement the Overflow count, dequeue the IRP, and release
232  // the Event
233  //
234 
235  VolDo->OverflowQueueCount -= 1;
236 
237  Entry = RemoveHeadList( &VolDo->OverflowQueue );
238 
239  } else {
240 
241  VolDo->PostedRequestCount -= 1;
242 
243  Entry = NULL;
244  }
245 
246  KeReleaseSpinLock( &VolDo->OverflowQueueSpinLock, SavedIrql );
247 
248  //
249  // There wasn't an entry, break out of the loop and return to
250  // the Ex Worker thread.
251  //
252 
253  if (Entry == NULL) {
254 
255  break;
256  }
257 
258  //
259  // Extract the IrpContext , Irp, set wait to TRUE, and loop.
260  //
261 
262  IrpContext = CONTAINING_RECORD( Entry,
263  IRP_CONTEXT,
264  WorkQueueItem.List );
265 
266  Irp = IrpContext->Irp;
268  __analysis_assert( IrpSp != 0 );
269 
270  continue;
271  }
272 
273  break;
274  }
275 
276  return;
277 }
278 
279 
280 
281 
VOID CdSetThreadContext(_Inout_ PIRP_CONTEXT IrpContext, _In_ PTHREAD_CONTEXT ThreadContext)
Definition: cddata.c:981
#define TRUE
Definition: types.h:120
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define FsRtlEnterFileSystem
PIRP Irp
Definition: usbstor.h:298
#define FsRtlExitFileSystem
_In_ PIRP Irp
Definition: csq.h:116
#define IRP_CONTEXT_FLAG_MORE_PROCESSING
Definition: cdstruc.h:1220
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_SEH2_TRY
Definition: create.c:4250
ULONG OverflowQueueCount
Definition: cdstruc.h:752
UCHAR KIRQL
Definition: env_spec_w32.h:591
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
VOID CdCompleteRequest(_Inout_opt_ PIRP_CONTEXT IrpContext, _Inout_opt_ PIRP Irp, _In_ NTSTATUS Status)
Definition: cddata.c:914
#define IRP_CONTEXT_FSP_FLAGS
Definition: cdstruc.h:1267
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
smooth NULL
Definition: ftsmooth.c:416
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
VOID NTAPI CdFspDispatch(_In_ PVOID Context)
Definition: fspdisp.c:28
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2867
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
NTSTATUS CdCommonDevControl(_Inout_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
Definition: devctrl.c:46
Status
Definition: gdiplustypes.h:24
#define _In_
Definition: no_sal2.h:204
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
_SEH2_END
Definition: create.c:4424
LONG CdExceptionFilter(_Inout_ PIRP_CONTEXT IrpContext, _In_ PEXCEPTION_POINTERS ExceptionPointer)
Definition: cddata.c:525
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
__volatile LONG PostedRequestCount
Definition: cdstruc.h:745
VOID CdCleanupIrpContext(_In_ PIRP_CONTEXT IrpContext, _In_ BOOLEAN Post)
Definition: strucsup.c:1733
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
NTSTATUS CdCommonLockControl(_Inout_ PIRP_CONTEXT IrpContext, _Inout_ PIRP Irp)
Definition: lockctrl.c:35
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_CLEANUP
struct tagContext Context
Definition: acpixf.h:1030
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
KSPIN_LOCK OverflowQueueSpinLock
Definition: cdstruc.h:766
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
return STATUS_SUCCESS
Definition: btrfs.c:2938
LIST_ENTRY OverflowQueue
Definition: cdstruc.h:760
base of all file and directory entries
Definition: entries.h:82
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define STATUS_CANT_WAIT
Definition: ntstatus.h:438
#define NT_ASSERT
Definition: rtlfuncs.h:3312