1 /* $Id: irp.c,v 1.48 2003/05/16 12:03:11 chorns Exp $
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
62 IoMakeAssociatedIrp(PIRP Irp
,
65 * FUNCTION: Allocates and initializes an irp to associated with a master irp
68 * StackSize = Number of stack locations to be allocated in the irp
69 * RETURNS: The irp allocated
74 AssocIrp
= IoAllocateIrp(StackSize
,FALSE
);
81 IoInitializeIrp(PIRP Irp
,
85 * FUNCTION: Initalizes an irp allocated by the caller
87 * Irp = IRP to initalize
88 * PacketSize = Size in bytes of the IRP
89 * StackSize = Number of stack locations in the IRP
94 memset(Irp
, 0, PacketSize
);
95 Irp
->Size
= PacketSize
;
96 Irp
->StackCount
= StackSize
;
97 Irp
->CurrentLocation
= StackSize
;
98 Irp
->Tail
.Overlay
.CurrentStackLocation
= &Irp
->Stack
[(ULONG
)StackSize
];
103 IofCallDriver(PDEVICE_OBJECT DeviceObject
,
106 * FUNCTION: Sends an IRP to the next lower driver
109 PDRIVER_OBJECT DriverObject
;
110 PIO_STACK_LOCATION Param
;
112 DPRINT("IofCallDriver(DeviceObject %x, Irp %x)\n",DeviceObject
,Irp
);
115 assert(DeviceObject
);
117 DriverObject
= DeviceObject
->DriverObject
;
119 assert(DriverObject
);
121 IoSetNextIrpStackLocation(Irp
);
122 Param
= IoGetCurrentIrpStackLocation(Irp
);
124 DPRINT("IrpSp 0x%X\n", Param
);
126 Param
->DeviceObject
= DeviceObject
;
128 DPRINT("MajorFunction %d\n", Param
->MajorFunction
);
129 DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n",
130 DriverObject
->MajorFunction
[Param
->MajorFunction
]);
132 if ((Param
->FileObject
) && (Param
->MajorFunction
!= IRP_MJ_CLOSE
))
134 ObReferenceObject(Param
->FileObject
);
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);
200 IopCompleteRequest(struct _KAPC
* Apc
,
201 PKNORMAL_ROUTINE
* NormalRoutine
,
202 PVOID
* NormalContext
,
203 PVOID
* SystemArgument1
,
204 PVOID
* SystemArgument2
)
206 DPRINT("IopCompleteRequest(Apc %x, SystemArgument1 %x, (*SystemArgument1) %x\n",
210 IoSecondStageCompletion((PIRP
)(*SystemArgument1
),
211 (KPRIORITY
)(*SystemArgument2
));
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
;
231 DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
232 Irp
,PriorityBoost
, Irp
->UserEvent
, PsGetCurrentThread());
234 assert(Irp
->CancelRoutine
== NULL
);
235 assert(Irp
->IoStatus
.Status
!= STATUS_PENDING
);
237 if (IoGetCurrentIrpStackLocation(Irp
)->Control
& SL_PENDING_RETURNED
)
239 Irp
->PendingReturned
= TRUE
;
242 for (i
=Irp
->CurrentLocation
;i
<(ULONG
)Irp
->StackCount
;i
++)
245 Completion routines expect the current irp stack location to be the same as when
246 IoSetCompletionRoutine was called to set them. A side effect is that completion
247 routines set by highest level drivers without their own stack location will receive
248 an invalid current stack location (at least it should be considered as invalid).
249 Since the DeviceObject argument passed is taken from the current stack, this value
250 is also invalid (NULL).
252 if (Irp
->CurrentLocation
< Irp
->StackCount
- 1)
254 IoSetPreviousIrpStackLocation(Irp
);
255 DeviceObject
= IoGetCurrentIrpStackLocation(Irp
)->DeviceObject
;
262 if (Irp
->Stack
[i
].CompletionRoutine
!= NULL
&&
263 ((NT_SUCCESS(Irp
->IoStatus
.Status
) && (Irp
->Stack
[i
].Control
& SL_INVOKE_ON_SUCCESS
)) ||
264 (!NT_SUCCESS(Irp
->IoStatus
.Status
) && (Irp
->Stack
[i
].Control
& SL_INVOKE_ON_ERROR
)) ||
265 (Irp
->Cancel
&& (Irp
->Stack
[i
].Control
& SL_INVOKE_ON_CANCEL
))))
267 Status
= Irp
->Stack
[i
].CompletionRoutine(DeviceObject
,
269 Irp
->Stack
[i
].CompletionContext
);
271 if (Status
== STATUS_MORE_PROCESSING_REQUIRED
)
277 if (IoGetCurrentIrpStackLocation(Irp
)->Control
& SL_PENDING_RETURNED
)
279 Irp
->PendingReturned
= TRUE
;
283 if (Irp
->PendingReturned
)
285 DPRINT("Dispatching APC\n");
286 KeInitializeApc(&Irp
->Tail
.Apc
,
287 &Irp
->Tail
.Overlay
.Thread
->Tcb
,
295 KeInsertQueueApc(&Irp
->Tail
.Apc
,
297 (PVOID
)(ULONG
)PriorityBoost
,
299 DPRINT("Finished dispatching APC\n");
303 DPRINT("Calling completion routine directly\n");
304 IoSecondStageCompletion(Irp
,PriorityBoost
);
305 DPRINT("Finished completition routine\n");
311 IoCompleteRequest(PIRP Irp
,
314 IofCompleteRequest(Irp
,
319 /**********************************************************************
321 * IoIsOperationSynchronous@4
324 * Check if the I/O operation associated with the given IRP
328 * Irp Packet to check.
331 * TRUE if Irp's operation is synchronous; otherwise FALSE.
334 IoIsOperationSynchronous(IN PIRP Irp
)
336 PFILE_OBJECT FileObject
= NULL
;
339 /* Check the FILE_OBJECT's flags first. */
340 FileObject
= IoGetCurrentIrpStackLocation(Irp
)->FileObject
;
341 if (!(FO_SYNCHRONOUS_IO
& FileObject
->Flags
))
343 /* Check IRP's flags. */
345 if (!((IRP_SYNCHRONOUS_API
| IRP_SYNCHRONOUS_PAGING_IO
) & Flags
))
351 /* Check more IRP's flags. */
353 if (!(IRP_PAGING_IO
& Flags
)
354 || (IRP_SYNCHRONOUS_PAGING_IO
& Flags
))
359 /* Otherwise, it is an asynchronous operation. */
365 IoEnqueueIrp(IN PIRP Irp
)
372 IoSetTopLevelIrp(IN PIRP Irp
)
376 Thread
= PsGetCurrentThread();
377 Thread
->TopLevelIrp
->TopLevelIrp
= Irp
;
382 IoGetTopLevelIrp(VOID
)
384 return(PsGetCurrentThread()->TopLevelIrp
->TopLevelIrp
);
389 IoQueueThreadIrp(IN PIRP Irp
)
397 IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
406 IN PDEVICE_OBJECT DeviceObject,
407 IN DEVICE_REGISTRY_PROPERTY DeviceProperty,
408 IN ULONG BufferLength,
409 OUT PVOID PropertyBuffer,
410 OUT PULONG ResultLength)
418 IoOpenDeviceRegistryKey(
419 IN PDEVICE_OBJECT DeviceObject,
420 IN ULONG DevInstKeyType,
421 IN ACCESS_MASK DesiredAccess,
422 OUT PHANDLE DevInstRegKey)