X-Git-Url: http://git.jankratochvil.net/?a=blobdiff_plain;f=ntoskrnl%2Fio%2Firp.c;h=8b54d3959b7c5a7883676236a7e5b1499b0f21a3;hb=eacae1ddd2c4afb25ce718074e5dbdcfc4854eb4;hp=96c03991ba631d0b6f49650113982cf0156c0214;hpb=2f6eb100edb95708c545abde1958189013283760;p=reactos.git diff --git a/ntoskrnl/io/irp.c b/ntoskrnl/io/irp.c index 96c0399..8b54d39 100644 --- a/ntoskrnl/io/irp.c +++ b/ntoskrnl/io/irp.c @@ -74,6 +74,7 @@ IoMakeAssociatedIrp(PIRP Irp, AssocIrp = IoAllocateIrp(StackSize,FALSE); UNIMPLEMENTED; + return NULL; } #endif /* LIBCAPTIVE */ @@ -108,7 +109,6 @@ IofCallDriver(PDEVICE_OBJECT DeviceObject, * FUNCTION: Sends an IRP to the next lower driver */ { - NTSTATUS Status; PDRIVER_OBJECT DriverObject; PIO_STACK_LOCATION Param; @@ -121,20 +121,20 @@ 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); + DriverObject->MajorFunction[Param->MajorFunction]); - return(Status); + if (!DriverObject->MajorFunction[Param->MajorFunction]) + KeBugCheck(0); + return DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, Irp); } @@ -226,38 +226,66 @@ IofCompleteRequest(PIRP Irp, * thread making the request */ { - int 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); - for (i=Irp->CurrentLocation;i<(int)Irp->StackCount;i++) + if (IoGetCurrentIrpStackLocation(Irp)->Control & SL_PENDING_RETURNED) { - if (Irp->Stack[i].CompletionRoutine != NULL) + Irp->PendingReturned = TRUE; + } + + for (i=Irp->CurrentLocation;i<(ULONG)Irp->StackCount;i++) + { + /* + 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) + { + IoSetPreviousIrpStackLocation(Irp); + DeviceObject = IoGetCurrentIrpStackLocation(Irp)->DeviceObject; + } + else { - Status = Irp->Stack[i].CompletionRoutine( - Irp->Stack[i].DeviceObject, - Irp, - Irp->Stack[i].CompletionContext); - if (Status == STATUS_MORE_PROCESSING_REQUIRED) - { + 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) + { if (Irp->UserIosb) { *Irp->UserIosb=Irp->IoStatus; } - return; - } + return; + } } - if (Irp->Stack[i].Control & SL_PENDING_RETURNED) - { - Irp->PendingReturned = TRUE; - } - if (Irp->CurrentLocation < Irp->StackCount - 1) + + if (IoGetCurrentIrpStackLocation(Irp)->Control & SL_PENDING_RETURNED) { - IoSkipCurrentIrpStackLocation(Irp); + Irp->PendingReturned = TRUE; } } + if (Irp->PendingReturned) { DPRINT("Dispatching APC\n"); @@ -320,6 +348,8 @@ IoIsOperationSynchronous(IN PIRP Irp) /* Check the FILE_OBJECT's flags first. */ FileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject; + if (FileObject == NULL) + KeBugCheck(0); if (!(FO_SYNCHRONOUS_IO & FileObject->Flags)) { /* Check IRP's flags. */ @@ -328,7 +358,7 @@ IoIsOperationSynchronous(IN PIRP Irp) { #ifdef LIBCAPTIVE /* libcaptive is fully single-thread/single-process synchronous model. */ - KeBugCheck(0); + return TRUE; #endif /* LIBCAPTIVE */ return(FALSE); } @@ -345,7 +375,7 @@ IoIsOperationSynchronous(IN PIRP Irp) /* Otherwise, it is an asynchronous operation. */ #ifdef LIBCAPTIVE /* libcaptive is fully single-thread/single-process synchronous model. */ - KeBugCheck(0); + return TRUE; #endif /* LIBCAPTIVE */ return(FALSE); }