1 /* $Id: irp.c,v 1.45 2002/10/03 19:39:56 robd 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
);
80 IoInitializeIrp(PIRP Irp
,
84 * FUNCTION: Initalizes an irp allocated by the caller
86 * Irp = IRP to initalize
87 * PacketSize = Size in bytes of the IRP
88 * StackSize = Number of stack locations in the IRP
93 memset(Irp
, 0, PacketSize
);
94 Irp
->Size
= PacketSize
;
95 Irp
->StackCount
= StackSize
;
96 Irp
->CurrentLocation
= StackSize
;
97 Irp
->Tail
.Overlay
.CurrentStackLocation
= &Irp
->Stack
[(ULONG
)StackSize
];
102 IofCallDriver(PDEVICE_OBJECT DeviceObject
,
105 * 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 Param
= IoGetNextIrpStackLocation(Irp
);
123 DPRINT("IrpSp 0x%X\n", Param
);
125 Irp
->Tail
.Overlay
.CurrentStackLocation
--;
126 Irp
->CurrentLocation
--;
128 DPRINT("MajorFunction %d\n", Param
->MajorFunction
);
129 DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n",
130 DriverObject
->MajorFunction
[Param
->MajorFunction
]);
131 Status
= DriverObject
->MajorFunction
[Param
->MajorFunction
](DeviceObject
,
140 IoCallDriver (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
142 return(IofCallDriver(DeviceObject
,
148 IoAllocateIrp(CCHAR StackSize
,
151 * FUNCTION: Allocates an IRP
153 * StackSize = the size of the stack required for the irp
154 * ChargeQuota = Charge allocation to current threads quota
155 * RETURNS: Irp allocated
161 DbgPrint("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",
164 KeDumpStackFrames(0,8);
169 // Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
170 Irp
= ExAllocatePoolWithTag(NonPagedPool
,
171 IoSizeOfIrp(StackSize
),
176 Irp
= ExAllocatePoolWithTag(NonPagedPool
,
177 IoSizeOfIrp(StackSize
),
187 IoSizeOfIrp(StackSize
),
190 // DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation);
197 IopCompleteRequest(struct _KAPC
* Apc
,
198 PKNORMAL_ROUTINE
* NormalRoutine
,
199 PVOID
* NormalContext
,
200 PVOID
* SystemArgument1
,
201 PVOID
* SystemArgument2
)
203 DPRINT("IopCompleteRequest(Apc %x, SystemArgument1 %x, (*SystemArgument1) %x\n",
207 IoSecondStageCompletion((PIRP
)(*SystemArgument1
),
208 (KPRIORITY
)(*SystemArgument2
));
213 IofCompleteRequest(PIRP Irp
,
216 * FUNCTION: Indicates the caller has finished all processing for a given
217 * I/O request and is returning the given IRP to the I/O manager
219 * Irp = Irp to be cancelled
220 * PriorityBoost = Increment by which to boost the priority of the
221 * thread making the request
227 DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
228 Irp
,PriorityBoost
, Irp
->UserEvent
, PsGetCurrentThread());
230 for (i
=Irp
->CurrentLocation
;i
<Irp
->StackCount
;i
++)
232 if (Irp
->Stack
[i
].CompletionRoutine
!= NULL
)
234 Status
= Irp
->Stack
[i
].CompletionRoutine(
235 Irp
->Stack
[i
].DeviceObject
,
237 Irp
->Stack
[i
].CompletionContext
);
238 if (Status
== STATUS_MORE_PROCESSING_REQUIRED
)
243 if (Irp
->Stack
[i
].Control
& SL_PENDING_RETURNED
)
245 Irp
->PendingReturned
= TRUE
;
247 if (Irp
->CurrentLocation
< Irp
->StackCount
- 1)
249 IoSkipCurrentIrpStackLocation(Irp
);
252 if (Irp
->PendingReturned
)
254 DPRINT("Dispatching APC\n");
255 KeInitializeApc(&Irp
->Tail
.Apc
,
256 &Irp
->Tail
.Overlay
.Thread
->Tcb
,
264 KeInsertQueueApc(&Irp
->Tail
.Apc
,
266 (PVOID
)(ULONG
)PriorityBoost
,
268 DPRINT("Finished dispatching APC\n");
272 DPRINT("Calling completion routine directly\n");
273 IoSecondStageCompletion(Irp
,PriorityBoost
);
274 DPRINT("Finished completition routine\n");
280 IoCompleteRequest(PIRP Irp
,
283 IofCompleteRequest(Irp
,
288 /**********************************************************************
290 * IoIsOperationSynchronous@4
293 * Check if the I/O operation associated with the given IRP
297 * Irp Packet to check.
300 * TRUE if Irp's operation is synchronous; otherwise FALSE.
303 IoIsOperationSynchronous(IN PIRP Irp
)
305 PFILE_OBJECT FileObject
= NULL
;
308 /* Check the FILE_OBJECT's flags first. */
309 FileObject
= IoGetCurrentIrpStackLocation(Irp
)->FileObject
;
310 if (!(FO_SYNCHRONOUS_IO
& FileObject
->Flags
))
312 /* Check IRP's flags. */
314 if (!((IRP_SYNCHRONOUS_API
| IRP_SYNCHRONOUS_PAGING_IO
) & Flags
))
320 /* Check more IRP's flags. */
322 if (!(IRP_PAGING_IO
& Flags
)
323 || (IRP_SYNCHRONOUS_PAGING_IO
& Flags
))
328 /* Otherwise, it is an asynchronous operation. */
334 IoEnqueueIrp(IN PIRP Irp
)
341 IoSetTopLevelIrp(IN PIRP Irp
)
345 Thread
= PsGetCurrentThread();
346 Thread
->TopLevelIrp
->TopLevelIrp
= Irp
;
351 IoGetTopLevelIrp(VOID
)
353 return(PsGetCurrentThread()->TopLevelIrp
->TopLevelIrp
);
358 IoQueueThreadIrp(IN PIRP Irp
)
366 IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
375 IN PDEVICE_OBJECT DeviceObject,
376 IN DEVICE_REGISTRY_PROPERTY DeviceProperty,
377 IN ULONG BufferLength,
378 OUT PVOID PropertyBuffer,
379 OUT PULONG ResultLength)
387 IoOpenDeviceRegistryKey(
388 IN PDEVICE_OBJECT DeviceObject,
389 IN ULONG DevInstKeyType,
390 IN ACCESS_MASK DesiredAccess,
391 OUT PHANDLE DevInstRegKey)