SetupDiGetDeviceInterfaceDetail возвращает только путь \ для всех объектов USB HID.

Я могу сказать, сколько у меня USB HID-устройств (7), но каждый раз, когда я пытаюсь получить подробную информацию о каком-либо устройстве, возвращаемый путь для него всегда «\», что делает так, что я вообще не могу получить доступ к устройству. . Я использую код, который очень похож по процедуре на этот код:

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);

person xitrium    schedule 16.11.2009    source источник


Ответы (2)


Наверняка вы компилируете с определением UNICODE? Тогда ваша строка форматирования Log() неверна. Исправить:

   Log("Opening device with path: %ls", deviceDetail->DevicePath);
person Hans Passant    schedule 16.11.2009
comment
Не обязательно, %s может быть в порядке, например. когда LOG вызывает wsprintfW - person MSalters; 17.11.2009
comment
wsprintf() требует const wchar_t*, он передает const char*. Но самое главное, это очень четко объясняет, почему он получает только \. - person Hans Passant; 17.11.2009
comment
О, чувак, nobugz, ты спасатель. Я предполагал, что наша функция журнала нормально обрабатывает UNICODE, но после просмотра этого поста я попробовал ее с %ls, и теперь она выводит что-то вроде: } что кажется гораздо более правильным, чем \ по крайней мере. Огромное спасибо! - person xitrium; 17.11.2009
comment
Хм, мой вызов CreateFile по-прежнему завершается с ошибкой ERROR_ACCESS_DENIED. Нужна ли мне юникод-версия функции или что-то в этом роде? Как указать unicode против ascii? еще раз спасибо! - person xitrium; 17.11.2009
comment
Я рекомендую вам создать другую тему и лучше задокументировать вашу проблему. - person Hans Passant; 17.11.2009
comment
Отличная идея. Чтобы быть полным, моя ошибка отказа в доступе, по-видимому, возникает из-за того, что я пытался открыть клавиатуру или мышь с разрешением на чтение. - person xitrium; 17.11.2009

В документации для SetupDiEnumDeviceInterfaces указано, что вы должны сначала вызвать его с помощью deviceIndex==0; вы не должны пропускать значения.

person MSalters    schedule 17.11.2009