ReactOS 0.4.16-dev-252-g9ccafe8
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
40#ifdef __REACTOS__
42#else
43VOID
44#endif
47 IN PIRP Irp
48)
49{
50 //
51 // Check on the return value in the Irp.
52 //
53
54 if (Irp->IoStatus.Status == STATUS_SUCCESS) {
55
56 //
57 // queue the Irp context in the workqueue.
58 //
59
61
62 } else {
63
64 //
65 // complete the request in case of failure
66 //
67
69 Irp->IoStatus.Status );
70 }
71
72 return;
73}
74
75
76/*
77 * Ext2LockIrp
78 *
79 * performs buffer locking if we need pend the process of the Irp
80 *
81 * Arguments:
82 * Context: the irp context
83 * Irp: the I/O request packet.
84 *
85 * Return Value:
86 * N/A
87 */
88
89#ifdef __REACTOS__
91#else
92VOID
93#endif
96 IN PIRP Irp
97)
98{
100 PEXT2_IRP_CONTEXT IrpContext;
101
102 if (Irp == NULL) {
103 return;
104 }
105
107
108 IrpContext = (PEXT2_IRP_CONTEXT) Context;
109
110 if ( IrpContext->MajorFunction == IRP_MJ_READ ||
111 IrpContext->MajorFunction == IRP_MJ_WRITE ) {
112
113 //
114 // lock the user's buffer to MDL, if the I/O is bufferred
115 //
116
117 if (!IsFlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {
118
120 (IrpContext->MajorFunction == IRP_MJ_READ) ?
122 }
123
124 } else if (IrpContext->MajorFunction == IRP_MJ_DIRECTORY_CONTROL
125 && IrpContext->MinorFunction == IRP_MN_QUERY_DIRECTORY) {
126
127 ULONG Length = ((PEXTENDED_IO_STACK_LOCATION) IrpSp)->Parameters.QueryDirectory.Length;
129
130 } else if (IrpContext->MajorFunction == IRP_MJ_QUERY_EA) {
131
132 ULONG Length = ((PEXTENDED_IO_STACK_LOCATION) IrpSp)->Parameters.QueryEa.Length;
134
135 } else if (IrpContext->MajorFunction == IRP_MJ_SET_EA) {
136 ULONG Length = ((PEXTENDED_IO_STACK_LOCATION) IrpSp)->Parameters.SetEa.Length;
138
139 } else if ( (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) &&
140 (IrpContext->MinorFunction == IRP_MN_USER_FS_REQUEST) ) {
142 if ( (EIrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_GET_VOLUME_BITMAP) ||
143 (EIrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_GET_RETRIEVAL_POINTERS) ||
145 ULONG Length = EIrpSp->Parameters.FileSystemControl.OutputBufferLength;
147 }
148 }
149
150 // Mark the request as pending status
151
153
154 return;
155}
156
159{
160 ASSERT(IrpContext);
161
162 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
163 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
164
165 /* set the flags of "can wait" and "queued" */
166 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
167 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);
168
169 /* make sure the buffer is kept valid in system context */
170 Ext2LockIrp(IrpContext, IrpContext->Irp);
171
172 /* initialize workite*/
174 &IrpContext->WorkQueueItem,
176 IrpContext );
177
178 /* dispatch it */
179 ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
180
181 return STATUS_PENDING;
182}
183
184
185#ifdef __REACTOS__
187#else
188VOID
189#endif
191{
192 PEXT2_IRP_CONTEXT IrpContext;
193
194 IrpContext = (PEXT2_IRP_CONTEXT) Context;
195
196 ASSERT(IrpContext);
197
198 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
199 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
200
201 _SEH2_TRY {
202
203 _SEH2_TRY {
204
206
207 if (!IrpContext->IsTopLevel) {
209 }
210
211 Ext2DispatchRequest(IrpContext);
212
214
215 Ext2ExceptionHandler(IrpContext);
216 } _SEH2_END;
217
218 } _SEH2_FINALLY {
219
221
223 } _SEH2_END;
224}
225
226
229{
230 ASSERT(IrpContext);
231
232 ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
233 (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
234
235 switch (IrpContext->MajorFunction) {
236
237 case IRP_MJ_CREATE:
238 return Ext2Create(IrpContext);
239
240 case IRP_MJ_CLOSE:
241 return Ext2Close(IrpContext);
242
243 case IRP_MJ_READ:
244 return Ext2Read(IrpContext);
245
246 case IRP_MJ_WRITE:
247 return Ext2Write(IrpContext);
248
250 return Ext2Flush(IrpContext);
251
253 return Ext2QueryFileInformation(IrpContext);
254
256 return Ext2SetFileInformation(IrpContext);
257
259 return Ext2QueryVolumeInformation(IrpContext);
260
262 return Ext2SetVolumeInformation(IrpContext);
263
265 return Ext2DirectoryControl(IrpContext);
266
268 return Ext2FileSystemControl(IrpContext);
269
271 return Ext2DeviceControl(IrpContext);
272
274 return Ext2LockControl(IrpContext);
275
276 case IRP_MJ_CLEANUP:
277 return Ext2Cleanup(IrpContext);
278
279 case IRP_MJ_SHUTDOWN:
280 return Ext2ShutDown(IrpContext);
281
282 case IRP_MJ_QUERY_EA:
283 return Ext2QueryEa(IrpContext);
284
285 case IRP_MJ_SET_EA:
286 return Ext2SetEa(IrpContext);
287
288#if (_WIN32_WINNT >= 0x0500)
289 case IRP_MJ_PNP:
290 return Ext2Pnp(IrpContext);
291#endif //(_WIN32_WINNT >= 0x0500)
292 default:
293 DEBUG(DL_ERR, ( "Ext2DispatchRequest: Unexpected major function: %xh\n",
294 IrpContext->MajorFunction));
295
297
299 }
300}
301
302
303#ifdef __REACTOS__
305#else
307#endif
309{
310 BOOLEAN AtIrqlPassiveLevel = FALSE;
311 BOOLEAN IsTopLevelIrp = FALSE;
312 PEXT2_IRP_CONTEXT IrpContext = NULL;
314
315 _SEH2_TRY {
316
317 _SEH2_TRY {
318
319#if EXT2_DEBUG
321#endif
322
323 AtIrqlPassiveLevel = (KeGetCurrentIrql() == PASSIVE_LEVEL);
324
325 if (AtIrqlPassiveLevel) {
327 }
328
329 if (!IoGetTopLevelIrp()) {
330 IsTopLevelIrp = TRUE;
332 }
333
335
336 if (!IrpContext) {
337
339 Irp->IoStatus.Status = Status;
340
342
343 } else {
344
345 if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
346 !AtIrqlPassiveLevel) {
347
348 DbgBreak();
349 }
350
351 Status = Ext2DispatchRequest(IrpContext);
352 }
354
355 Status = Ext2ExceptionHandler(IrpContext);
356 } _SEH2_END;
357
358 } _SEH2_FINALLY {
359
360 if (IsTopLevelIrp) {
362 }
363
364 if (AtIrqlPassiveLevel) {
366 }
367 } _SEH2_END;
368
369 return Status;
370}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DEBUG(args)
Definition: rdesktop.h:129
ARC_STATUS Ext2Close(ULONG FileId)
Definition: ext2.c:1195
ARC_STATUS Ext2Read(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: ext2.c:1243
#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 STATUS_PENDING
Definition: d3dkmdt.h:43
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
VOID Ext2OplockComplete(IN PVOID Context, IN PIRP Irp)
Definition: dispatch.c:45
PEXT2_GLOBAL Ext2Global
Definition: init.c:16
NTSTATUS Ext2QueueRequest(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: dispatch.c:158
NTSTATUS Ext2BuildRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: dispatch.c:308
NTSTATUS Ext2DispatchRequest(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: dispatch.c:228
VOID Ext2LockIrp(IN PVOID Context, IN PIRP Irp)
Definition: dispatch.c:94
VOID Ext2DeQueueRequest(IN PVOID Context)
Definition: dispatch.c:190
_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:148
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:465
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:514
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:113
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:783
NTSTATUS Ext2Write(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: write.c:1355
#define Ext2CompleteRequest(Irp, bPrint, PriorityBoost)
Definition: ext2fs.h:1475
#define DbgBreak()
Definition: ext2fs.h:46
VOID Ext2DbgPrintCall(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
#define IRP_CONTEXT_FLAG_REQUEUED
Definition: ext2fs.h:1094
#define FSCTL_GET_RETRIEVAL_POINTER_BASE
Definition: ext2fs.h:1132
NTSTATUS Ext2QueryFileInformation(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fileinfo.c:48
#define DL_ERR
Definition: ext2fs.h:1434
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 FSCTL_GET_RETRIEVAL_POINTERS
Definition: winioctl.h:744
#define FSCTL_GET_VOLUME_BITMAP
Definition: winioctl.h:743
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
#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:477
union _IO_STACK_LOCATION::@1579 Parameters
struct _IO_STACK_LOCATION::@3978::@3983 Write
struct _IO_STACK_LOCATION::@3978::@3993 FileSystemControl
UCHAR MajorFunction
Definition: ext2fs.h:1056
UCHAR MinorFunction
Definition: ext2fs.h:1057
EXT2_IDENTIFIER Identifier
Definition: ext2fs.h:1047
BOOLEAN IsTopLevel
Definition: ext2fs.h:1072
#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:119
_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
#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:863
@ IoWriteAccess
Definition: ketypes.h:864