https://git.reactos.org/?p=reactos.git;a=commitdiff;h=acd07e725e723ab62ea8bcd2251e93746b9dc569

commit acd07e725e723ab62ea8bcd2251e93746b9dc569
Author:     Victor Perevertkin <[email protected]>
AuthorDate: Fri Aug 21 08:20:59 2020 +0300
Commit:     Victor Perevertkin <[email protected]>
CommitDate: Fri Aug 21 08:20:59 2020 +0300

    [NTOS:IO] Do device reset inside the PipDeviceActionWorker
    This make the operation synchonized with the other device tree actions
    
    CORE-10456 CORE-17150
---
 ntoskrnl/include/internal/io.h |  3 ++-
 ntoskrnl/io/pnpmgr/devaction.c | 57 ++++++++++++++++++++++++++++++++++++++++++
 ntoskrnl/io/pnpmgr/plugplay.c  | 46 ++--------------------------------
 3 files changed, 61 insertions(+), 45 deletions(-)

diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h
index 4e810bc34fe..73f862c003d 100644
--- a/ntoskrnl/include/internal/io.h
+++ b/ntoskrnl/include/internal/io.h
@@ -544,7 +544,8 @@ typedef enum _SECURITY_DESCRIPTOR_TYPE
 typedef enum _DEVICE_ACTION
 {
     PiActionEnumDeviceTree,
-    PiActionEnumRootDevices
+    PiActionEnumRootDevices,
+    PiActionResetDevice
 } DEVICE_ACTION;
 
 //
diff --git a/ntoskrnl/io/pnpmgr/devaction.c b/ntoskrnl/io/pnpmgr/devaction.c
index 77b9990f35b..0351bec4dbd 100644
--- a/ntoskrnl/io/pnpmgr/devaction.c
+++ b/ntoskrnl/io/pnpmgr/devaction.c
@@ -2324,6 +2324,57 @@ cleanup:
                               &DeviceNode->InstancePath);
 }
 
+static
+NTSTATUS
+PipResetDevice(
+    _In_ PDEVICE_NODE DeviceNode)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    ASSERT(DeviceNode->Flags & DNF_ENUMERATED);
+    ASSERT(DeviceNode->Flags & DNF_PROCESSED);
+
+    /* Check if there's already a driver loaded for this device */
+    if (DeviceNode->Flags & DNF_ADDED)
+    {
+        /* FIXME: our drivers do not handle device removal well enough */
+#if 0
+        /* Remove the device node */
+        Status = IopRemoveDevice(DeviceNode);
+        if (NT_SUCCESS(Status))
+        {
+            /* Invalidate device relations for the parent to reenumerate the 
device */
+            DPRINT1("A new driver will be loaded for '%wZ' (FDO above 
removed)\n", &DeviceNode->InstancePath);
+            Status = 
IoInvalidateDeviceRelations(DeviceNode->Parent->PhysicalDeviceObject, 
BusRelations);
+        }
+        else
+#endif
+        {
+            /* A driver has already been loaded for this device */
+            DPRINT("A reboot is required for the current driver for '%wZ' to 
be replaced\n", &DeviceNode->InstancePath);
+            DeviceNode->Problem = CM_PROB_NEED_RESTART;
+        }
+    }
+    else
+    {
+        /* FIXME: What if the device really is disabled? */
+        DeviceNode->Flags &= ~DNF_DISABLED;
+        DeviceNode->Problem = 0;
+
+        /* Load service data from the registry */
+        Status = IopActionConfigureChildServices(DeviceNode, 
DeviceNode->Parent);
+
+        if (NT_SUCCESS(Status))
+        {
+            /* Start the service and begin PnP initialization of the device 
again */
+            DPRINT("A new driver will be loaded for '%wZ' (no FDO above)\n", 
&DeviceNode->InstancePath);
+            Status = IopActionInitChildServices(DeviceNode, 
DeviceNode->Parent);
+        }
+    }
+
+    return Status;
+}
+
 #ifdef DBG
 static
 PCSTR
