From abbc5ba45a2072e4e3e56fd6596955be1c579fdb Mon Sep 17 00:00:00 2001 From: Victor Perevertkin Date: Tue, 16 Mar 2021 02:25:09 +0300 Subject: [PATCH] [UMPNPMGR][USETUP] Use PlugPlayControlStartDevice in usetup and umpnpmgr Instead of PlugPlayControlResetDevice, PlugPlayControlStartDevice should be used for a newly installed device. For usetup, add a device status check before starting attempt, so we're not touching devices which are already started. CORE-17463 CORE-17490 --- base/services/umpnpmgr/rpcserver.c | 9 +++---- base/setup/usetup/devinst.c | 38 ++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/base/services/umpnpmgr/rpcserver.c b/base/services/umpnpmgr/rpcserver.c index cf9ba100f1b..cf49713061a 100644 --- a/base/services/umpnpmgr/rpcserver.c +++ b/base/services/umpnpmgr/rpcserver.c @@ -3081,17 +3081,14 @@ static CONFIGRET EnableDeviceInstance( _In_ LPWSTR pszDeviceInstance) { - PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA ResetDeviceData; + PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA ControlData; CONFIGRET ret = CR_SUCCESS; NTSTATUS Status; DPRINT("Enable device instance %S\n", pszDeviceInstance); - RtlInitUnicodeString(&ResetDeviceData.DeviceInstance, - pszDeviceInstance); - Status = NtPlugPlayControl(PlugPlayControlResetDevice, - &ResetDeviceData, - sizeof(PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA)); + RtlInitUnicodeString(&ControlData.DeviceInstance, pszDeviceInstance); + Status = NtPlugPlayControl(PlugPlayControlStartDevice, &ControlData, sizeof(ControlData)); if (!NT_SUCCESS(Status)) ret = NtStatusToCrError(Status); diff --git a/base/setup/usetup/devinst.c b/base/setup/usetup/devinst.c index 80d93ce1d51..eee7c25b4ec 100644 --- a/base/setup/usetup/devinst.c +++ b/base/setup/usetup/devinst.c @@ -39,20 +39,25 @@ typedef struct /* FUNCTIONS ****************************************************************/ static BOOLEAN -ResetDevice( - IN LPCWSTR DeviceId) +AreDriversLoaded( + IN PCWSTR DeviceId) { - PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA ResetDeviceData; + PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData; NTSTATUS Status; - RtlInitUnicodeString(&ResetDeviceData.DeviceInstance, DeviceId); - Status = NtPlugPlayControl(PlugPlayControlResetDevice, &ResetDeviceData, sizeof(PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA)); - if (!NT_SUCCESS(Status)) + RtlInitUnicodeString(&PlugPlayData.DeviceInstance, DeviceId); + PlugPlayData.Operation = PNP_GET_DEVICE_STATUS; + + Status = NtPlugPlayControl(PlugPlayControlDeviceStatus, &PlugPlayData, sizeof(PlugPlayData)); + if (NT_SUCCESS(Status)) + { + return (_Bool)((PlugPlayData.DeviceStatus & DN_DRIVER_LOADED) && + !(PlugPlayData.DeviceStatus & DN_HAS_PROBLEM)); + } + else { - DPRINT1("NtPlugPlayControl() failed with status 0x%08x\n", Status); return FALSE; } - return TRUE; } static BOOLEAN @@ -81,6 +86,10 @@ InstallDriver( NTSTATUS Status; BOOLEAN deviceInstalled = FALSE; + /* First check if the driver needs any action at all */ + if (AreDriversLoaded(DeviceId)) + return TRUE; + /* Check if we know the hardware */ if (!SpInfFindFirstLine(hInf, L"HardwareIdsDatabase", HardwareId, &Context)) return FALSE; @@ -190,8 +199,17 @@ InstallDriver( (wcslen(Driver) + 1) * sizeof(WCHAR)); if (NT_SUCCESS(Status)) { - /* Restart the device, so it will use the driver we registered */ - deviceInstalled = ResetDevice(DeviceId); + /* We've registered the driver, time to start a device */ + PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA ControlData; + RtlInitUnicodeString(&ControlData.DeviceInstance, DeviceId); + + Status = NtPlugPlayControl(PlugPlayControlStartDevice, &ControlData, sizeof(ControlData)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtPlugPlayControl() failed with status 0x%08x\n", Status); + } + + deviceInstalled = NT_SUCCESS(Status); } INF_FreeData(Driver); -- 2.17.1