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);
79 #endif /* LIBCAPTIVE */
82 IoInitializeIrp(PIRP Irp,
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->Type = IO_TYPE_IRP;
97 Irp->Size = PacketSize;
98 Irp->StackCount = StackSize;
99 Irp->CurrentLocation = StackSize;
100 Irp->Tail.Overlay.CurrentStackLocation = &Irp->Stack[(ULONG)StackSize];
105 IofCallDriver(PDEVICE_OBJECT DeviceObject,
108 * 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 Param = IoGetNextIrpStackLocation(Irp);
126 DPRINT("IrpSp 0x%X\n", Param);
128 Irp->Tail.Overlay.CurrentStackLocation--;
129 Irp->CurrentLocation--;
131 DPRINT("MajorFunction %d\n", Param->MajorFunction);
132 DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n",
133 DriverObject->MajorFunction[Param->MajorFunction]);
134 Status = DriverObject->MajorFunction[Param->MajorFunction](DeviceObject,
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
232 DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
233 Irp,PriorityBoost, Irp->UserEvent, PsGetCurrentThread());
235 for (i=Irp->CurrentLocation;i<(int)Irp->StackCount;i++)
237 if (Irp->Stack[i].CompletionRoutine != NULL)
239 Status = Irp->Stack[i].CompletionRoutine(
240 Irp->Stack[i].DeviceObject,
242 Irp->Stack[i].CompletionContext);
243 if (Status == STATUS_MORE_PROCESSING_REQUIRED)
247 *Irp->UserIosb=Irp->IoStatus;
252 if (Irp->Stack[i].Control & SL_PENDING_RETURNED)
254 Irp->PendingReturned = TRUE;
256 if (Irp->CurrentLocation < Irp->StackCount - 1)
258 IoSkipCurrentIrpStackLocation(Irp);
261 if (Irp->PendingReturned)
263 DPRINT("Dispatching APC\n");
265 KeInitializeApc(&Irp->Tail.Apc,
266 &Irp->Tail.Overlay.Thread->Tcb,
274 KeInsertQueueApc(&Irp->Tail.Apc,
276 (PVOID)(ULONG)PriorityBoost,
278 DPRINT("Finished dispatching APC\n");
279 #else /* !LIBCAPTIVE */
281 #endif /* !LIBCAPTIVE */
285 DPRINT("Calling completion routine directly\n");
286 IoSecondStageCompletion(Irp,PriorityBoost);
287 DPRINT("Finished completition routine\n");
293 IoCompleteRequest(PIRP Irp,
296 IofCompleteRequest(Irp,
301 /**********************************************************************
303 * IoIsOperationSynchronous@4
306 * Check if the I/O operation associated with the given IRP
310 * Irp Packet to check.
313 * TRUE if Irp's operation is synchronous; otherwise FALSE.
316 IoIsOperationSynchronous(IN PIRP Irp)
318 PFILE_OBJECT FileObject = NULL;
321 /* Check the FILE_OBJECT's flags first. */
322 FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
323 if (!(FO_SYNCHRONOUS_IO & FileObject->Flags))
325 /* Check IRP's flags. */
327 if (!((IRP_SYNCHRONOUS_API | IRP_SYNCHRONOUS_PAGING_IO) & Flags))
330 /* libcaptive is fully single-thread/single-process synchronous model. */
332 #endif /* LIBCAPTIVE */
337 /* Check more IRP's flags. */
339 if (!(IRP_PAGING_IO & Flags)
340 || (IRP_SYNCHRONOUS_PAGING_IO & Flags))
345 /* Otherwise, it is an asynchronous operation. */
347 /* libcaptive is fully single-thread/single-process synchronous model. */
349 #endif /* LIBCAPTIVE */
356 IoEnqueueIrp(IN PIRP Irp)
361 #endif /* LIBCAPTIVE */
364 IoSetTopLevelIrp(IN PIRP Irp)
368 Thread = PsGetCurrentThread();
369 Thread->TopLevelIrp->TopLevelIrp = Irp;
374 IoGetTopLevelIrp(VOID)
376 return(PsGetCurrentThread()->TopLevelIrp->TopLevelIrp);
382 IoQueueThreadIrp(IN PIRP Irp)
390 IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
399 IN PDEVICE_OBJECT DeviceObject,
400 IN DEVICE_REGISTRY_PROPERTY DeviceProperty,
401 IN ULONG BufferLength,
402 OUT PVOID PropertyBuffer,
403 OUT PULONG ResultLength)
411 IoOpenDeviceRegistryKey(
412 IN PDEVICE_OBJECT DeviceObject,
413 IN ULONG DevInstKeyType,
414 IN ACCESS_MASK DesiredAccess,
415 OUT PHANDLE DevInstRegKey)
422 #endif /* LIBCAPTIVE */