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 if (!DriverObject->MajorFunction[Param->MajorFunction])
136 Status = DriverObject->MajorFunction[Param->MajorFunction](DeviceObject,
145 IoCallDriver (PDEVICE_OBJECT DeviceObject, PIRP Irp)
147 return(IofCallDriver(DeviceObject,
153 IoAllocateIrp(CCHAR StackSize,
156 * FUNCTION: Allocates an IRP
158 * StackSize = the size of the stack required for the irp
159 * ChargeQuota = Charge allocation to current threads quota
160 * RETURNS: Irp allocated
166 DbgPrint("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",
169 KeDumpStackFrames(0,8);
174 // Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
175 Irp = ExAllocatePoolWithTag(NonPagedPool,
176 IoSizeOfIrp(StackSize),
181 Irp = ExAllocatePoolWithTag(NonPagedPool,
182 IoSizeOfIrp(StackSize),
192 IoSizeOfIrp(StackSize),
195 // DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation);
203 IopCompleteRequest(struct _KAPC* Apc,
204 PKNORMAL_ROUTINE* NormalRoutine,
205 PVOID* NormalContext,
206 PVOID* SystemArgument1,
207 PVOID* SystemArgument2)
209 DPRINT("IopCompleteRequest(Apc %x, SystemArgument1 %x, (*SystemArgument1) %x\n",
213 IoSecondStageCompletion((PIRP)(*SystemArgument1),
214 (KPRIORITY)(*SystemArgument2));
217 #endif /* LIBCAPTIVE */
220 IofCompleteRequest(PIRP Irp,
223 * FUNCTION: Indicates the caller has finished all processing for a given
224 * I/O request and is returning the given IRP to the I/O manager
226 * Irp = Irp to be cancelled
227 * PriorityBoost = Increment by which to boost the priority of the
228 * thread making the request
234 DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
235 Irp,PriorityBoost, Irp->UserEvent, PsGetCurrentThread());
237 for (i=Irp->CurrentLocation;i<(int)Irp->StackCount;i++)
239 if (Irp->Stack[i].CompletionRoutine != NULL)
241 Status = Irp->Stack[i].CompletionRoutine(
242 Irp->Stack[i].DeviceObject,
244 Irp->Stack[i].CompletionContext);
245 if (Status == STATUS_MORE_PROCESSING_REQUIRED)
249 *Irp->UserIosb=Irp->IoStatus;
254 if (Irp->Stack[i].Control & SL_PENDING_RETURNED)
256 Irp->PendingReturned = TRUE;
258 if (Irp->CurrentLocation < Irp->StackCount - 1)
260 IoSkipCurrentIrpStackLocation(Irp);
263 if (Irp->PendingReturned)
265 DPRINT("Dispatching APC\n");
267 KeInitializeApc(&Irp->Tail.Apc,
268 &Irp->Tail.Overlay.Thread->Tcb,
276 KeInsertQueueApc(&Irp->Tail.Apc,
278 (PVOID)(ULONG)PriorityBoost,
280 DPRINT("Finished dispatching APC\n");
281 #else /* !LIBCAPTIVE */
283 #endif /* !LIBCAPTIVE */
287 DPRINT("Calling completion routine directly\n");
288 IoSecondStageCompletion(Irp,PriorityBoost);
289 DPRINT("Finished completition routine\n");
295 IoCompleteRequest(PIRP Irp,
298 IofCompleteRequest(Irp,
303 /**********************************************************************
305 * IoIsOperationSynchronous@4
308 * Check if the I/O operation associated with the given IRP
312 * Irp Packet to check.
315 * TRUE if Irp's operation is synchronous; otherwise FALSE.
318 IoIsOperationSynchronous(IN PIRP Irp)
320 PFILE_OBJECT FileObject = NULL;
323 /* Check the FILE_OBJECT's flags first. */
324 FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
325 if (!(FO_SYNCHRONOUS_IO & FileObject->Flags))
327 /* Check IRP's flags. */
329 if (!((IRP_SYNCHRONOUS_API | IRP_SYNCHRONOUS_PAGING_IO) & Flags))
332 /* libcaptive is fully single-thread/single-process synchronous model. */
334 #endif /* LIBCAPTIVE */
339 /* Check more IRP's flags. */
341 if (!(IRP_PAGING_IO & Flags)
342 || (IRP_SYNCHRONOUS_PAGING_IO & Flags))
347 /* Otherwise, it is an asynchronous operation. */
349 /* libcaptive is fully single-thread/single-process synchronous model. */
351 #endif /* LIBCAPTIVE */
358 IoEnqueueIrp(IN PIRP Irp)
363 #endif /* LIBCAPTIVE */
366 IoSetTopLevelIrp(IN PIRP Irp)
370 Thread = PsGetCurrentThread();
371 Thread->TopLevelIrp->TopLevelIrp = Irp;
376 IoGetTopLevelIrp(VOID)
378 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)
424 #endif /* LIBCAPTIVE */