1 /* $Id: irp.c,v 1.30 2000/10/11 20:50:34 dwelch 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 ****************************************************************/
33 #include <ddk/ntddk.h>
35 #include <internal/io.h>
36 #include <internal/ps.h>
39 #include <internal/debug.h>
41 /* FUNCTIONS ****************************************************************/
43 PDEVICE_OBJECT STDCALL
44 IoGetDeviceToVerify (PETHREAD Thread
)
46 * FUNCTION: Returns a pointer to the device, representing a removable-media
47 * device, that is the target of the given thread's I/O request
57 * FUNCTION: Releases a caller allocated irp
67 IoMakeAssociatedIrp (PIRP Irp
, CCHAR StackSize
)
69 * FUNCTION: Allocates and initializes an irp to associated with a master irp
72 * StackSize = Number of stack locations to be allocated in the irp
73 * RETURNS: The irp allocated
78 AssocIrp
= IoAllocateIrp(StackSize
,FALSE
);
84 IoInitializeIrp (PIRP Irp
, USHORT PacketSize
, CCHAR StackSize
)
86 * FUNCTION: Initalizes an irp allocated by the caller
88 * Irp = IRP to initalize
89 * PacketSize = Size in bytes of the IRP
90 * StackSize = Number of stack locations in the IRP
95 memset(Irp
, 0, PacketSize
);
96 Irp
->Size
= PacketSize
;
97 Irp
->StackCount
= StackSize
;
98 Irp
->CurrentLocation
= StackSize
;
99 Irp
->Tail
.Overlay
.CurrentStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
104 IofCallDriver (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
106 * FUNCTION: Sends an IRP to the next lower driver
110 PDRIVER_OBJECT DriverObject
;
111 PIO_STACK_LOCATION Param
;
113 // DPRINT("IoCallDriver(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
115 DriverObject
= DeviceObject
->DriverObject
;
116 Param
= IoGetNextIrpStackLocation(Irp
);
118 Irp
->Tail
.Overlay
.CurrentStackLocation
--;
119 Irp
->CurrentLocation
--;
121 // DPRINT("MajorFunction %d\n", Param->MajorFunction);
122 // DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n",
123 // DriverObject->MajorFunction[Param->MajorFunction]);
124 Status
= DriverObject
->MajorFunction
[Param
->MajorFunction
](DeviceObject
,
132 IoCallDriver (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
134 return IofCallDriver (
143 IoAllocateIrp (CCHAR StackSize
, BOOLEAN ChargeQuota
)
145 * FUNCTION: Allocates an IRP
147 * StackSize = the size of the stack required for the irp
148 * ChargeQuota = Charge allocation to current threads quota
149 * RETURNS: Irp allocated
155 DbgPrint("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",
158 KeDumpStackFrames(0,8);
163 // Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
164 Irp
= ExAllocatePool(NonPagedPool
,IoSizeOfIrp(StackSize
));
168 Irp
= ExAllocatePool(NonPagedPool
,IoSizeOfIrp(StackSize
));
176 IoInitializeIrp(Irp
, IoSizeOfIrp(StackSize
), StackSize
);
178 // DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation);
184 VOID
IopCompleteRequest(struct _KAPC
* Apc
,
185 PKNORMAL_ROUTINE
* NormalRoutine
,
186 PVOID
* NormalContext
,
187 PVOID
* SystemArgument1
,
188 PVOID
* SystemArgument2
)
190 DPRINT("IopCompleteRequest(Apc %x, SystemArgument1 %x, "
191 "(*SystemArgument1) %x\n", Apc
, SystemArgument1
,
193 IoSecondStageCompletion((PIRP
)(*SystemArgument1
),
194 (KPRIORITY
)(*SystemArgument2
));
200 IofCompleteRequest (PIRP Irp
, CCHAR PriorityBoost
)
202 * FUNCTION: Indicates the caller has finished all processing for a given
203 * I/O request and is returning the given IRP to the I/O manager
205 * Irp = Irp to be cancelled
206 * PriorityBoost = Increment by which to boost the priority of the
207 * thread making the request
214 DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
215 Irp
,PriorityBoost
, Irp
->UserEvent
, PsGetCurrentThread());
217 for (i
=0;i
<Irp
->StackCount
;i
++)
219 if (Irp
->Stack
[i
].CompletionRoutine
!= NULL
)
221 Status
= Irp
->Stack
[i
].CompletionRoutine(
222 Irp
->Stack
[i
].DeviceObject
,
224 Irp
->Stack
[i
].CompletionContext
);
225 if (Status
== STATUS_MORE_PROCESSING_REQUIRED
)
230 if (Irp
->Stack
[i
].Control
& SL_PENDING_RETURNED
)
232 Irp
->PendingReturned
= TRUE
;
236 if (Irp
->PendingReturned
)
238 DPRINT("Dispatching APC\n");
239 Thread
= &Irp
->Tail
.Overlay
.Thread
->Tcb
;
240 KeInitializeApc(&Irp
->Tail
.Apc
,
249 KeInsertQueueApc(&Irp
->Tail
.Apc
,
251 (PVOID
)(ULONG
)PriorityBoost
,
253 DPRINT("Finished dispatching APC\n");
257 DPRINT("Calling completion routine directly\n");
258 IoSecondStageCompletion(Irp
,PriorityBoost
);
259 DPRINT("Finished completition routine\n");
266 IoCompleteRequest (PIRP Irp
, CCHAR PriorityBoost
)
275 /**********************************************************************
277 * IoIsOperationSynchronous@4
280 * Check if the I/O operation associated with the given IRP
284 * Irp Packet to check.
287 * TRUE if Irp's operation is synchronous; otherwise FALSE.
291 IoIsOperationSynchronous (
296 PFILE_OBJECT FileObject
= NULL
;
299 * Check the associated FILE_OBJECT's
302 FileObject
= Irp
->Tail
.Overlay
.OriginalFileObject
;
303 if (!(FO_SYNCHRONOUS_IO
& FileObject
->Flags
))
305 /* Check IRP's flags. */
307 if (!( (IRP_SYNCHRONOUS_API
| IRP_SYNCHRONOUS_PAGING_IO
)
315 * Check more IRP's flags.
318 if ( !(IRP_MOUNT_COMPLETION
& Flags
)
319 || (IRP_SYNCHRONOUS_PAGING_IO
& Flags
)
325 * Otherwise, it is an
326 * asynchronous operation.
350 Thread
= PsGetCurrentThread ();
351 Thread
->TopLevelIrp
.TopLevelIrp
= Irp
;
361 return (PsGetCurrentThread ()->TopLevelIrp
.TopLevelIrp
);