ReactOS 0.4.15-dev-5893-g1bb4167
dispatch.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYRIGHT.TXT
3 * PROJECT: Ext2 File System Driver for WinNT/2K/XP
4 * FILE: dispatch.c
5 * PROGRAMMER: Matt Wu <mattwu@163.com>
6 * HOMEPAGE: http://www.ext2fsd.com
7 * UPDATE HISTORY:
8 */
9
10/* INCLUDES *****************************************************************/
11
12#include "ext2fs.h"
13
14/* GLOBALS ***************************************************************/
15
17
18/* DEFINITIONS *************************************************************/
19
20#ifdef ALLOC_PRAGMA
21#pragma alloc_text(PAGE, Ext2QueueRequest)
22#pragma alloc_text(PAGE, Ext2DeQueueRequest)
23#endif
24
25/*
26 * Ext2OplockComplete
27 *
28 * callback routine of FsRtlCheckOplock when an oplock break has
29 * completed, allowing an Irp to resume execution.
30 *
31 * Arguments:
32 *
33 * Context: the IrpContext to be queued
34 * Irp: the I/O request packet
35 *
36 * Return Value:
37 * N/A
38 */
39
43 IN PIRP Irp
44)
45{
46 //
47 // Check on the return value in the Irp.
48 //
49
50 if (Irp->IoStatus.Status == STATUS_SUCCESS) {
51
52 //
53 // queue the Irp context in the workqueue.
54 //
55
57
58 } else {
59
60 //
61 // complete the request in case of failure
62 //
63
65 Irp->IoStatus.Status );
66 }
67
68 return;
69}
70
71
72/*
73 * Ext2LockIrp
74 *
75 * performs buffer locking if we need pend the process of the Irp
76 *
77 * Arguments:
78 * Context: the irp context
79 * Irp: the I/O request packet.
80 *
81 * Return Value:
82 * N/A
83 */
84
88 IN PIRP Irp
89)
90{
92 PEXT2_IRP_CONTEXT IrpContext;
93
94 if (Irp == NULL) {
95 return;
96 }
97
99
100 IrpContext = (PEXT2_IRP_CONTEXT) Context;
101
102 if ( IrpContext->MajorFunction == IRP_MJ_READ ||
103 IrpContext->MajorFunction == IRP_MJ_WRITE ) {
104
105 //
106 // lock the user's buffer to MDL, if the I/O is bufferred
107 //
108
109 if (!IsFlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {
110
111 Ext2LockUserBuffer( Irp, IrpSp->Parameters.Write.Length,
112 (IrpContext->MajorFunction == IRP_MJ_READ) ?
114 }
115
116 } else if (IrpContext->MajorFunction == IRP_MJ_DIRECTORY_CONTROL
117 && IrpContext->MinorFunction == IRP_MN_QUERY_DIRECTORY) {
118
119 ULONG Length = ((PEXTENDED_IO_STACK_LOCATION) IrpSp)->Parameters.QueryDirectory.Length;
121
122 } else if (IrpContext->MajorFunction == IRP_MJ_QUERY_EA) {
123
124 ULONG Length = ((PEXTENDED_IO_STACK_LOCATION) IrpSp)->Parameters.QueryEa.Length;
126
127 } else if (IrpContext->MajorFunction == IRP_MJ_SET_EA) {
128 ULONG Length = ((PEXTENDED_IO_STACK_LOCATION) IrpSp)->Parameters.SetEa.Length;
130
131 } else if ( (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) &&
132 (IrpContext->MinorFunction == IRP_MN_USER_FS_REQUEST) ) {
134 if ( (EIrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_GET_VOLUME_BITMAP) ||
135 (EIrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_GET_RETRIEVAL_POINTERS) ||
136 (EIrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_GET_RETRIEVAL_POINTER_BASE) ) {
137 ULONG Length = EIrpSp->Parameters.FileSystemControl.OutputBufferLength;
139 }
140 }
141
142 // Mark the request as pending status
143
145
146 return;
147}
148
151{
152 ASSERT(IrpContext);
153
154 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
155 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
156
157 /* set the flags of "can wait" and "queued" */
158 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
159 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);
160
161 /* make sure the buffer is kept valid in system context */
162 Ext2LockIrp(IrpContext, IrpContext->Irp);
163
164 /* initialize workite*/
166 &IrpContext->WorkQueueItem,
168 IrpContext );
169
170 /* dispatch it */
171 ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
172
173 return STATUS_PENDING;
174}
175
176
179{
180 PEXT2_IRP_CONTEXT IrpContext;
181
182 IrpContext = (PEXT2_IRP_CONTEXT) Context;
183
184 ASSERT(IrpContext);
185
186 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
187 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
188
189 _SEH2_TRY {
190
191 _SEH2_TRY {
192
194
195 if (!IrpContext->IsTopLevel) {
197 }
198
199 Ext2DispatchRequest(IrpContext);
200
202
203 Ext2ExceptionHandler(IrpContext);
204 } _SEH2_END;
205
206 } _SEH2_FINALLY {
207
209
211 } _SEH2_END;
212}
213
214
217{
218 ASSERT(IrpContext);
219
220 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
221 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
222
223 switch (IrpContext->MajorFunction) {
224
225 case IRP_MJ_CREATE:
226 return Ext2Create(IrpContext);
227
228 case IRP_MJ_CLOSE:
229 return Ext2Close(IrpContext);
230
231 case IRP_MJ_READ:
232 return Ext2Read(IrpContext);
233
234 case IRP_MJ_WRITE:
235 return Ext2Write(IrpContext);
236
238 return Ext2Flush(IrpContext);
239
241 return Ext2QueryFileInformation(IrpContext);
242
244 return Ext2SetFileInformation(IrpContext);
245
247 return Ext2QueryVolumeInformation(IrpContext);
248
250 return Ext2SetVolumeInformation(IrpContext);
251
253 return Ext2DirectoryControl(IrpContext);
254
256 return Ext2FileSystemControl(IrpContext);
257
259 return Ext2DeviceControl(IrpContext);
260
262 return Ext2LockControl(IrpContext);
263
264 case IRP_MJ_CLEANUP:
265 return Ext2Cleanup(IrpContext);
266
267 case IRP_MJ_SHUTDOWN:
268 return Ext2ShutDown(IrpContext);
269
270 case IRP_MJ_QUERY_EA:
271 return Ext2QueryEa(IrpContext);
272
273 case IRP_MJ_SET_EA:
274 return Ext2SetEa(IrpContext);
275
276#if (_WIN32_WINNT >= 0x0500)
277 case IRP_MJ_PNP:
278 return Ext2Pnp(IrpContext);
279#endif //(_WIN32_WINNT >= 0x0500)
280 default:
281 DEBUG(DL_ERR, ( "Ext2DispatchRequest: Unexpected major function: %xh\n",
282 IrpContext->MajorFunction));
283
285
287 }
288}
289
290
293{
294 BOOLEAN AtIrqlPassiveLevel = FALSE;
295 BOOLEAN IsTopLevelIrp = FALSE;
296 PEXT2_IRP_CONTEXT IrpContext = NULL;
298
299 _SEH2_TRY {
300
301 _SEH2_TRY {
302
303#if EXT2_DEBUG
305#endif
306
307 AtIrqlPassiveLevel = (KeGetCurrentIrql() == PASSIVE_LEVEL);
308
309 if (AtIrqlPassiveLevel) {
311 }
312
313 if (!IoGetTopLevelIrp()) {
314 IsTopLevelIrp = TRUE;
316 }
317
319
320 if (!IrpContext) {
321
323 Irp->IoStatus.Status = Status;
324
326
327 } else {
328
329 if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
330 !AtIrqlPassiveLevel) {
331
332 DbgBreak();
333 }
334
335 Status = Ext2DispatchRequest(IrpContext);
336 }
338
339 Status = Ext2ExceptionHandler(IrpContext);
340 } _SEH2_END;
341
342 } _SEH2_FINALLY {
343
344 if (IsTopLevelIrp) {
346 }
347
348 if (AtIrqlPassiveLevel) {
350 }
351 } _SEH2_END;
352
353 return Status;
354}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DEBUG(args)
Definition: rdesktop.h:129
ARC_STATUS Ext2Close(ULONG FileId)
Definition: ext2.c:1192
ARC_STATUS Ext2Read(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: ext2.c:1240
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
PEXT2_GLOBAL Ext2Global
Definition: init.c:16
NTSTATUS Ext2QueueRequest(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: dispatch.c:150
NTSTATUS NTAPI Ext2BuildRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: dispatch.c:292
VOID NTAPI Ext2DeQueueRequest(IN PVOID Context)
Definition: dispatch.c:178
NTSTATUS Ext2DispatchRequest(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: dispatch.c:216
VOID NTAPI Ext2OplockComplete(IN PVOID Context, IN PIRP Irp)
Definition: dispatch.c:41
VOID NTAPI Ext2LockIrp(IN PVOID Context, IN PIRP Irp)
Definition: dispatch.c:86
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
NTSTATUS Ext2ExceptionHandler(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: except.c:112
NTSTATUS Ext2QueryEa(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: ea.c:94
NTSTATUS Ext2Pnp(IN PEXT2_IRP_CONTEXT IrpContext)
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
NTSTATUS Ext2ExceptionFilter(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: except.c:21
NTSTATUS Ext2Flush(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: flush.c:144
NTSTATUS Ext2ShutDown(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: shutdown.c:25
PEXT2_IRP_CONTEXT Ext2AllocateIrpContext(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: memory.c:35
@ EXT2ICX
Definition: ext2fs.h:460
NTSTATUS Ext2Cleanup(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: cleanup.c:21
NTSTATUS Ext2DirectoryControl(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: dirctl.c:1236
NTSTATUS Ext2Create(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: create.c:1951
NTSTATUS Ext2SetFileInformation(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fileinfo.c:509
NTSTATUS Ext2QueryVolumeInformation(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: volinfo.c:27
struct ext2_icb * PEXT2_IRP_CONTEXT
NTSTATUS Ext2LockControl(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: lock.c:25
NTSTATUS Ext2LockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
Definition: block.c:101
NTSTATUS Ext2FileSystemControl(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:2848
NTSTATUS Ext2SetVolumeInformation(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: volinfo.c:292
NTSTATUS Ext2DeviceControl(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: devctl.c:759
NTSTATUS Ext2Write(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: write.c:1339
#define Ext2CompleteRequest(Irp, bPrint, PriorityBoost)
Definition: ext2fs.h:1438
#define DbgBreak()
Definition: ext2fs.h:46
VOID Ext2DbgPrintCall(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
#define IRP_CONTEXT_FLAG_REQUEUED
Definition: ext2fs.h:1085
#define FSCTL_GET_RETRIEVAL_POINTER_BASE
Definition: ext2fs.h:1123
NTSTATUS Ext2QueryFileInformation(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fileinfo.c:43
#define DL_ERR
Definition: ext2fs.h:1397
NTSTATUS Ext2CompleteIrpContext(IN PEXT2_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: read.c:32
NTSTATUS Ext2SetEa(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: ea.c:436
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
Status
Definition: gdiplustypes.h:25
IoMarkIrpPending(Irp)
#define ASSERT(a)
Definition: mode.c:44
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define STATUS_PENDING
Definition: ntstatus.h:82
#define FSCTL_GET_RETRIEVAL_POINTERS
Definition: winioctl.h:95
#define FSCTL_GET_VOLUME_BITMAP
Definition: winioctl.h:94
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
#define IRP_MN_QUERY_DIRECTORY
Definition: rdpdr.c:55
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
#define STATUS_SUCCESS
Definition: shellext.h:65
EXT2_IDENTIFIER_TYPE Type
Definition: ext2fs.h:472
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
UCHAR MajorFunction
Definition: ext2fs.h:1047
UCHAR MinorFunction
Definition: ext2fs.h:1048
EXT2_IDENTIFIER Identifier
Definition: ext2fs.h:1038
BOOLEAN IsTopLevel
Definition: ext2fs.h:1063
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_DRIVER_INTERNAL_ERROR
Definition: udferr_usr.h:177
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define PEXTENDED_IO_STACK_LOCATION
Definition: udffs.h:121
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
@ CriticalWorkQueue
Definition: extypes.h:189
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define IRP_MJ_QUERY_EA
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_MJ_SET_VOLUME_INFORMATION
#define IRP_MN_USER_FS_REQUEST
Definition: iotypes.h:4403
#define IRP_MJ_SET_EA
#define IRP_MN_MDL
Definition: iotypes.h:4419
#define IRP_MJ_FLUSH_BUFFERS
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_CLEANUP
@ IoReadAccess
Definition: ketypes.h:851
@ IoWriteAccess
Definition: ketypes.h:852