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
63 IoMakeAssociatedIrp(PIRP Irp,
66 * FUNCTION: Allocates and initializes an irp to associated with a master irp
69 * StackSize = Number of stack locations to be allocated in the irp
70 * RETURNS: The irp allocated
75 AssocIrp = IoAllocateIrp(StackSize,FALSE);
80 #endif /* LIBCAPTIVE */
83 IoInitializeIrp(PIRP Irp,
87 * FUNCTION: Initalizes an irp allocated by the caller
89 * Irp = IRP to initalize
90 * PacketSize = Size in bytes of the IRP
91 * StackSize = Number of stack locations in the IRP
96 memset(Irp, 0, PacketSize);
97 Irp->Type = IO_TYPE_IRP;
98 Irp->Size = PacketSize;
99 Irp->StackCount = StackSize;
100 Irp->CurrentLocation = StackSize;
101 Irp->Tail.Overlay.CurrentStackLocation = &Irp->Stack[(ULONG)StackSize];
106 IofCallDriver(PDEVICE_OBJECT DeviceObject,
109 * FUNCTION: Sends an IRP to the next lower driver
112 PDRIVER_OBJECT DriverObject;
113 PIO_STACK_LOCATION Param;
115 DPRINT("IofCallDriver(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
118 assert(DeviceObject);
120 DriverObject = DeviceObject->DriverObject;
122 assert(DriverObject);
124 IoSetNextIrpStackLocation(Irp);
125 Param = IoGetCurrentIrpStackLocation(Irp);
127 DPRINT("IrpSp 0x%X\n", Param);
129 Param->DeviceObject = DeviceObject;
131 DPRINT("MajorFunction %d\n", Param->MajorFunction);
132 DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n",
133 DriverObject->MajorFunction[Param->MajorFunction]);
135 if (!DriverObject->MajorFunction[Param->MajorFunction])
137 return DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, Irp);
143 IoCallDriver (PDEVICE_OBJECT DeviceObject, PIRP Irp)
145 return(IofCallDriver(DeviceObject,
151 IoAllocateIrp(CCHAR StackSize,
154 * FUNCTION: Allocates an IRP
156 * StackSize = the size of the stack required for the irp
157 * ChargeQuota = Charge allocation to current threads quota
158 * RETURNS: Irp allocated
164 DbgPrint("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",
167 KeDumpStackFrames(0,8);
172 // Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
173 Irp = ExAllocatePoolWithTag(NonPagedPool,
174 IoSizeOfIrp(StackSize),
179 Irp = ExAllocatePoolWithTag(NonPagedPool,
180 IoSizeOfIrp(StackSize),
190 IoSizeOfIrp(StackSize),
193 // DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation);
201 IopCompleteRequest(struct _KAPC* Apc,
202 PKNORMAL_ROUTINE* NormalRoutine,
203 PVOID* NormalContext,
204 PVOID* SystemArgument1,
205 PVOID* SystemArgument2)
207 DPRINT("IopCompleteRequest(Apc %x, SystemArgument1 %x, (*SystemArgument1) %x\n",
211 IoSecondStageCompletion((PIRP)(*SystemArgument1),
212 (KPRIORITY)(*SystemArgument2));
215 #endif /* LIBCAPTIVE */
218 IofCompleteRequest(PIRP Irp,
221 * FUNCTION: Indicates the caller has finished all processing for a given
222 * I/O request and is returning the given IRP to the I/O manager
224 * Irp = Irp to be cancelled
225 * PriorityBoost = Increment by which to boost the priority of the
226 * thread making the request
231 PDEVICE_OBJECT DeviceObject;
233 DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
234 Irp,PriorityBoost, Irp->UserEvent, PsGetCurrentThread());
236 assert(Irp->CancelRoutine == NULL);
237 assert(Irp->IoStatus.Status != STATUS_PENDING);
239 if (IoGetCurrentIrpStackLocation(Irp)->Control & SL_PENDING_RETURNED)
241 Irp->PendingReturned = TRUE;
244 for (i=Irp->CurrentLocation;i<(ULONG)Irp->StackCount;i++)
247 Completion routines expect the current irp stack location to be the same as when
248 IoSetCompletionRoutine was called to set them. A side effect is that completion
249 routines set by highest level drivers without their own stack location will receive
250 an invalid current stack location (at least it should be considered as invalid).
251 Since the DeviceObject argument passed is taken from the current stack, this value
252 is also invalid (NULL).
254 if (Irp->CurrentLocation < Irp->StackCount - 1)
256 IoSetPreviousIrpStackLocation(Irp);
257 DeviceObject = IoGetCurrentIrpStackLocation(Irp)->DeviceObject;
264 if (Irp->Stack[i].CompletionRoutine != NULL &&
265 ((NT_SUCCESS(Irp->IoStatus.Status) && (Irp->Stack[i].Control & SL_INVOKE_ON_SUCCESS)) ||
266 (!NT_SUCCESS(Irp->IoStatus.Status) && (Irp->Stack[i].Control & SL_INVOKE_ON_ERROR)) ||
267 (Irp->Cancel && (Irp->Stack[i].Control & SL_INVOKE_ON_CANCEL))))
269 Status = Irp->Stack[i].CompletionRoutine(DeviceObject,
271 Irp->Stack[i].CompletionContext);
273 if (Status == STATUS_MORE_PROCESSING_REQUIRED)
277 *Irp->UserIosb=Irp->IoStatus;
283 if (IoGetCurrentIrpStackLocation(Irp)->Control & SL_PENDING_RETURNED)
285 Irp->PendingReturned = TRUE;
289 if (Irp->PendingReturned)
291 DPRINT("Dispatching APC\n");
293 KeInitializeApc(&Irp->Tail.Apc,
294 &Irp->Tail.Overlay.Thread->Tcb,
302 KeInsertQueueApc(&Irp->Tail.Apc,
304 (PVOID)(ULONG)PriorityBoost,
306 DPRINT("Finished dispatching APC\n");
307 #else /* !LIBCAPTIVE */
309 #endif /* !LIBCAPTIVE */
313 DPRINT("Calling completion routine directly\n");
314 IoSecondStageCompletion(Irp,PriorityBoost);
315 DPRINT("Finished completition routine\n");
321 IoCompleteRequest(PIRP Irp,
324 IofCompleteRequest(Irp,
329 /**********************************************************************
331 * IoIsOperationSynchronous@4
334 * Check if the I/O operation associated with the given IRP
338 * Irp Packet to check.
341 * TRUE if Irp's operation is synchronous; otherwise FALSE.
344 IoIsOperationSynchronous(IN PIRP Irp)
346 PFILE_OBJECT FileObject = NULL;
349 /* Check the FILE_OBJECT's flags first. */
350 FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
351 if (FileObject == NULL)
353 if (!(FO_SYNCHRONOUS_IO & FileObject->Flags))
355 /* Check IRP's flags. */
357 if (!((IRP_SYNCHRONOUS_API | IRP_SYNCHRONOUS_PAGING_IO) & Flags))
360 /* libcaptive is fully single-thread/single-process synchronous model. */
362 #endif /* LIBCAPTIVE */
367 /* Check more IRP's flags. */
369 if (!(IRP_PAGING_IO & Flags)
370 || (IRP_SYNCHRONOUS_PAGING_IO & Flags))
375 /* Otherwise, it is an asynchronous operation. */
377 /* libcaptive is fully single-thread/single-process synchronous model. */
379 #endif /* LIBCAPTIVE */
386 IoEnqueueIrp(IN PIRP Irp)
391 #endif /* LIBCAPTIVE */
394 IoSetTopLevelIrp(IN PIRP Irp)
398 Thread = PsGetCurrentThread();
399 Thread->TopLevelIrp->TopLevelIrp = Irp;
404 IoGetTopLevelIrp(VOID)
406 return(PsGetCurrentThread()->TopLevelIrp->TopLevelIrp);
412 IoQueueThreadIrp(IN PIRP Irp)
420 IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
429 IN PDEVICE_OBJECT DeviceObject,
430 IN DEVICE_REGISTRY_PROPERTY DeviceProperty,
431 IN ULONG BufferLength,
432 OUT PVOID PropertyBuffer,
433 OUT PULONG ResultLength)
441 IoOpenDeviceRegistryKey(
442 IN PDEVICE_OBJECT DeviceObject,
443 IN ULONG DevInstKeyType,
444 IN ACCESS_MASK DesiredAccess,
445 OUT PHANDLE DevInstRegKey)
452 #endif /* LIBCAPTIVE */