ドライバーのバージョン番号をプログラムで取得する方法を探しています。デバイス マネージャーがデバイスのドライバー プロパティに表示するのと同じ番号が必要です。
背景: カスタム ハードウェアと通信するアプリケーションがあります。カスタム ハードウェアのデバイス ドライバには、特定のバージョン番号より前の既知のバグがあります。アプリケーションでドライバーのバージョンを確認し、更新が必要な場合はユーザーに警告するようにします。アプリケーションは Windows XP および 7 で実行され、C++ で記述されています。
私が使用した以前のハックは、system32/drivers から直接 .sys ファイルを読み取り、「FileVersion」を直接検索することでした。これは多くの理由で良くありません。特に Windows 7 では管理者権限が必要なようです。
クラス GUID とハードウェア ID (つまり、「USB\VID_1234&PID_5678」) はわかっています。
アプリケーションは現在、SetupDiGetClassDevs、SetupDiEnumDeviceInterfaces、次に SetupDiGetDeviceInterfaceDetail を使用して「DevicePath」を取得します。次に、そのパスを使用して CreateFile を呼び出し、ドライバーと通信します。
どこかから SP_DRVINFO_DATA 構造体を取得する必要があるようです。SetupDiGetDeviceInterfaceDetail など、setupapi.h のさまざまな機能を試しました。私が試したいくつかのコードは次のとおりです。
int main(void)
{
HDEVINFO DeviceInfoSet = SetupDiGetClassDevs((LPGUID)&GUID_DEVINTERFACE_USBSPI, NULL, NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
SP_INTERFACE_DEVICE_DATA InterfaceDeviceData;
InterfaceDeviceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
// Cycle through all devices.
for (int i = 0; i < 32; i++)
{
if (!SetupDiEnumDeviceInterfaces(DeviceInfoSet, 0, (LPGUID)&GUID_DEVINTERFACE_USBSPI, i, &InterfaceDeviceData))
break;
PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData;
DWORD RequiredSize;
SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, &InterfaceDeviceData, NULL, 0, &RequiredSize, NULL);
DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, RequiredSize);
try
{
DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, &InterfaceDeviceData, DeviceInterfaceDetailData, RequiredSize, NULL, NULL);
// Try to get the driver info. This part always fails with code
// 259 (ERROR_NO_MORE_ITEMS).
SP_DRVINFO_DATA drvInfo;
drvInfo.cbSize = sizeof(SP_DRVINFO_DATA);
if (!SetupDiEnumDriverInfo(DeviceInfoSet, NULL, SPDIT_CLASSDRIVER, i, &drvInfo))
printf("error = %d\n", GetLastError());
printf("Driver version is %08x %08x\n", drvInfo.DriverVersion >> 32, drvInfo.DriverVersion & 0xffffffff);
}
catch(...)
{
HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
throw;
}
HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
}
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
return 0;
}
編集- 更新されたコードは次のようになります。
HDEVINFO devInfoSet = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USBSPI, NULL, NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
// Cycle through all devices.
for (int i = 0; ; i++)
{
// Get the device info for this device
SP_DEVINFO_DATA devInfo;
devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiEnumDeviceInfo(devInfoSet, i, &devInfo))
break;
// Get the first info item for this driver
SP_DRVINFO_DATA drvInfo;
drvInfo.cbSize = sizeof(SP_DRVINFO_DATA);
if (!SetupDiEnumDriverInfo(devInfoSet, &devInfo, SPDIT_COMPATDRIVER, 0, &drvInfo))
printf("err - %d\n", GetLastError()); // Still fails with "no more items"
}
SetupDiDestroyDeviceInfoList(devInfoSet);