USB 加密狗(非存储设备)在插入时重新启动后无法识别

USB dongle (non-storage device) not recognized after rebooted while plugged in

我们有一个可编程的专有 USB 加密狗(不是存储设备),我们将其插入机器 运行 Windows CE7。有了加密狗,我们可以使用 API。一个简单的 API 函数是“checkIfDongleInserted”函数。 USB dongle 在 运行 机器上插入时被识别,即它列在 HKLM\Drivers\Active 下的 Wince 注册表中,我们可以使用 checkIfDongleInserted 函数找到它。 但是,如果我们在加密狗保持插入状态时重启机器,设备将不再被识别,即它不会出现在注册表中并且 API 函数失败。如果我们手动重新插入加密狗,它就会再次被识别。 有趣的是,其他设备(USB 记忆棒、USB 键盘、USB 鼠标)在机器保持插入状态的情况下重新启动机器后可以正常工作并被完美识别。

在检查USB dongle 的驱动程序后,我发现它实现了USBInstallDriver 接口。研究这个界面让我找到了 https://docs.microsoft.com/en-us/previous-versions/windows/embedded/ms923254(v=msdn.10),在评论中它说

The USB driver module calls this function when an unrecognized device is attached to the USB port

所以我的猜测是,在机器 运行 时重新启动这个“USB 驱动程序模块”(从客户端应用程序)可能是识别 USB 加密狗的一个想法。虽然我没有从客户端应用程序中看到这种情况。

这个特定设备在插入时启动时未被检测到的原因可能是什么? 有没有办法识别它而无需手动重新插入它?

受到 this post 的启发,我找到了解决方案。 我的假设是正确的,我必须重新启动 USB 控制器,我只是不知道如何。 经过进一步研究,我发现 HCD (Host Controller Driver) 是检测插入的 USB 设备的驱动程序,我需要重新加载。这样做后,它会再次检测到我已经插入的 USB 加密狗。

使用 FindFirstDevice 查找设备(在本例中为主机控制器),然后使用 DeactivateDevice() 卸载驱动程序,并在不久之后再次使用 ActivateDeviceEx() 加载驱动程序。

这是没有任何错误处理的代码(我在另一台PC上,懒得把所有东西都复制过来,所以我只是用C语言粗略地写了上面的步骤)

DeviceSearchType searchType = DeviceSearchByDeviceName;
DEVMGR_DEVICE_INFORMATION deviceInfo;

//Find HCD
handle = FindFirstDevice(searchType,L"HCD*",&deviceInfo);


//Save the deviceKey to later be able to ActivateDeviceEx()
WCHAR* deviceKey = deviceInfo.szDeviceKey;
DeactivateDevice(deviceInfo.hDevice);
Sleep(100); //to make sure
ActivateDeviceEx(deviceKey,NULL,0,NULL);