ReactOS  0.4.13-dev-100-gc8611ae
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 VOID NTAPI
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 
85 VOID NTAPI
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 
149 NTSTATUS
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 
177 VOID NTAPI
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 
215 NTSTATUS
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 
261  case IRP_MJ_LOCK_CONTROL:
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 
318  IrpContext = Ext2AllocateIrpContext(DeviceObject, Irp);
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 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
NTSTATUS NTAPI Ext2BuildRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: dispatch.c:292
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS Ext2Cleanup(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: cleanup.c:21
#define FsRtlEnterFileSystem
#define IRP_MJ_FLUSH_BUFFERS
NTSTATUS Ext2FileSystemControl(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fsctl.c:2848
#define FsRtlExitFileSystem
#define IRP_MJ_SHUTDOWN
_In_ PIRP Irp
Definition: csq.h:116
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS Ext2QueueRequest(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: dispatch.c:150
#define IRP_MJ_SET_VOLUME_INFORMATION
#define IRP_MN_QUERY_DIRECTORY
Definition: rdpdr.c:55
NTSTATUS Ext2LockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
Definition: block.c:101
NTSTATUS Ext2SetEa(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: ea.c:436
VOID NTAPI Ext2OplockComplete(IN PVOID Context, IN PIRP Irp)
Definition: dispatch.c:41
#define FSCTL_GET_RETRIEVAL_POINTER_BASE
Definition: ext2fs.h:1123
_SEH2_TRY
Definition: create.c:4250
NTSTATUS Ext2LockControl(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: lock.c:25
EXT2_IDENTIFIER_TYPE Type
Definition: ext2fs.h:472
NTSTATUS Ext2QueryEa(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: ea.c:94
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define IRP_MJ_SET_EA
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS Ext2DispatchRequest(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: dispatch.c:216
NTSTATUS Ext2DeviceControl(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: devctl.c:759
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
NTSTATUS Ext2QueryVolumeInformation(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: volinfo.c:27
NTSTATUS Ext2Write(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: write.c:1339
NTSTATUS Ext2QueryFileInformation(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fileinfo.c:43
EXT2_IDENTIFIER Identifier
Definition: ext2fs.h:1038
#define IRP_MJ_QUERY_EA
NTSTATUS Ext2ShutDown(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: shutdown.c:25
#define IRP_MN_USER_FS_REQUEST
Definition: iotypes.h:4046
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
BOOLEAN IsTopLevel
Definition: ext2fs.h:1063
NTSTATUS Ext2DirectoryControl(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: dirctl.c:1236
#define STATUS_PENDING
Definition: ntstatus.h:82
NTSTATUS Ext2ExceptionHandler(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: except.c:112
NTSTATUS Ext2ExceptionFilter(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: except.c:21
#define IRP_MJ_FILE_SYSTEM_CONTROL
ARC_STATUS Ext2Close(ULONG FileId)
Definition: ext2.c:1197
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
#define Ext2CompleteRequest(Irp, bPrint, PriorityBoost)
Definition: ext2fs.h:1438
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_DRIVER_INTERNAL_ERROR
Definition: udferr_usr.h:177
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
NTSTATUS Ext2CompleteIrpContext(IN PEXT2_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: read.c:32
#define FSCTL_GET_RETRIEVAL_POINTERS
Definition: winioctl.h:95
#define IRP_MN_MDL
Definition: iotypes.h:4062
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
Status
Definition: gdiplustypes.h:24
#define DL_ERR
Definition: ext2fs.h:1397
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
_SEH2_END
Definition: create.c:4424
ARC_STATUS Ext2Read(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: ext2.c:1252
NTSTATUS Ext2Create(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: create.c:1951
#define FSCTL_GET_VOLUME_BITMAP
Definition: winioctl.h:94
UCHAR MajorFunction
Definition: ext2fs.h:1047
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
struct ext2_icb * PEXT2_IRP_CONTEXT
_SEH2_FINALLY
Definition: create.c:4395
#define IRP_CONTEXT_FLAG_REQUEUED
Definition: ext2fs.h:1085
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
#define IRP_MJ_READ
Definition: rdpdr.c:46
NTSTATUS Ext2SetVolumeInformation(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: volinfo.c:292
#define IRP_MJ_CLEANUP
NTSTATUS Ext2SetFileInformation(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: fileinfo.c:509
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
NTSTATUS Ext2Flush(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: flush.c:144
PEXT2_GLOBAL Ext2Global
Definition: init.c:16
#define DbgBreak()
Definition: ext2fs.h:46
PEXT2_IRP_CONTEXT Ext2AllocateIrpContext(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: memory.c:35
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define DEBUG(args)
Definition: rdesktop.h:129
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
IO_STACK_LOCATION * PEXTENDED_IO_STACK_LOCATION
Definition: ext2fs.h:174
VOID NTAPI Ext2DeQueueRequest(IN PVOID Context)
Definition: dispatch.c:178
NTSTATUS Ext2Pnp(IN PEXT2_IRP_CONTEXT IrpContext)
UCHAR MinorFunction
Definition: ext2fs.h:1048
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
return STATUS_SUCCESS
Definition: btrfs.c:2725
IoMarkIrpPending(Irp)
VOID NTAPI Ext2LockIrp(IN PVOID Context, IN PIRP Irp)
Definition: dispatch.c:86
VOID Ext2DbgPrintCall(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52