-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:
Hartmut Birr 2003-01-25 16:16:54 +00:00
parent 5d6425550e
commit 1c7ac901e2

View file

@ -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");