mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
-IoCallDriver didn't set DeviceObject member in next stack location.
-IofCompleteRequest: fixed broken completion routine handling (Thanks to Gunnar Andr� Dalsnes) svn path=/trunk/; revision=4068
This commit is contained in:
parent
5d6425550e
commit
1c7ac901e2
1 changed files with 57 additions and 31 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: irp.c,v 1.46 2002/11/10 18:17:41 chorns Exp $
|
/* $Id: irp.c,v 1.47 2003/01/25 16:16:54 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -73,6 +73,7 @@ IoMakeAssociatedIrp(PIRP Irp,
|
||||||
|
|
||||||
AssocIrp = IoAllocateIrp(StackSize,FALSE);
|
AssocIrp = IoAllocateIrp(StackSize,FALSE);
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -105,7 +106,6 @@ IofCallDriver(PDEVICE_OBJECT DeviceObject,
|
||||||
* FUNCTION: Sends an IRP to the next lower driver
|
* FUNCTION: Sends an IRP to the next lower driver
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
|
||||||
PDRIVER_OBJECT DriverObject;
|
PDRIVER_OBJECT DriverObject;
|
||||||
PIO_STACK_LOCATION Param;
|
PIO_STACK_LOCATION Param;
|
||||||
|
|
||||||
|
@ -118,20 +118,18 @@ IofCallDriver(PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
assert(DriverObject);
|
assert(DriverObject);
|
||||||
|
|
||||||
Param = IoGetNextIrpStackLocation(Irp);
|
IoSetNextIrpStackLocation(Irp);
|
||||||
|
Param = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
DPRINT("IrpSp 0x%X\n", Param);
|
DPRINT("IrpSp 0x%X\n", Param);
|
||||||
|
|
||||||
Irp->Tail.Overlay.CurrentStackLocation--;
|
Param->DeviceObject = DeviceObject;
|
||||||
Irp->CurrentLocation--;
|
|
||||||
|
|
||||||
DPRINT("MajorFunction %d\n", Param->MajorFunction);
|
DPRINT("MajorFunction %d\n", Param->MajorFunction);
|
||||||
DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n",
|
DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n",
|
||||||
DriverObject->MajorFunction[Param->MajorFunction]);
|
DriverObject->MajorFunction[Param->MajorFunction]);
|
||||||
Status = DriverObject->MajorFunction[Param->MajorFunction](DeviceObject,
|
|
||||||
Irp);
|
return DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, Irp);
|
||||||
|
|
||||||
return(Status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -221,34 +219,62 @@ IofCompleteRequest(PIRP Irp,
|
||||||
* thread making the request
|
* thread making the request
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
|
||||||
DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
|
DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
|
||||||
Irp,PriorityBoost, Irp->UserEvent, PsGetCurrentThread());
|
Irp,PriorityBoost, Irp->UserEvent, PsGetCurrentThread());
|
||||||
|
|
||||||
|
assert(Irp->CancelRoutine == NULL);
|
||||||
|
assert(Irp->IoStatus.Status != STATUS_PENDING);
|
||||||
|
|
||||||
|
if (IoGetCurrentIrpStackLocation(Irp)->Control & SL_PENDING_RETURNED)
|
||||||
|
{
|
||||||
|
Irp->PendingReturned = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
for (i=Irp->CurrentLocation;i<(ULONG)Irp->StackCount;i++)
|
for (i=Irp->CurrentLocation;i<(ULONG)Irp->StackCount;i++)
|
||||||
{
|
{
|
||||||
if (Irp->Stack[i].CompletionRoutine != NULL)
|
/*
|
||||||
{
|
Completion routines expect the current irp stack location to be the same as when
|
||||||
Status = Irp->Stack[i].CompletionRoutine(
|
IoSetCompletionRoutine was called to set them. A side effect is that completion
|
||||||
Irp->Stack[i].DeviceObject,
|
routines set by highest level drivers without their own stack location will receive
|
||||||
Irp,
|
an invalid current stack location (at least it should be considered as invalid).
|
||||||
Irp->Stack[i].CompletionContext);
|
Since the DeviceObject argument passed is taken from the current stack, this value
|
||||||
if (Status == STATUS_MORE_PROCESSING_REQUIRED)
|
is also invalid (NULL).
|
||||||
{
|
*/
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Irp->Stack[i].Control & SL_PENDING_RETURNED)
|
|
||||||
{
|
|
||||||
Irp->PendingReturned = TRUE;
|
|
||||||
}
|
|
||||||
if (Irp->CurrentLocation < Irp->StackCount - 1)
|
if (Irp->CurrentLocation < Irp->StackCount - 1)
|
||||||
{
|
{
|
||||||
IoSkipCurrentIrpStackLocation(Irp);
|
IoSetPreviousIrpStackLocation(Irp);
|
||||||
|
DeviceObject = IoGetCurrentIrpStackLocation(Irp)->DeviceObject;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DeviceObject = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Irp->Stack[i].CompletionRoutine != NULL &&
|
||||||
|
((NT_SUCCESS(Irp->IoStatus.Status) && (Irp->Stack[i].Control & SL_INVOKE_ON_SUCCESS)) ||
|
||||||
|
(!NT_SUCCESS(Irp->IoStatus.Status) && (Irp->Stack[i].Control & SL_INVOKE_ON_ERROR)) ||
|
||||||
|
(Irp->Cancel && (Irp->Stack[i].Control & SL_INVOKE_ON_CANCEL))))
|
||||||
|
{
|
||||||
|
Status = Irp->Stack[i].CompletionRoutine(DeviceObject,
|
||||||
|
Irp,
|
||||||
|
Irp->Stack[i].CompletionContext);
|
||||||
|
|
||||||
|
if (Status == STATUS_MORE_PROCESSING_REQUIRED)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IoGetCurrentIrpStackLocation(Irp)->Control & SL_PENDING_RETURNED)
|
||||||
|
{
|
||||||
|
Irp->PendingReturned = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Irp->PendingReturned)
|
if (Irp->PendingReturned)
|
||||||
{
|
{
|
||||||
DPRINT("Dispatching APC\n");
|
DPRINT("Dispatching APC\n");
|
||||||
|
|
Loading…
Reference in a new issue