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 ****************************************************************/
55 * FUNCTION: Releases a caller allocated irp
68 IoMakeAssociatedIrp(PIRP Irp,
71 * FUNCTION: Allocates and initializes an irp to associated with a master irp
74 * StackSize = Number of stack locations to be allocated in the irp
75 * RETURNS: The irp allocated
80 AssocIrp = IoAllocateIrp(StackSize,FALSE);
90 IoInitializeIrp(PIRP Irp,
94 * FUNCTION: Initalizes an irp allocated by the caller
96 * Irp = IRP to initalize
97 * PacketSize = Size in bytes of the IRP
98 * StackSize = Number of stack locations in the IRP
103 memset(Irp, 0, PacketSize);
104 Irp->Size = PacketSize;
105 Irp->StackCount = StackSize;
106 Irp->CurrentLocation = StackSize;
107 Irp->Tail.Overlay.CurrentStackLocation = &Irp->Stack[(ULONG)StackSize];
115 IofCallDriver(PDEVICE_OBJECT DeviceObject,
118 * FUNCTION: Sends an IRP to the next lower driver
121 PDRIVER_OBJECT DriverObject;
122 PIO_STACK_LOCATION Param;
124 DPRINT("IofCallDriver(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
127 assert(DeviceObject);
129 DriverObject = DeviceObject->DriverObject;
131 assert(DriverObject);
133 IoSetNextIrpStackLocation(Irp);
134 Param = IoGetCurrentIrpStackLocation(Irp);
136 DPRINT("IrpSp 0x%X\n", Param);
138 Param->DeviceObject = DeviceObject;
140 DPRINT("MajorFunction %d\n", Param->MajorFunction);
141 DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n",
142 DriverObject->MajorFunction[Param->MajorFunction]);
144 return DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, Irp);
153 IoCallDriver (PDEVICE_OBJECT DeviceObject, PIRP Irp)
155 return(IofCallDriver(DeviceObject,
164 IoAllocateIrp(CCHAR StackSize,
167 * FUNCTION: Allocates an IRP
169 * StackSize = the size of the stack required for the irp
170 * ChargeQuota = Charge allocation to current threads quota
171 * RETURNS: Irp allocated
177 DbgPrint("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",
180 KeDumpStackFrames(0,8);
185 // Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
186 Irp = ExAllocatePoolWithTag(NonPagedPool,
187 IoSizeOfIrp(StackSize),
192 Irp = ExAllocatePoolWithTag(NonPagedPool,
193 IoSizeOfIrp(StackSize),
203 IoSizeOfIrp(StackSize),
206 // DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation);
216 IofCompleteRequest(PIRP Irp,
219 * FUNCTION: Indicates the caller has finished all processing for a given
220 * I/O request and is returning the given IRP to the I/O manager
222 * Irp = Irp to be cancelled
223 * PriorityBoost = Increment by which to boost the priority of the
224 * thread making the request
229 PDEVICE_OBJECT DeviceObject;
230 PFILE_OBJECT OriginalFileObject;
232 DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
233 Irp,PriorityBoost, Irp->UserEvent, PsGetCurrentThread());
235 assert(Irp->CancelRoutine == NULL);
236 assert(Irp->IoStatus.Status != STATUS_PENDING);
238 if (IoGetCurrentIrpStackLocation(Irp)->Control & SL_PENDING_RETURNED)
240 Irp->PendingReturned = TRUE;
243 for (i=Irp->CurrentLocation;i<(ULONG)Irp->StackCount;i++)
246 Completion routines expect the current irp stack location to be the same as when
247 IoSetCompletionRoutine was called to set them. A side effect is that completion
248 routines set by highest level drivers without their own stack location will receive
249 an invalid current stack location (at least it should be considered as invalid).
250 Since the DeviceObject argument passed is taken from the current stack, this value
251 is also invalid (NULL).
253 if (Irp->CurrentLocation < Irp->StackCount - 1)
255 IoSetPreviousIrpStackLocation(Irp);
256 DeviceObject = IoGetCurrentIrpStackLocation(Irp)->DeviceObject;
263 if (Irp->Stack[i].CompletionRoutine != NULL &&
264 ((NT_SUCCESS(Irp->IoStatus.Status) && (Irp->Stack[i].Control & SL_INVOKE_ON_SUCCESS)) ||
265 (!NT_SUCCESS(Irp->IoStatus.Status) && (Irp->Stack[i].Control & SL_INVOKE_ON_ERROR)) ||
266 (Irp->Cancel && (Irp->Stack[i].Control & SL_INVOKE_ON_CANCEL))))
268 Status = Irp->Stack[i].CompletionRoutine(DeviceObject,
270 Irp->Stack[i].Context);
272 if (Status == STATUS_MORE_PROCESSING_REQUIRED)
278 if (IoGetCurrentIrpStackLocation(Irp)->Control & SL_PENDING_RETURNED)
280 Irp->PendingReturned = TRUE;
284 //Windows NT File System Internals, page 154
285 OriginalFileObject = Irp->Tail.Overlay.OriginalFileObject;
287 if (Irp->PendingReturned)
291 DPRINT("Dispatching APC\n");
292 KeInitializeApc( &Irp->Tail.Apc,
293 &Irp->Tail.Overlay.Thread->Tcb,
294 OriginalApcEnvironment,
295 IoSecondStageCompletion,
297 (PKNORMAL_ROUTINE) NULL,
301 bStatus = KeInsertQueueApc(&Irp->Tail.Apc,
303 (PVOID)(ULONG)PriorityBoost,
306 if (bStatus == FALSE)
308 DPRINT1("Error queueing APC for thread. Thread has probably exited.\n");
311 DPRINT("Finished dispatching APC\n");
315 DPRINT("Calling IoSecondStageCompletion routine directly\n");
316 IoSecondStageCompletion(NULL,NULL,(PVOID)&OriginalFileObject,(PVOID) &Irp,(PVOID) &PriorityBoost);
317 DPRINT("Finished completition routine\n");
327 IoCompleteRequest(PIRP Irp,
330 IofCompleteRequest(Irp,
335 /**********************************************************************
337 * IoIsOperationSynchronous@4
340 * Check if the I/O operation associated with the given IRP
344 * Irp Packet to check.
347 * TRUE if Irp's operation is synchronous; otherwise FALSE.
352 IoIsOperationSynchronous(IN PIRP Irp)
354 PFILE_OBJECT FileObject = NULL;
356 FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
358 if (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO)
363 if (Irp->Flags & IRP_PAGING_IO)
368 //NOTE: Windows 2000 crash if IoStack->FileObject == NULL, so I guess we should too;-)
369 if (Irp->Flags & IRP_SYNCHRONOUS_API || FileObject->Flags & FO_SYNCHRONOUS_IO)
374 /* Otherwise, it is an asynchronous operation. */
383 IoEnqueueIrp(IN PIRP Irp)
393 IoSetTopLevelIrp(IN PIRP Irp)
397 Thread = PsGetCurrentThread();
398 Thread->TopLevelIrp->TopLevelIrp = Irp;
406 IoGetTopLevelIrp(VOID)
408 return(PsGetCurrentThread()->TopLevelIrp->TopLevelIrp);
416 IoQueueThreadIrp(IN PIRP Irp)