我想从USB设备上读取HID功能报告,我有 VendorID 和 DeviceID ,并且保证只有一个匹配该描述的设备。
这不难,但我在阅读MSDN文档时感到很困惑。
感谢libudev :),我在几个小时内就在linux上工作了。但我需要一个原生的Windows实现(最好是VC ++,可能使用Hidsdi.h和/或Setupapi.h)
任何人都可以指出我正确的方向。
答案 0 :(得分:1)
使用本机Windows库,它可能不是完成此任务的正确方法,但它可以工作。我建议不要直接使用这个代码,因为它很糟糕,但随意阅读它有用的东西。
找到设备ID为0021且供应商ID为2833的HID 然后读取特征报告0x0F;
#include <Windows.h>
#include <iostream>
#include <Setupapi.h>
#include <Hidsdi.h>
using namespace std;
// returns true if full_string contains the substring
BOOL findSubstring(WCHAR *full_string, const char *substring){
unsigned int c = 0, d = 0;
while (true) {
if (substring[d] == '\0')
return true;
if (full_string[c] == '\0')
return false;
d = (full_string[c] == substring[d]) ? d + 1 : 0;
if (c++ > MAX_PATH)
return false;
}
}
int main()
{
GUID guid;
HDEVINFO hDeviceInfo;
SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceDetail;
DWORD i = 0;
WCHAR *devicePath = NULL;
// Obtain a handle to the connected HID devices
HidD_GetHidGuid(&guid);
hDeviceInfo = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (hDeviceInfo == INVALID_HANDLE_VALUE) {
cerr << "Failed to get Device Handle" << endl;
return 1;
}
i = 0;
deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
// Enumerate through all the HID devices
while (SetupDiEnumDeviceInterfaces(hDeviceInfo, NULL, &guid, i++, &deviceInterfaceData)) {
ULONG requiredSize;
// Get the details with null values to get the required size of the buffer
SetupDiGetDeviceInterfaceDetail(hDeviceInfo, &deviceInterfaceData, NULL, 0, &requiredSize, 0);
deviceDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(requiredSize);
deviceDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
// Fill the buffer with the device details
if (!SetupDiGetDeviceInterfaceDetail(hDeviceInfo, &deviceInterfaceData, deviceDetail, requiredSize, &requiredSize, NULL)) {
cerr << "Could not obtain the HID device for some reason" << endl;
SetupDiDestroyDeviceInfoList(hDeviceInfo);
free(deviceDetail);
return 1;
}
// Check that the device path contains two strings, which are our vendorID and pathID.
if (findSubstring(deviceDetail->DevicePath, "vid_2833") && findSubstring(deviceDetail->DevicePath, "pid_0021")) {
devicePath = deviceDetail->DevicePath;
}
}
if (devicePath != NULL) {
// Open the HID
HANDLE HIDfile = CreateFile(devicePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD err = GetLastError();
if (err != 0) {
cerr << "unable to obtain read permissions for the HID device, error: " << err << endl;
} else {
// Allocate buffer for the feature report
BYTE buffer[30];
memset(buffer, 0, sizeof(buffer[0]));
buffer[0] = 0x0FU; // Feature report 0x0F
if (!HidD_GetFeature(HIDfile, buffer, sizeof(buffer))){
cout << "Feature report failed" << endl;
}
else {
cout << "Feature report successful" << endl;
for (int i = 0; i < 30; i++)
cout << hex << (int)buffer[i];
}
cout << endl;
}
}
// probably small memory leak
// free(deviceDetail);
SetupDiDestroyDeviceInfoList(hDeviceInfo);
return 0;
}