1 /* $Id: irp.c,v 1.42 2002/09/07 15:12:53 chorns Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/irp.c
7 * PROGRAMMER: David Welch (welch@mcmail.com)
12 /* NOTES *******************************************************************
31 /* INCLUDES ****************************************************************/
36 #include <internal/debug.h>
39 /* GLOBALS *******************************************************************/
41 #define TAG_IRP TAG('I', 'R', 'P', ' ')
43 /* FUNCTIONS ****************************************************************/
49 * FUNCTION: Releases a caller allocated irp
59 IoMakeAssociatedIrp(PIRP Irp
,
62 * FUNCTION: Allocates and initializes an irp to associated with a master irp
65 * StackSize = Number of stack locations to be allocated in the irp
66 * RETURNS: The irp allocated
71 AssocIrp
= IoAllocateIrp(StackSize
,FALSE
);
77 IoInitializeIrp(PIRP Irp
,
81 * FUNCTION: Initalizes an irp allocated by the caller
83 * Irp = IRP to initalize
84 * PacketSize = Size in bytes of the IRP
85 * StackSize = Number of stack locations in the IRP
90 memset(Irp
, 0, PacketSize
);
91 Irp
->Size
= PacketSize
;
92 Irp
->StackCount
= StackSize
;
93 Irp
->CurrentLocation
= StackSize
;
94 Irp
->Tail
.Overlay
.CurrentStackLocation
= IoGetSpecificIrpStackLocation(Irp
, StackSize
);
99 IofCallDriver(PDEVICE_OBJECT DeviceObject
,
102 * FUNCTION: Sends an IRP to the next lower driver
106 PDRIVER_OBJECT DriverObject
;
107 PIO_STACK_LOCATION Param
;
109 DPRINT("IofCallDriver(DeviceObject %x, Irp %x)\n",DeviceObject
,Irp
);
112 assert(DeviceObject
);
114 DriverObject
= DeviceObject
->DriverObject
;
116 assert(DriverObject
);
118 Param
= IoGetNextIrpStackLocation(Irp
);
120 DPRINT("IrpSp 0x%X\n", Param
);
122 Irp
->Tail
.Overlay
.CurrentStackLocation
--;
123 Irp
->CurrentLocation
--;
125 DPRINT("MajorFunction %d\n", Param
->MajorFunction
);
126 DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n",
127 DriverObject
->MajorFunction
[Param
->MajorFunction
]);
128 Status
= ((PDRIVER_DISPATCH
)DriverObject
->MajorFunction
[Param
->MajorFunction
])(DeviceObject
,
138 IoCallDriver (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
140 return(IofCallDriver(DeviceObject
,
146 IoAllocateIrp(CCHAR StackSize
,
149 * FUNCTION: Allocates an IRP
151 * StackSize = the size of the stack required for the irp
152 * ChargeQuota = Charge allocation to current threads quota
153 * RETURNS: Irp allocated
159 DbgPrint("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",
162 KeDumpStackFrames(0,8);
167 // Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
168 Irp
= ExAllocatePoolWithTag(NonPagedPool
,
169 IoSizeOfIrp(StackSize
),
174 Irp
= ExAllocatePoolWithTag(NonPagedPool
,
175 IoSizeOfIrp(StackSize
),
185 IoSizeOfIrp(StackSize
),
188 // DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation);
195 IopCompleteRequest(struct _KAPC
* Apc
,
196 PKNORMAL_ROUTINE
* NormalRoutine
,
197 PVOID
* NormalContext
,
198 PVOID
* SystemArgument1
,
199 PVOID
* SystemArgument2
)
201 DPRINT("IopCompleteRequest(Apc %x, SystemArgument1 %x, (*SystemArgument1) %x\n",
205 IoSecondStageCompletion((PIRP
)(*SystemArgument1
),
206 (KPRIORITY
)(*SystemArgument2
));
211 IofCompleteRequest(PIRP Irp
,
214 * FUNCTION: Indicates the caller has finished all processing for a given
215 * I/O request and is returning the given IRP to the I/O manager
217 * Irp = Irp to be cancelled
218 * PriorityBoost = Increment by which to boost the priority of the
219 * thread making the request
225 DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
226 Irp
,PriorityBoost
, Irp
->UserEvent
, PsGetCurrentThread());
228 for (i
=Irp
->CurrentLocation
;i
<Irp
->StackCount
;i
++)
230 PIO_STACK_LOCATION IrpSp
= IoGetSpecificIrpStackLocation(Irp
, i
);
231 if (IrpSp
->CompletionRoutine
!= NULL
)
233 Status
= IrpSp
->CompletionRoutine(IrpSp
->DeviceObject
,
236 if (Status
== STATUS_MORE_PROCESSING_REQUIRED
)
241 if (IrpSp
->Control
& SL_PENDING_RETURNED
)
243 Irp
->PendingReturned
= TRUE
;
245 if (Irp
->CurrentLocation
< Irp
->StackCount
- 1)
247 IoSkipCurrentIrpStackLocation(Irp
);
250 if (Irp
->PendingReturned
)
252 DPRINT("Dispatching APC\n");
253 KeInitializeApc(&Irp
->Tail
.Apc
,
254 &Irp
->Tail
.Overlay
.Thread
->Tcb
,
262 KeInsertQueueApc(&Irp
->Tail
.Apc
,
264 (PVOID
)(ULONG
)PriorityBoost
,
266 DPRINT("Finished dispatching APC\n");
270 DPRINT("Calling completion routine directly\n");
271 IoSecondStageCompletion(Irp
,PriorityBoost
);
272 DPRINT("Finished completition routine\n");
276 #undef IoCompleteRequest
279 IoCompleteRequest(PIRP Irp
,
282 IofCompleteRequest(Irp
,
287 /**********************************************************************
289 * IoIsOperationSynchronous@4
292 * Check if the I/O operation associated with the given IRP
296 * Irp Packet to check.
299 * TRUE if Irp's operation is synchronous; otherwise FALSE.
302 IoIsOperationSynchronous(IN PIRP Irp
)
304 PFILE_OBJECT FileObject
= NULL
;
307 /* Check the associated FILE_OBJECT's flags first. */
308 FileObject
= Irp
->Tail
.Overlay
.OriginalFileObject
;
309 if (!(FO_SYNCHRONOUS_IO
& FileObject
->Flags
))
311 /* Check IRP's flags. */
313 if (!((IRP_SYNCHRONOUS_API
| IRP_SYNCHRONOUS_PAGING_IO
) & Flags
))
319 /* Check more IRP's flags. */
321 if (!(IRP_MOUNT_COMPLETION
& Flags
)
322 || (IRP_SYNCHRONOUS_PAGING_IO
& Flags
))
327 /* Otherwise, it is an asynchronous operation. */
333 IoEnqueueIrp(IN PIRP Irp
)
340 IoSetTopLevelIrp(IN PIRP Irp
)
344 Thread
= PsGetCurrentThread();
345 Thread
->TopLevelIrp
->TopLevelIrp
= Irp
;
350 IoGetTopLevelIrp(VOID
)
352 return(PsGetCurrentThread()->TopLevelIrp
->TopLevelIrp
);
357 IoQueueThreadIrp(IN PIRP Irp
)