2015-04-13 3 views
0

я хочу прочитать HID отчета функции с устройства USB, у меня есть VendorID и DeviceID, и это гарантирует, что будет только одно устройства соответствия этого описания.Чтение отчета функции USB HID

Это не должно быть сложно, но я чувствую себя настолько запутанным, читая документацию MSDN.

Я получил это, работая над linux через пару часов, благодаря libudev :). Но мне нужна встроенная реализация windows (желательно VC++ и, вероятно, с использованием Hidsdi.h и или Setupapi.h)

Может кто-нибудь указать мне в правильном направлении.

+1

Попробуйте [HIDAPI] (http://www.signal11.us/oss/hidapi/). –

ответ

1

Получил его работу с родными библиотеками окон, это, вероятно, не правильный путь для выполнения этой задачи, но он работает. Я бы советовал не использовать этот код напрямую, так как это ужасно, но не стесняйтесь читать его для чего-нибудь полезного.

Он находит HID с идентификатором устройства: 0021 и идентификатором продавца: 2833 затем считывает отчет о функции 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; 
}