[idd] install: let SetupAPI manage device updates

Remove the separate ConfigMgr disable and enable transaction. It
bypassed device class/co-installers, failed before DiInstallDriverW,
and could add two 30-second waits to every update.

Keep LGIddHelper stopped across both DiInstallDriverW calls and let
SetupAPI own PnP stop/start and report any required restart.
This commit is contained in:
Geoffrey McRae
2026-08-15 19:11:48 +10:00
parent d23a7a3cf2
commit 5d51567fd5

View File

@@ -545,7 +545,6 @@ typedef struct DeviceRuntimeState
bool present;
bool started;
bool usable;
bool disabled;
bool created;
bool rollbackDeviceSafe;
WCHAR instanceId[MAX_DEVICE_ID_LEN];
@@ -603,114 +602,6 @@ bool deviceIsUsable(const DeviceDesc *device)
state.present && state.usable;
}
bool waitForDeviceState(
const DeviceRuntimeState *state,
bool started)
{
const ULONGLONG deadline = GetTickCount64() + STATE_WAIT_TIMEOUT_MS;
for (;;)
{
DEVINST devInst;
CONFIGRET cr = CM_Locate_DevNodeW(
&devInst, (DEVINSTID_W) state->instanceId, CM_LOCATE_DEVNODE_NORMAL);
if (cr != CR_SUCCESS)
{
debugConfigError(L"CM_Locate_DevNodeW", cr);
return false;
}
ULONG status;
ULONG problem;
cr = CM_Get_DevNode_Status(&status, &problem, devInst, 0);
if (cr != CR_SUCCESS)
{
debugConfigError(L"CM_Get_DevNode_Status", cr);
return false;
}
if (((status & DN_STARTED) != 0) == started)
return true;
if (GetTickCount64() >= deadline)
{
fwprintf(stderr, L"%s: timed out waiting for device to %s\n",
state->device->name, started ? L"start" : L"stop");
return false;
}
Sleep(100);
}
}
bool disableDevice(DeviceRuntimeState *state)
{
if (!state->present || !state->started)
return true;
DEVINST devInst;
CONFIGRET cr = CM_Locate_DevNodeW(
&devInst, state->instanceId, CM_LOCATE_DEVNODE_NORMAL);
if (cr != CR_SUCCESS)
{
debugConfigError(L"CM_Locate_DevNodeW", cr);
return false;
}
wprintf(L"Temporarily disabling %s...\n", state->device->name);
cr = CM_Disable_DevNode(devInst, CM_DISABLE_UI_NOT_OK);
if (cr != CR_SUCCESS)
{
debugConfigError(L"CM_Disable_DevNode", cr);
return false;
}
state->disabled = true;
return waitForDeviceState(state, false);
}
bool enableDevice(DeviceRuntimeState *state)
{
if (!state->disabled)
return true;
DEVINST devInst;
CONFIGRET cr = CM_Locate_DevNodeW(
&devInst, state->instanceId, CM_LOCATE_DEVNODE_NORMAL);
if (cr != CR_SUCCESS)
{
debugConfigError(L"CM_Locate_DevNodeW", cr);
return false;
}
wprintf(L"Re-enabling %s...\n", state->device->name);
cr = CM_Enable_DevNode(devInst, 0);
if (cr != CR_SUCCESS)
{
debugConfigError(L"CM_Enable_DevNode", cr);
return false;
}
if (!waitForDeviceState(state, true))
return false;
state->disabled = false;
return true;
}
bool enableDevices(
DeviceRuntimeState *idd,
DeviceRuntimeState *input)
{
if (!enableDevice(idd))
return false;
if (input->disabled && !deviceIsUsable(&LGIDD_DEVICE))
{
fwprintf(stderr,
L"LGInput remains disabled because LGIdd is not usable\n");
return false;
}
return enableDevice(input);
}
DeviceRuntimeState *runtimeStateForDevice(
const DeviceDesc *device,
DeviceRuntimeState *idd,
@@ -1116,7 +1007,7 @@ void install(const DeviceDesc *const devices[DEVICE_COUNT])
bool helperWasRunning = false;
bool installSucceeded = false;
bool rollbackSucceeded = true;
bool restoreSucceeded;
bool restoreSucceeded = true;
BOOL needRestart = FALSE;
if (!captureDeviceState(&LGIDD_DEVICE, &idd) ||
@@ -1127,11 +1018,6 @@ void install(const DeviceDesc *const devices[DEVICE_COUNT])
if (!stopHelperService(&helperExisted, &helperWasRunning))
exit(1);
// LGInput consumes LGIdd's input pipe, so quiesce the dependent device
// first and restore the provider first.
if (!disableDevice(&input) || !disableDevice(&idd))
goto cleanup;
_putws(L"Preparing registry key...");
if (!ensureKeyWithAce())
goto cleanup;
@@ -1178,8 +1064,6 @@ cleanup:
}
}
restoreSucceeded = enableDevices(&idd, &input);
if (installSucceeded && restoreSucceeded && !needRestart)
{
_putws(L"Starting LGIddHelper...");