https://git.reactos.org/?p=reactos.git;a=commitdiff;h=acd07e725e723ab62ea8b…
commit acd07e725e723ab62ea8bcd2251e93746b9dc569
Author: Victor Perevertkin <victor.perevertkin(a)reactos.org>
AuthorDate: Fri Aug 21 08:20:59 2020 +0300
Commit: Victor Perevertkin <victor.perevertkin(a)reactos.org>
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);