Harry Johnston's answer brought me close, but I had to add a bit more to make it work. The magic bit that was missing was that I had to call both SetupDiEnumDeviceInfo
and SetupDiBuildDriverInfoList
before SetupDiEnumDriverInfoW
actually did something useful.
Here is a complete (modulo cleanup) example, replace the string passed to SetupDiGetClassDevsW
to match your own device. For my specific device it prints
Driver found: description: USBXpress Device, MfgName: Silicon Labs, ProviderName: Silicon Laboratories Inc.
on a PC with the driver installed and
No driver found
on a PC (actually VM) with no driver installed.
#include <Windows.h>
#include <SetupAPI.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "setupapi.lib")
int main(int argc, char ** argv)
{
HDEVINFO hdevinfo = SetupDiGetClassDevsW(NULL, LR"(USBVID_10C4&PID_EA61)",
NULL, DIGCF_ALLCLASSES);
if (hdevinfo == INVALID_HANDLE_VALUE)
{
DWORD err = GetLastError();
printf("SetupDiGetClassDevs: %u
", err);
return 1;
}
SP_DEVINFO_DATA devinfo;
devinfo.cbSize = sizeof(devinfo);
if (!SetupDiEnumDeviceInfo(hdevinfo, 0, &devinfo))
{
DWORD err = GetLastError();
printf("SetupDiEnumDeviceInfo: %u %d
", err, 0);
return 1;
}
if (!SetupDiBuildDriverInfoList(hdevinfo, &devinfo, SPDIT_COMPATDRIVER)) {
printf("error %d
", GetLastError());
return 1;
}
SP_DRVINFO_DATA_W drvdata;
drvdata.cbSize = sizeof(SP_DRVINFO_DATA_W);
BOOL worked = SetupDiEnumDriverInfoW(hdevinfo, &devinfo, SPDIT_COMPATDRIVER,
0, &drvdata);
if (worked) {
printf("Driver found: description: %ws, MfgName: %ws, ProviderName: %ws
",
drvdata.Description, drvdata.MfgName, drvdata.ProviderName);
}
else {
DWORD err = GetLastError();
if (err == ERROR_NO_MORE_ITEMS)
printf("No driver found
");
else {
printf("SetupDiEnumDriverInfoW: %d", err);
return 1;
}
}
return 0;
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…