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>
34 #include <internal/io.h>
35 #include <internal/ps.h>
36 #include <internal/pool.h>
39 #include <internal/debug.h>
41 /* GLOBALS *******************************************************************/
43 #define TAG_IRP TAG('I', 'R', 'P', ' ')
46 /* FUNCTIONS ****************************************************************/
52 * FUNCTION: Releases a caller allocated irp
62 IoMakeAssociatedIrp(PIRP Irp,
65 * FUNCTION: Allocates and initializes an irp to associated with a master irp
68 * StackSize = Number of stack locations to be allocated in the irp
69 * RETURNS: The irp allocated
74 AssocIrp = IoAllocateIrp(StackSize,FALSE);
80 IoInitializeIrp(PIRP Irp,
84 * FUNCTION: Initalizes an irp allocated by the caller
86 * Irp = IRP to initalize
87 * PacketSize = Size in bytes of the IRP
88 * StackSize = Number of stack locations in the IRP
93 memset(Irp, 0, PacketSize);
94 Irp->Size = PacketSize;
95 Irp->StackCount = StackSize;
96 Irp->CurrentLocation = StackSize;
97 Irp->Tail.Overlay.CurrentStackLocation = &Irp->Stack[(ULONG)StackSize];
102 IofCallDriver(PDEVICE_OBJECT DeviceObject,
105 * FUNCTION: Sends an IRP to the next lower driver
109 PDRIVER_OBJECT DriverObject;
110 PIO_STACK_LOCATION Param;
112 DPRINT("IofCallDriver(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
115 assert(DeviceObject);
117 DriverObject = DeviceObject->DriverObject;
119 assert(DriverObject);
121 Param = IoGetNextIrpStackLocation(Irp);
123 DPRINT("IrpSp 0x%X\n", Param);
125 Irp->Tail.Overlay.CurrentStackLocation--;
126 Irp->CurrentLocation--;
128 DPRINT("MajorFunction %d\n", Param->MajorFunction);
129 DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n",
130 DriverObject->MajorFunction[Param->MajorFunction]);
131 Status = DriverObject->MajorFunction[Param->MajorFunction](DeviceObject,
140 IoCallDriver (PDEVICE_OBJECT DeviceObject, PIRP Irp)
142 return(IofCallDriver(DeviceObject,
148 IoAllocateIrp(CCHAR StackSize,
151 * FUNCTION: Allocates an IRP
153 * StackSize = the size of the stack required for the irp
154 * ChargeQuota = Charge allocation to current threads quota
155 * RETURNS: Irp allocated
161 DbgPrint("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",
164 KeDumpStackFrames(0,8);
169 // Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
170 Irp = ExAllocatePoolWithTag(NonPagedPool,
171 IoSizeOfIrp(StackSize),
176 Irp = ExAllocatePoolWithTag(NonPagedPool,
177 IoSizeOfIrp(StackSize),
187 IoSizeOfIrp(StackSize),
190 // DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation);
197 IopCompleteRequest(struct _KAPC* Apc,
198 PKNORMAL_ROUTINE* NormalRoutine,
199 PVOID* NormalContext,
200 PVOID* SystemArgument1,
201 PVOID* SystemArgument2)
203 DPRINT("IopCompleteRequest(Apc %x, SystemArgument1 %x, (*SystemArgument1) %x\n",
207 IoSecondStageCompletion((PIRP)(*SystemArgument1),
208 (KPRIORITY)(*SystemArgument2));
213 IofCompleteRequest(PIRP Irp,
216 * FUNCTION: Indicates the caller has finished all processing for a given
217 * I/O request and is returning the given IRP to the I/O manager
219 * Irp = Irp to be cancelled
220 * PriorityBoost = Increment by which to boost the priority of the
221 * thread making the request
227 DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
228 Irp,PriorityBoost, Irp->UserEvent, PsGetCurrentThread());
230 for (i=Irp->CurrentLocation;i<Irp->StackCount;i++)
232 if (Irp->Stack[i].CompletionRoutine != NULL)
234 Status = Irp->Stack[i].CompletionRoutine(
235 Irp->Stack[i].DeviceObject,
237 Irp->Stack[i].CompletionContext);
238 if (Status == STATUS_MORE_PROCESSING_REQUIRED)
243 if (Irp->Stack[i].Control & SL_PENDING_RETURNED)
245 Irp->PendingReturned = TRUE;
247 if (Irp->CurrentLocation < Irp->StackCount - 1)
249 IoSkipCurrentIrpStackLocation(Irp);
252 if (Irp->PendingReturned)
254 DPRINT("Dispatching APC\n");
255 KeInitializeApc(&Irp->Tail.Apc,
256 &Irp->Tail.Overlay.Thread->Tcb,
264 KeInsertQueueApc(&Irp->Tail.Apc,
266 (PVOID)(ULONG)PriorityBoost,
268 DPRINT("Finished dispatching APC\n");
272 DPRINT("Calling completion routine directly\n");
273 IoSecondStageCompletion(Irp,PriorityBoost);
274 DPRINT("Finished completition routine\n");
280 IoCompleteRequest(PIRP Irp,
283 IofCompleteRequest(Irp,
288 /**********************************************************************
290 * IoIsOperationSynchronous@4
293 * Check if the I/O operation associated with the given IRP
297 * Irp Packet to check.
300 * TRUE if Irp's operation is synchronous; otherwise FALSE.
303 IoIsOperationSynchronous(IN PIRP Irp)
305 PFILE_OBJECT FileObject = NULL;
308 /* Check the FILE_OBJECT's flags first. */
309 FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
310 if (!(FO_SYNCHRONOUS_IO & FileObject->Flags))
312 /* Check IRP's flags. */
314 if (!((IRP_SYNCHRONOUS_API | IRP_SYNCHRONOUS_PAGING_IO) & Flags))
320 /* Check more IRP's flags. */
322 if (!(IRP_PAGING_IO & Flags)
323 || (IRP_SYNCHRONOUS_PAGING_IO & Flags))
328 /* Otherwise, it is an asynchronous operation. */
334 IoEnqueueIrp(IN PIRP Irp)
341 IoSetTopLevelIrp(IN PIRP Irp)
345 Thread = PsGetCurrentThread();
346 Thread->TopLevelIrp->TopLevelIrp = Irp;
351 IoGetTopLevelIrp(VOID)
353 return(PsGetCurrentThread()->TopLevelIrp->TopLevelIrp);
358 IoQueueThreadIrp(IN PIRP Irp)
366 IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
375 IN PDEVICE_OBJECT DeviceObject,
376 IN DEVICE_REGISTRY_PROPERTY DeviceProperty,
377 IN ULONG BufferLength,
378 OUT PVOID PropertyBuffer,
379 OUT PULONG ResultLength)
387 IoOpenDeviceRegistryKey(
388 IN PDEVICE_OBJECT DeviceObject,
389 IN ULONG DevInstKeyType,
390 IN ACCESS_MASK DesiredAccess,
391 OUT PHANDLE DevInstRegKey)