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);
81 IoInitializeIrp(PIRP Irp,
85 * FUNCTION: Initalizes an irp allocated by the caller
87 * Irp = IRP to initalize
88 * PacketSize = Size in bytes of the IRP
89 * StackSize = Number of stack locations in the IRP
94 memset(Irp, 0, PacketSize);
95 Irp->Size = PacketSize;
96 Irp->StackCount = StackSize;
97 Irp->CurrentLocation = StackSize;
98 Irp->Tail.Overlay.CurrentStackLocation = &Irp->Stack[(ULONG)StackSize];
103 IofCallDriver(PDEVICE_OBJECT DeviceObject,
106 * 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 IoSetNextIrpStackLocation(Irp);
122 Param = IoGetCurrentIrpStackLocation(Irp);
124 DPRINT("IrpSp 0x%X\n", Param);
126 Param->DeviceObject = DeviceObject;
128 DPRINT("MajorFunction %d\n", Param->MajorFunction);
129 DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n",
130 DriverObject->MajorFunction[Param->MajorFunction]);
132 return DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, Irp);
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
224 PDEVICE_OBJECT DeviceObject;
226 DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
227 Irp,PriorityBoost, Irp->UserEvent, PsGetCurrentThread());
229 assert(Irp->CancelRoutine == NULL);
230 assert(Irp->IoStatus.Status != STATUS_PENDING);
232 if (IoGetCurrentIrpStackLocation(Irp)->Control & SL_PENDING_RETURNED)
234 Irp->PendingReturned = TRUE;
237 for (i=Irp->CurrentLocation;i<(ULONG)Irp->StackCount;i++)
240 Completion routines expect the current irp stack location to be the same as when
241 IoSetCompletionRoutine was called to set them. A side effect is that completion
242 routines set by highest level drivers without their own stack location will receive
243 an invalid current stack location (at least it should be considered as invalid).
244 Since the DeviceObject argument passed is taken from the current stack, this value
245 is also invalid (NULL).
247 if (Irp->CurrentLocation < Irp->StackCount - 1)
249 IoSetPreviousIrpStackLocation(Irp);
250 DeviceObject = IoGetCurrentIrpStackLocation(Irp)->DeviceObject;
257 if (Irp->Stack[i].CompletionRoutine != NULL &&
258 ((NT_SUCCESS(Irp->IoStatus.Status) && (Irp->Stack[i].Control & SL_INVOKE_ON_SUCCESS)) ||
259 (!NT_SUCCESS(Irp->IoStatus.Status) && (Irp->Stack[i].Control & SL_INVOKE_ON_ERROR)) ||
260 (Irp->Cancel && (Irp->Stack[i].Control & SL_INVOKE_ON_CANCEL))))
262 Status = Irp->Stack[i].CompletionRoutine(DeviceObject,
264 Irp->Stack[i].CompletionContext);
266 if (Status == STATUS_MORE_PROCESSING_REQUIRED)
272 if (IoGetCurrentIrpStackLocation(Irp)->Control & SL_PENDING_RETURNED)
274 Irp->PendingReturned = TRUE;
278 if (Irp->PendingReturned)
280 DPRINT("Dispatching APC\n");
281 KeInitializeApc(&Irp->Tail.Apc,
282 &Irp->Tail.Overlay.Thread->Tcb,
290 KeInsertQueueApc(&Irp->Tail.Apc,
292 (PVOID)(ULONG)PriorityBoost,
294 DPRINT("Finished dispatching APC\n");
298 DPRINT("Calling completion routine directly\n");
299 IoSecondStageCompletion(Irp,PriorityBoost);
300 DPRINT("Finished completition routine\n");
306 IoCompleteRequest(PIRP Irp,
309 IofCompleteRequest(Irp,
314 /**********************************************************************
316 * IoIsOperationSynchronous@4
319 * Check if the I/O operation associated with the given IRP
323 * Irp Packet to check.
326 * TRUE if Irp's operation is synchronous; otherwise FALSE.
329 IoIsOperationSynchronous(IN PIRP Irp)
331 PFILE_OBJECT FileObject = NULL;
334 /* Check the FILE_OBJECT's flags first. */
335 FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
336 if (!(FO_SYNCHRONOUS_IO & FileObject->Flags))
338 /* Check IRP's flags. */
340 if (!((IRP_SYNCHRONOUS_API | IRP_SYNCHRONOUS_PAGING_IO) & Flags))
346 /* Check more IRP's flags. */
348 if (!(IRP_PAGING_IO & Flags)
349 || (IRP_SYNCHRONOUS_PAGING_IO & Flags))
354 /* Otherwise, it is an asynchronous operation. */
360 IoEnqueueIrp(IN PIRP Irp)
367 IoSetTopLevelIrp(IN PIRP Irp)
371 Thread = PsGetCurrentThread();
372 Thread->TopLevelIrp->TopLevelIrp = Irp;
377 IoGetTopLevelIrp(VOID)
379 return(PsGetCurrentThread()->TopLevelIrp->TopLevelIrp);
384 IoQueueThreadIrp(IN PIRP Irp)
392 IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
401 IN PDEVICE_OBJECT DeviceObject,
402 IN DEVICE_REGISTRY_PROPERTY DeviceProperty,
403 IN ULONG BufferLength,
404 OUT PVOID PropertyBuffer,
405 OUT PULONG ResultLength)
413 IoOpenDeviceRegistryKey(
414 IN PDEVICE_OBJECT DeviceObject,
415 IN ULONG DevInstKeyType,
416 IN ACCESS_MASK DesiredAccess,
417 OUT PHANDLE DevInstRegKey)