1 /* $Id: irp.c,v 1.26 2000/03/06 01:02:30 ea 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>
35 #include <internal/string.h>
36 #include <internal/io.h>
39 #include <internal/debug.h>
41 /* FUNCTIONS ****************************************************************/
45 IoGetDeviceToVerify (PETHREAD Thread
)
47 * FUNCTION: Returns a pointer to the device, representing a removable-media
48 * device, that is the target of the given thread's I/O request
59 * FUNCTION: Releases a caller allocated irp
70 IoMakeAssociatedIrp (PIRP Irp
, CCHAR StackSize
)
72 * FUNCTION: Allocates and initializes an irp to associated with a master irp
75 * StackSize = Number of stack locations to be allocated in the irp
76 * RETURNS: The irp allocated
81 AssocIrp
= IoAllocateIrp(StackSize
,FALSE
);
86 /**********************************************************************
91 IoMarkIrpPending (PIRP Irp
)
93 * FUNCTION: Marks the specified irp, indicating further processing will
94 * be required by other driver routines
99 // DPRINT("IoGetCurrentIrpStackLocation(Irp) %x\n",
100 // IoGetCurrentIrpStackLocation(Irp));
101 IoGetCurrentIrpStackLocation(Irp
)->Control
|= SL_PENDING_RETURNED
;
105 /**********************************************************************
110 IoSizeOfIrp (CCHAR StackSize
)
112 * FUNCTION: Determines the size of an IRP
114 * StackSize = number of stack locations in the IRP
115 * RETURNS: The size of the IRP in bytes
118 return(sizeof(IRP
)+((StackSize
-1)*sizeof(IO_STACK_LOCATION
)));
124 IoInitializeIrp (PIRP Irp
, USHORT PacketSize
, CCHAR StackSize
)
126 * FUNCTION: Initalizes an irp allocated by the caller
128 * Irp = IRP to initalize
129 * PacketSize = Size in bytes of the IRP
130 * StackSize = Number of stack locations in the IRP
135 memset(Irp
, 0, PacketSize
);
136 Irp
->Size
= PacketSize
;
137 Irp
->StackCount
= StackSize
;
138 Irp
->CurrentLocation
= StackSize
;
139 Irp
->Tail
.Overlay
.CurrentStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
143 /**********************************************************************
145 * IoGetCurrentIrpStackLocation
148 IoGetCurrentIrpStackLocation (PIRP Irp
)
150 * FUNCTION: Gets a pointer to the callers location in the I/O stack in
153 * Irp = Points to the IRP
154 * RETURNS: A pointer to the stack location
157 // DPRINT("IoGetCurrentIrpStackLocation: Irp %08lx CurLoc %d StkCnt %d\n",
159 // Irp->CurrentLocation,
162 return(&Irp
->Stack
[(ULONG
)Irp
->CurrentLocation
]);
166 /**********************************************************************
168 * IoSetNextIrpStackLocation
171 IoSetNextIrpStackLocation (PIRP Irp
)
173 Irp
->CurrentLocation
--;
174 Irp
->Tail
.Overlay
.CurrentStackLocation
--;
178 /**********************************************************************
180 * IoGetNextIrpStackLocation
183 IoGetNextIrpStackLocation (PIRP Irp
)
185 * FUNCTION: Gives a higher level driver access to the next lower driver's
188 * Irp = points to the irp
189 * RETURNS: A pointer to the stack location
192 // DPRINT("IoGetNextIrpStackLocation(Irp %x)\n",Irp);
195 // DPRINT("Irp %x Irp->StackPtr %x\n",Irp,Irp->CurrentLocation);
196 return(&Irp
->Stack
[Irp
->CurrentLocation
-1]);
202 IofCallDriver (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
204 * FUNCTION: Sends an IRP to the next lower driver
208 PDRIVER_OBJECT DriverObject
;
209 PIO_STACK_LOCATION Param
;
211 // DPRINT("IoCallDriver(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
213 DriverObject
= DeviceObject
->DriverObject
;
214 Param
= IoGetNextIrpStackLocation(Irp
);
216 Irp
->Tail
.Overlay
.CurrentStackLocation
--;
217 Irp
->CurrentLocation
--;
219 // DPRINT("MajorFunction %d\n", Param->MajorFunction);
220 // DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n",
221 // DriverObject->MajorFunction[Param->MajorFunction]);
222 Status
= DriverObject
->MajorFunction
[Param
->MajorFunction
](DeviceObject
,
230 IoCallDriver (PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
232 return IofCallDriver (
241 IoAllocateIrp (CCHAR StackSize
, BOOLEAN ChargeQuota
)
243 * FUNCTION: Allocates an IRP
245 * StackSize = the size of the stack required for the irp
246 * ChargeQuota = Charge allocation to current threads quota
247 * RETURNS: Irp allocated
253 DbgPrint("IoAllocateIrp(StackSize %d ChargeQuota %d)\n",
256 KeDumpStackFrames(0,8);
261 // Irp = ExAllocatePoolWithQuota(NonPagedPool,IoSizeOfIrp(StackSize));
262 Irp
= ExAllocatePool(NonPagedPool
,IoSizeOfIrp(StackSize
));
266 Irp
= ExAllocatePool(NonPagedPool
,IoSizeOfIrp(StackSize
));
274 IoInitializeIrp(Irp
, IoSizeOfIrp(StackSize
), StackSize
);
276 // DPRINT("Irp %x Irp->StackPtr %d\n", Irp, Irp->CurrentLocation);
282 /**********************************************************************
284 * IoSetCompletionRoutine
287 IoSetCompletionRoutine (PIRP Irp
,
288 PIO_COMPLETION_ROUTINE CompletionRoutine
,
290 BOOLEAN InvokeOnSuccess
,
291 BOOLEAN InvokeOnError
,
292 BOOLEAN InvokeOnCancel
)
294 IO_STACK_LOCATION
* param
= IoGetNextIrpStackLocation(Irp
);
296 param
->CompletionRoutine
=CompletionRoutine
;
297 param
->CompletionContext
=Context
;
300 param
->Control
= param
->Control
| SL_INVOKE_ON_SUCCESS
;
304 param
->Control
= param
->Control
| SL_INVOKE_ON_ERROR
;
308 param
->Control
= param
->Control
| SL_INVOKE_ON_CANCEL
;
312 VOID
IopCompleteRequest(struct _KAPC
* Apc
,
313 PKNORMAL_ROUTINE
* NormalRoutine
,
314 PVOID
* NormalContext
,
315 PVOID
* SystemArgument1
,
316 PVOID
* SystemArgument2
)
318 DPRINT("IopCompleteRequest(Apc %x, SystemArgument1 %x, "
319 "(*SystemArgument1) %x\n", Apc
, SystemArgument1
,
321 IoSecondStageCompletion((PIRP
)(*SystemArgument1
),
322 (KPRIORITY
)(*SystemArgument2
));
328 IofCompleteRequest (PIRP Irp
, CCHAR PriorityBoost
)
330 * FUNCTION: Indicates the caller has finished all processing for a given
331 * I/O request and is returning the given IRP to the I/O manager
333 * Irp = Irp to be cancelled
334 * PriorityBoost = Increment by which to boost the priority of the
335 * thread making the request
342 DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
343 Irp
,PriorityBoost
, Irp
->UserEvent
, PsGetCurrentThread());
345 for (i
=0;i
<Irp
->StackCount
;i
++)
347 if (Irp
->Stack
[i
].CompletionRoutine
!= NULL
)
349 Status
= Irp
->Stack
[i
].CompletionRoutine(
350 Irp
->Stack
[i
].DeviceObject
,
352 Irp
->Stack
[i
].CompletionContext
);
353 if (Status
== STATUS_MORE_PROCESSING_REQUIRED
)
358 if (Irp
->Stack
[i
].Control
& SL_PENDING_RETURNED
)
360 Irp
->PendingReturned
= TRUE
;
364 if (Irp
->PendingReturned
)
366 DPRINT("Dispatching APC\n");
367 Thread
= &Irp
->Tail
.Overlay
.Thread
->Tcb
;
368 KeInitializeApc(&Irp
->Tail
.Apc
,
374 Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
,
377 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
);
378 KeInsertQueueApc(&Irp
->Tail
.Apc
,
380 (PVOID
)(ULONG
)PriorityBoost
,
382 DPRINT("Finished dispatching APC\n");
386 DPRINT("Calling completion routine directly\n");
387 IoSecondStageCompletion(Irp
,PriorityBoost
);
388 DPRINT("Finished completition routine\n");
395 IoCompleteRequest (PIRP Irp
, CCHAR PriorityBoost
)
404 /**********************************************************************
406 * IoIsOperationSynchronous@4
409 * Check if the I/O operation associated with the given IRP
413 * Irp Packet to check.
416 * TRUE if Irp's operation is synchronous; otherwise FALSE.
420 IoIsOperationSynchronous (
425 PFILE_OBJECT FileObject
= NULL
;
428 * Check the associated FILE_OBJECT's
431 FileObject
= Irp
->Tail
.Overlay
.OriginalFileObject
;
432 if (!(FO_SYNCHRONOUS_IO
& FileObject
->Flags
))
434 /* Check IRP's flags. */
436 if (!( (IRP_SYNCHRONOUS_API
| IRP_SYNCHRONOUS_PAGING_IO
)
444 * Check more IRP's flags.
447 if ( !(IRP_MOUNT_COMPLETION
& Flags
)
448 || (IRP_SYNCHRONOUS_PAGING_IO
& Flags
)
454 * Otherwise, it is an
455 * asynchronous operation.