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 if (Param->MajorFunction==IRP_MJ_FLUSH_BUFFERS)
139 ObDereferenceObject(Param->FileObject);
140 return STATUS_SUCCESS;
144 return DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, Irp);
150 IoCallDriver (PDEVICE_OBJECT DeviceObject, PIRP Irp)
152 return(IofCallDriver(DeviceObject,
158 IoAllocateIrp(CCHAR StackSize,
161 * FUNCTION: Allocates an IRP
163 * StackSize = the size of the stack required for the irp
164 * ChargeQuota = Charge allocation to current threads quota
165 * RETURNS: Irp allocated
171 DbgPrint("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",
174 KeDumpStackFrames(0,8);
179 // Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
180 Irp = ExAllocatePoolWithTag(NonPagedPool,
181 IoSizeOfIrp(StackSize),
186 Irp = ExAllocatePoolWithTag(NonPagedPool,
187 IoSizeOfIrp(StackSize),
197 IoSizeOfIrp(StackSize),
200 // DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation);
208 IopCompleteRequest(struct _KAPC* Apc,
209 PKNORMAL_ROUTINE* NormalRoutine,
210 PVOID* NormalContext,
211 PVOID* SystemArgument1,
212 PVOID* SystemArgument2)
214 DPRINT("IopCompleteRequest(Apc %x, SystemArgument1 %x, (*SystemArgument1) %x\n",
218 IoSecondStageCompletion((PIRP)(*SystemArgument1),
219 (KPRIORITY)(*SystemArgument2));
222 #endif /* LIBCAPTIVE */
226 /* file-scope of libcaptive/io/irp.c: */
227 extern void IofCompleteRequest_register_APC(PIRP Irp,CCHAR PriorityBoost);
228 #endif /* LIBCAPTIVE */
231 IofCompleteRequest(PIRP Irp,
234 * FUNCTION: Indicates the caller has finished all processing for a given
235 * I/O request and is returning the given IRP to the I/O manager
237 * Irp = Irp to be cancelled
238 * PriorityBoost = Increment by which to boost the priority of the
239 * thread making the request
244 PDEVICE_OBJECT DeviceObject;
246 DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
247 Irp,PriorityBoost, Irp->UserEvent, PsGetCurrentThread());
249 assert(Irp->CancelRoutine == NULL);
250 assert(Irp->IoStatus.Status != STATUS_PENDING);
252 if (IoGetCurrentIrpStackLocation(Irp)->Control & SL_PENDING_RETURNED)
254 Irp->PendingReturned = TRUE;
257 for (i=Irp->CurrentLocation;i<(ULONG)Irp->StackCount;i++)
260 Completion routines expect the current irp stack location to be the same as when
261 IoSetCompletionRoutine was called to set them. A side effect is that completion
262 routines set by highest level drivers without their own stack location will receive
263 an invalid current stack location (at least it should be considered as invalid).
264 Since the DeviceObject argument passed is taken from the current stack, this value
265 is also invalid (NULL).
267 if (Irp->CurrentLocation < Irp->StackCount - 1)
269 IoSetPreviousIrpStackLocation(Irp);
270 DeviceObject = IoGetCurrentIrpStackLocation(Irp)->DeviceObject;
277 if (Irp->Stack[i].CompletionRoutine != NULL &&
278 ((NT_SUCCESS(Irp->IoStatus.Status) && (Irp->Stack[i].Control & SL_INVOKE_ON_SUCCESS)) ||
279 (!NT_SUCCESS(Irp->IoStatus.Status) && (Irp->Stack[i].Control & SL_INVOKE_ON_ERROR)) ||
280 (Irp->Cancel && (Irp->Stack[i].Control & SL_INVOKE_ON_CANCEL))))
282 Status = Irp->Stack[i].CompletionRoutine(DeviceObject,
284 Irp->Stack[i].CompletionContext);
286 if (Status == STATUS_MORE_PROCESSING_REQUIRED)
290 *Irp->UserIosb=Irp->IoStatus;
296 if (IoGetCurrentIrpStackLocation(Irp)->Control & SL_PENDING_RETURNED)
298 Irp->PendingReturned = TRUE;
302 if (Irp->PendingReturned)
305 /* FIXME: Why the hell should we bother with some damned APCs?!?
306 * Call it directly below!
308 DPRINT("IofCompleteRequest() dispatching APC: using g_idle_add_full()\n");
309 IofCompleteRequest_register_APC(Irp,PriorityBoost);
310 #else /* !LIBCAPTIVE */
311 DPRINT("Dispatching APC\n");
312 KeInitializeApc(&Irp->Tail.Apc,
313 &Irp->Tail.Overlay.Thread->Tcb,
321 KeInsertQueueApc(&Irp->Tail.Apc,
323 (PVOID)(ULONG)PriorityBoost,
325 #endif /* !LIBCAPTIVE */
326 DPRINT("Finished dispatching APC\n");
330 DPRINT("Calling completion routine directly\n");
331 IoSecondStageCompletion(Irp,PriorityBoost);
332 DPRINT("Finished completition routine\n");
338 IoCompleteRequest(PIRP Irp,
341 IofCompleteRequest(Irp,
346 /**********************************************************************
348 * IoIsOperationSynchronous@4
351 * Check if the I/O operation associated with the given IRP
355 * Irp Packet to check.
358 * TRUE if Irp's operation is synchronous; otherwise FALSE.
361 IoIsOperationSynchronous(IN PIRP Irp)
363 PFILE_OBJECT FileObject = NULL;
366 /* Check the FILE_OBJECT's flags first. */
367 FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
368 if (FileObject == NULL)
370 if (!(FO_SYNCHRONOUS_IO & FileObject->Flags))
372 /* Check IRP's flags. */
374 if (!((IRP_SYNCHRONOUS_API | IRP_SYNCHRONOUS_PAGING_IO) & Flags))
377 /* libcaptive is fully single-thread/single-process synchronous model. */
379 #endif /* LIBCAPTIVE */
384 /* Check more IRP's flags. */
386 if (!(IRP_PAGING_IO & Flags)
387 || (IRP_SYNCHRONOUS_PAGING_IO & Flags))
392 /* Otherwise, it is an asynchronous operation. */
394 /* libcaptive is fully single-thread/single-process synchronous model. */
396 #endif /* LIBCAPTIVE */
403 IoEnqueueIrp(IN PIRP Irp)
408 #endif /* LIBCAPTIVE */
411 IoSetTopLevelIrp(IN PIRP Irp)
415 Thread = PsGetCurrentThread();
416 Thread->TopLevelIrp->TopLevelIrp = Irp;
421 IoGetTopLevelIrp(VOID)
423 return(PsGetCurrentThread()->TopLevelIrp->TopLevelIrp);
429 IoQueueThreadIrp(IN PIRP Irp)
437 IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
446 IN PDEVICE_OBJECT DeviceObject,
447 IN DEVICE_REGISTRY_PROPERTY DeviceProperty,
448 IN ULONG BufferLength,
449 OUT PVOID PropertyBuffer,
450 OUT PULONG ResultLength)
458 IoOpenDeviceRegistryKey(
459 IN PDEVICE_OBJECT DeviceObject,
460 IN ULONG DevInstKeyType,
461 IN ACCESS_MASK DesiredAccess,
462 OUT PHANDLE DevInstRegKey)
469 #endif /* LIBCAPTIVE */