3

I can tell how many USB HID devices I have (7), but every time I try to get details on any device, the path returned for it is always "\", making it so that I can't access the device at all. I'm using code that is very similar in procedure to this code:

HANDLE connectDeviceNumber(DWORD deviceIndex)
{
    GUID hidGUID;
    HDEVINFO hardwareDeviceInfoSet;
    SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
    PSP_INTERFACE_DEVICE_DETAIL_DATA deviceDetail;
    ULONG requiredSize;
    HANDLE deviceHandle = INVALID_HANDLE_VALUE;
    DWORD result;

    //Get the HID GUID value - used as mask to get list of devices
    HidD_GetHidGuid (&hidGUID);

    //Get a list of devices matching the criteria (hid interface, present)
    hardwareDeviceInfoSet = SetupDiGetClassDevs (&hidGUID,
                                                 NULL, // Define no enumerator (global)
                                                 NULL, // Define no
                                                 (DIGCF_PRESENT | // Only Devices present
                                                 DIGCF_DEVICEINTERFACE)); // Function class devices.

    deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

    //Go through the list and get the interface data
    result = SetupDiEnumDeviceInterfaces (hardwareDeviceInfoSet,
                                          NULL, //infoData,
                                          &hidGUID, //interfaceClassGuid,
                                          deviceIndex, 
                                          &deviceInterfaceData);

    /* Failed to get a device - possibly the index is larger than the number of devices */
    if (result == FALSE)
    {
        SetupDiDestroyDeviceInfoList (hardwareDeviceInfoSet);
        Log("hidin: -- failed to get specified device number");
        return INVALID_HANDLE_VALUE;
    }

    //Get the details with null values to get the required size of the buffer
    SetupDiGetDeviceInterfaceDetail (hardwareDeviceInfoSet,
                                     &deviceInterfaceData,
                                     NULL, //interfaceDetail,
                                     0, //interfaceDetailSize,
                                     &requiredSize,
                                     0); //infoData))

    //Allocate the buffer
    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 (hardwareDeviceInfoSet,
                                          &deviceInterfaceData,
                                          deviceDetail,
                                          requiredSize,
                                          &requiredSize,
                                          NULL)) 
    {
        SetupDiDestroyDeviceInfoList (hardwareDeviceInfoSet);
        free (deviceDetail);
        Log("hidin: -- failed to get device info");
        return INVALID_HANDLE_VALUE;
    }

    Log("Opening device with path: %s", deviceDetail->DevicePath);
xitrium
  • 4,235
  • 4
  • 23
  • 17

2 Answers2

5

Surely you are compiling with UNICODE defined? Then you Log() formatting string is wrong. Fix:

   Log("Opening device with path: %ls", deviceDetail->DevicePath);
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Doesn't have to be, %s could be OK, e.g. when LOG calls `wsprintfW` – MSalters Nov 17 '09 at 09:25
  • 1
    wsprintf() requires a const wchar_t*, he's passing a const char*. But most of all, it does so very cleanly explain why he only ever gets a "\". – Hans Passant Nov 17 '09 at 11:18
  • Oh man, nobugz you are a lifesaver. I was assuming that our Log function handled UNICODE okay but after seeing this post I tried it out with %ls and it now prints out stuff like: \\?\hid#vid_045e&pid_071d&mi_00#9&1b684538&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} which seems much more correct than "\" at least. Thanks so much! – xitrium Nov 17 '09 at 15:22
  • Hmm, my CreateFile call is still failing with ERROR_ACCESS_DENIED. Do I need a unicode version of the function or something? How does one specify unicode vs. ascii? thanks again! – xitrium Nov 17 '09 at 15:35
  • 1
    I recommend you start another thread and document your problem better. – Hans Passant Nov 17 '09 at 16:15
  • Good idea. Just to be complete, my access denied error apparently results because I was trying to open a keyboard or mouse with read permission. – xitrium Nov 17 '09 at 16:20
1

The documentation for SetupDiEnumDeviceInterfaces states that you should first call it with deviceIndex==0; you're not supposed to skip values.

MSalters
  • 173,980
  • 10
  • 155
  • 350