1 /* $Id: irp.c,v 1.39 2002/01/21 22:30:26 hbirr 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', ' ')
45 /* FUNCTIONS ****************************************************************/
51 * FUNCTION: Releases a caller allocated irp
61 IoMakeAssociatedIrp (PIRP Irp
, CCHAR StackSize
)
63 * FUNCTION: Allocates and initializes an irp to associated with a master irp
66 * StackSize = Number of stack locations to be allocated in the irp
67 * RETURNS: The irp allocated
72 AssocIrp
= IoAllocateIrp(StackSize
,FALSE
);
78 IoInitializeIrp (PIRP Irp
, USHORT PacketSize
, CCHAR StackSize
)
80 * FUNCTION: Initalizes an irp allocated by the caller
82 * Irp = IRP to initalize
83 * PacketSize = Size in bytes of the IRP
84 * StackSize = Number of stack locations in the IRP
89 memset(Irp
, 0, PacketSize
);
90 Irp
->Size
= PacketSize
;
91 Irp
->StackCount
= StackSize
;
92 Irp
->CurrentLocation
= StackSize
;
93 Irp
->Tail
.Overlay
.CurrentStackLocation
= &Irp
->Stack
[(ULONG
)StackSize
];
98 IofCallDriver (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
100 * FUNCTION: Sends an IRP to the next lower driver
104 PDRIVER_OBJECT DriverObject
;
105 PIO_STACK_LOCATION Param
;
107 DPRINT("IofCallDriver(DeviceObject %x, Irp %x)\n",DeviceObject
,Irp
);
110 assert(DeviceObject
);
112 DriverObject
= DeviceObject
->DriverObject
;
114 assert(DriverObject
);
116 Param
= IoGetNextIrpStackLocation(Irp
);
118 DPRINT("IrpSp 0x%X\n", Param
);
120 Irp
->Tail
.Overlay
.CurrentStackLocation
--;
121 Irp
->CurrentLocation
--;
123 DPRINT("MajorFunction %d\n", Param
->MajorFunction
);
124 DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n",
125 DriverObject
->MajorFunction
[Param
->MajorFunction
]);
126 Status
= DriverObject
->MajorFunction
[Param
->MajorFunction
](DeviceObject
,
134 IoCallDriver (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
136 return IofCallDriver (
145 IoAllocateIrp (CCHAR StackSize
, BOOLEAN ChargeQuota
)
147 * FUNCTION: Allocates an IRP
149 * StackSize = the size of the stack required for the irp
150 * ChargeQuota = Charge allocation to current threads quota
151 * RETURNS: Irp allocated
157 DbgPrint("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",
160 KeDumpStackFrames(0,8);
165 // Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
166 Irp
= ExAllocatePoolWithTag(NonPagedPool
, IoSizeOfIrp(StackSize
),
171 Irp
= ExAllocatePoolWithTag(NonPagedPool
,IoSizeOfIrp(StackSize
),
180 IoInitializeIrp(Irp
, IoSizeOfIrp(StackSize
), StackSize
);
182 // DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation);
189 IopCompleteRequest(struct _KAPC
* Apc
,
190 PKNORMAL_ROUTINE
* NormalRoutine
,
191 PVOID
* NormalContext
,
192 PVOID
* SystemArgument1
,
193 PVOID
* SystemArgument2
)
195 DPRINT("IopCompleteRequest(Apc %x, SystemArgument1 %x, "
196 "(*SystemArgument1) %x\n", Apc
, SystemArgument1
,
198 IoSecondStageCompletion((PIRP
)(*SystemArgument1
),
199 (KPRIORITY
)(*SystemArgument2
));
204 IofCompleteRequest(PIRP Irp
,
207 * FUNCTION: Indicates the caller has finished all processing for a given
208 * I/O request and is returning the given IRP to the I/O manager
210 * Irp = Irp to be cancelled
211 * PriorityBoost = Increment by which to boost the priority of the
212 * thread making the request
218 DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
219 Irp
,PriorityBoost
, Irp
->UserEvent
, PsGetCurrentThread());
221 for (i
=0;i
<Irp
->StackCount
;i
++)
223 if (Irp
->Stack
[i
].CompletionRoutine
!= NULL
)
225 Status
= Irp
->Stack
[i
].CompletionRoutine(
226 Irp
->Stack
[i
].DeviceObject
,
228 Irp
->Stack
[i
].CompletionContext
);
229 if (Status
== STATUS_MORE_PROCESSING_REQUIRED
)
234 if (Irp
->Stack
[i
].Control
& SL_PENDING_RETURNED
)
236 Irp
->PendingReturned
= TRUE
;
239 if (Irp
->PendingReturned
)
241 DPRINT("Dispatching APC\n");
242 KeInitializeApc(&Irp
->Tail
.Apc
,
243 &Irp
->Tail
.Overlay
.Thread
->Tcb
,
251 KeInsertQueueApc(&Irp
->Tail
.Apc
,
253 (PVOID
)(ULONG
)PriorityBoost
,
255 DPRINT("Finished dispatching APC\n");
259 DPRINT("Calling completion routine directly\n");
260 IoSecondStageCompletion(Irp
,PriorityBoost
);
261 DPRINT("Finished completition routine\n");
268 IoCompleteRequest (PIRP Irp
, CCHAR PriorityBoost
)
277 /**********************************************************************
279 * IoIsOperationSynchronous@4
282 * Check if the I/O operation associated with the given IRP
286 * Irp Packet to check.
289 * TRUE if Irp's operation is synchronous; otherwise FALSE.
293 IoIsOperationSynchronous (
298 PFILE_OBJECT FileObject
= NULL
;
301 * Check the associated FILE_OBJECT's
304 FileObject
= Irp
->Tail
.Overlay
.OriginalFileObject
;
305 if (!(FO_SYNCHRONOUS_IO
& FileObject
->Flags
))
307 /* Check IRP's flags. */
309 if (!( (IRP_SYNCHRONOUS_API
| IRP_SYNCHRONOUS_PAGING_IO
)
317 * Check more IRP's flags.
320 if ( !(IRP_MOUNT_COMPLETION
& Flags
)
321 || (IRP_SYNCHRONOUS_PAGING_IO
& Flags
)
327 * Otherwise, it is an
328 * asynchronous operation.
352 Thread
= PsGetCurrentThread ();
353 Thread
->TopLevelIrp
->TopLevelIrp
= Irp
;
363 return (PsGetCurrentThread ()->TopLevelIrp
->TopLevelIrp
);