diff --git a/reactos/ntoskrnl/io/iomgr/irp.c b/reactos/ntoskrnl/io/iomgr/irp.c index 4e22696fb01..7cb53c3abc1 100644 --- a/reactos/ntoskrnl/io/iomgr/irp.c +++ b/reactos/ntoskrnl/io/iomgr/irp.c @@ -1411,16 +1411,56 @@ IofCompleteRequest(IN PIRP Irp, } } +NTSTATUS +NTAPI +IopSynchronousCompletion( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context) +{ + if (Irp->PendingReturned) + KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); + return STATUS_MORE_PROCESSING_REQUIRED; +} + /* - * @unimplemented + * @implemented */ BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED; - return FALSE; + KEVENT Event; + NTSTATUS Status; + + /* Check if next stack location is available */ + if (Irp->CurrentLocation < Irp->StackCount) + { + /* No more stack location */ + return FALSE; + } + + /* Initialize event */ + KeInitializeEvent(&Event, NotificationEvent, FALSE); + + /* Copy stack location for next driver */ + IoCopyCurrentIrpStackLocationToNext(Irp); + + /* Set a completion routine, which will signal the event */ + IoSetCompletionRoutine(Irp, IopSynchronousCompletion, &Event, TRUE, TRUE, TRUE); + + /* Call next driver */ + Status = IoCallDriver(DeviceObject, Irp); + + /* Check if irp is pending */ + if (Status == STATUS_PENDING) + { + /* Yes, wait for its completion */ + KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); + } + + return TRUE; } /* diff --git a/reactos/ntoskrnl/io/pnpmgr/pnproot.c b/reactos/ntoskrnl/io/pnpmgr/pnproot.c index 717c0d9bcfd..3a87713598b 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnproot.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnproot.c @@ -226,48 +226,6 @@ cleanup: return Status; } -static NTSTATUS STDCALL -ForwardIrpAndWaitCompletion( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context) -{ - if (Irp->PendingReturned) - KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); - return STATUS_MORE_PROCESSING_REQUIRED; -} - -static NTSTATUS -ForwardIrpAndWait( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PDEVICE_OBJECT LowerDevice; - KEVENT Event; - NTSTATUS Status; - - ASSERT(((PPNPROOT_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->IsFDO); - LowerDevice = ((PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Ldo; - - ASSERT(LowerDevice); - - KeInitializeEvent(&Event, NotificationEvent, FALSE); - IoCopyCurrentIrpStackLocationToNext(Irp); - - DPRINT("Calling lower device %p [%wZ]\n", LowerDevice, &LowerDevice->DriverObject->DriverName); - IoSetCompletionRoutine(Irp, ForwardIrpAndWaitCompletion, &Event, TRUE, TRUE, TRUE); - - Status = IoCallDriver(LowerDevice, Irp); - if (Status == STATUS_PENDING) - { - Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); - if (NT_SUCCESS(Status)) - Status = Irp->IoStatus.Status; - } - - return Status; -} - static NTSTATUS NTAPI QueryStringCallback( IN PWSTR ValueName, @@ -702,10 +660,14 @@ PnpRootFdoPnpControl( case IRP_MN_START_DEVICE: DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n"); - Status = ForwardIrpAndWait(DeviceObject, Irp); - if (NT_SUCCESS(Status)) - DeviceExtension->State = dsStarted; - Status = STATUS_SUCCESS; + if (!IoForwardIrpSynchronously(DeviceExtension->Ldo, Irp)) + Status = STATUS_UNSUCCESSFUL; + else + { + Status = Irp->IoStatus.Status; + if (NT_SUCCESS(Status)) + DeviceExtension->State = dsStarted; + } break; case IRP_MN_STOP_DEVICE: