Author: hpoussin
Date: Mon Dec  3 12:03:38 2007
New Revision: 30979
URL: 
http://svn.reactos.org/svn/reactos?rev=30979&view=rev
Log:
Implement IoForwardIrpSynchronously
Use it in root bus
Modified:
    trunk/reactos/ntoskrnl/io/iomgr/irp.c
    trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c
Modified: trunk/reactos/ntoskrnl/io/iomgr/irp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/irp.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/io/iomgr/irp.c (original)
+++ trunk/reactos/ntoskrnl/io/iomgr/irp.c Mon Dec  3 12:03:38 2007
@@ -1411,16 +1411,56 @@
     }
 }
-/*
- * @unimplemented
+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;
+}
+
+/*
+ * @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;
 }
 /*
Modified: trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/pnpmgr/pnproot…
==============================================================================
--- trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c (original)
+++ trunk/reactos/ntoskrnl/io/pnpmgr/pnproot.c Mon Dec  3 12:03:38 2007
@@ -226,48 +226,6 @@
     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 @@
         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: