From 1c7ac901e2b927eccf5ce188bb86c0343e998bdf Mon Sep 17 00:00:00 2001 From: Hartmut Birr Date: Sat, 25 Jan 2003 16:16:54 +0000 Subject: [PATCH] =?UTF-8?q?-IoCallDriver=20didn't=20set=20DeviceObject=20m?= =?UTF-8?q?ember=20in=20next=20stack=20location.=20-IofCompleteRequest:=20?= =?UTF-8?q?fixed=20broken=20completion=20routine=20handling=20(Thanks=20to?= =?UTF-8?q?=20Gunnar=20Andr=EF=BF=BD=20Dalsnes)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit svn path=/trunk/; revision=4068 --- reactos/ntoskrnl/io/irp.c | 88 +++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 31 deletions(-) diff --git a/reactos/ntoskrnl/io/irp.c b/reactos/ntoskrnl/io/irp.c index 988994262f9..9b1347c88ec 100644 --- a/reactos/ntoskrnl/io/irp.c +++ b/reactos/ntoskrnl/io/irp.c @@ -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 * PROJECT: ReactOS kernel @@ -73,6 +73,7 @@ IoMakeAssociatedIrp(PIRP Irp, AssocIrp = IoAllocateIrp(StackSize,FALSE); UNIMPLEMENTED; + return NULL; } @@ -105,7 +106,6 @@ IofCallDriver(PDEVICE_OBJECT DeviceObject, * FUNCTION: Sends an IRP to the next lower driver */ { - NTSTATUS Status; PDRIVER_OBJECT DriverObject; PIO_STACK_LOCATION Param; @@ -118,20 +118,18 @@ IofCallDriver(PDEVICE_OBJECT DeviceObject, assert(DriverObject); - Param = IoGetNextIrpStackLocation(Irp); + IoSetNextIrpStackLocation(Irp); + Param = IoGetCurrentIrpStackLocation(Irp); DPRINT("IrpSp 0x%X\n", Param); - Irp->Tail.Overlay.CurrentStackLocation--; - Irp->CurrentLocation--; - + Param->DeviceObject = DeviceObject; + DPRINT("MajorFunction %d\n", Param->MajorFunction); DPRINT("DriverObject->MajorFunction[Param->MajorFunction] %x\n", - DriverObject->MajorFunction[Param->MajorFunction]); - Status = DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, - Irp); - - return(Status); + DriverObject->MajorFunction[Param->MajorFunction]); + + return DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, Irp); } @@ -221,34 +219,62 @@ IofCompleteRequest(PIRP Irp, * thread making the request */ { - ULONG i; - NTSTATUS Status; - + ULONG i; + NTSTATUS Status; + PDEVICE_OBJECT DeviceObject; + 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++) { - if (Irp->Stack[i].CompletionRoutine != NULL) - { - Status = Irp->Stack[i].CompletionRoutine( - Irp->Stack[i].DeviceObject, - Irp, - Irp->Stack[i].CompletionContext); - if (Status == STATUS_MORE_PROCESSING_REQUIRED) - { - return; - } - } - if (Irp->Stack[i].Control & SL_PENDING_RETURNED) - { - Irp->PendingReturned = TRUE; - } + /* + Completion routines expect the current irp stack location to be the same as when + IoSetCompletionRoutine was called to set them. A side effect is that completion + routines set by highest level drivers without their own stack location will receive + an invalid current stack location (at least it should be considered as invalid). + Since the DeviceObject argument passed is taken from the current stack, this value + is also invalid (NULL). + */ 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) { DPRINT("Dispatching APC\n");