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
|
||||
* 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);
|
||||
return DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, Irp);
|
||||
}
|
||||
|
||||
|
||||
|
@ -223,32 +221,60 @@ IofCompleteRequest(PIRP Irp,
|
|||
{
|
||||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
|
||||
DPRINT("IoCompleteRequest(Irp %x, PriorityBoost %d) Event %x THread %x\n",
|
||||
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)
|
||||
/*
|
||||
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)
|
||||
{
|
||||
Status = Irp->Stack[i].CompletionRoutine(
|
||||
Irp->Stack[i].DeviceObject,
|
||||
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 (Irp->Stack[i].Control & SL_PENDING_RETURNED)
|
||||
|
||||
if (IoGetCurrentIrpStackLocation(Irp)->Control & SL_PENDING_RETURNED)
|
||||
{
|
||||
Irp->PendingReturned = TRUE;
|
||||
}
|
||||
if (Irp->CurrentLocation < Irp->StackCount - 1)
|
||||
{
|
||||
IoSkipCurrentIrpStackLocation(Irp);
|
||||
}
|
||||
}
|
||||
|
||||
if (Irp->PendingReturned)
|
||||
{
|
||||
DPRINT("Dispatching APC\n");
|
||||
|
|
Loading…
Reference in a new issue