@@ -2336,6 +2387,8 @@ ActionToStr(
             return "PiActionEnumDeviceTree";
         case PiActionEnumRootDevices:
             return "PiActionEnumRootDevices";
+        case PiActionResetDevice:
+            return "PiActionResetDevice";
         default:
             return "(request unknown)";
     }
@@ -2376,6 +2429,10 @@ PipDeviceActionWorker(
                 status = PipEnumerateDevice(deviceNode);
                 break;
 
+            case PiActionResetDevice:
+                status = PipResetDevice(deviceNode);
+                break;
+
             default:
                 DPRINT1("Unimplemented device action %u\n", Request->Action);
                 status = STATUS_NOT_IMPLEMENTED;
diff --git a/ntoskrnl/io/pnpmgr/plugplay.c b/ntoskrnl/io/pnpmgr/plugplay.c
index 968c6804b86..933e514d9f9 100644
--- a/ntoskrnl/io/pnpmgr/plugplay.c
+++ b/ntoskrnl/io/pnpmgr/plugplay.c
@@ -1037,8 +1037,7 @@ static NTSTATUS
 IopResetDevice(PPLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData)
 {
     PDEVICE_OBJECT DeviceObject;
-    PDEVICE_NODE DeviceNode;
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
     UNICODE_STRING DeviceInstance;
 
     Status = IopCaptureUnicodeString(&DeviceInstance, 
&ResetDeviceData->DeviceInstance);
@@ -1060,48 +1059,7 @@ IopResetDevice(PPLUGPLAY_CONTROL_RESET_DEVICE_DATA 
ResetDeviceData)
         return STATUS_NO_SUCH_DEVICE;
     }
 
-    /* Get the device node */
-    DeviceNode = IopGetDeviceNode(DeviceObject);
-
-    ASSERT(DeviceNode->Flags & DNF_ENUMERATED);
-    ASSERT(DeviceNode->Flags & DNF_PROCESSED);
-
-    /* Check if there's already a driver loaded for this device */
-    if (DeviceNode->Flags & DNF_ADDED)
-    {
-#if 0
-        /* Remove the device node */
-        Status = IopRemoveDevice(DeviceNode);
-        if (NT_SUCCESS(Status))
-        {
-            /* Invalidate device relations for the parent to reenumerate the 
device */
-            DPRINT1("A new driver will be loaded for '%wZ' (FDO above 
removed)\n", &DeviceNode->InstancePath);
-            Status = 
IoSynchronousInvalidateDeviceRelations(DeviceNode->Parent->PhysicalDeviceObject,
 BusRelations);
-        }
-        else
-#endif
-        {
-            /* A driver has already been loaded for this device */
-            DPRINT("A reboot is required for the current driver for '%wZ' to 
be replaced\n", &DeviceNode->InstancePath);
-            DeviceNode->Problem = CM_PROB_NEED_RESTART;
-        }
-    }
-    else
-    {
-        /* FIXME: What if the device really is disabled? */
-        DeviceNode->Flags &= ~DNF_DISABLED;
-        DeviceNode->Problem = 0;
-
-        /* Load service data from the registry */
-        Status = IopActionConfigureChildServices(DeviceNode, 
DeviceNode->Parent);
-
-        if (NT_SUCCESS(Status))
-        {
-            /* Start the service and begin PnP initialization of the device 
again */
-            DPRINT("A new driver will be loaded for '%wZ' (no FDO above)\n", 
&DeviceNode->InstancePath);
-            Status = IopActionInitChildServices(DeviceNode, 
DeviceNode->Parent);
-        }
-    }
+    Status = PiPerformSyncDeviceAction(DeviceObject, PiActionResetDevice);
 
     ObDereferenceObject(DeviceObject);
 

Reply via email to