Перечисление интерфейсов в наборе информации об устройстве, полученном для конкретного перечислителя PnP

Я пытаюсь получить данные об интерфейсах устройства через SetupDiEnumDeviceInterfaces() для всех устройств, которые соответствуют определенному перечислителю PnP. Рассмотрим следующий пример (только для интерфейса с индексом 0):

#include <stdio.h>
#include <Windows.h>
#include <SetupAPI.h>

static int get_interface(HDEVINFO);

int main()
{
    HDEVINFO devInfoSet = SetupDiGetClassDevsA(NULL, "USBSTOR", NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
    if (devInfoSet == INVALID_HANDLE_VALUE)
    {
        fprintf(stderr, "SetupDiGetClassDevsA: Error %lu\n", GetLastError());
        return 1;
    }

    int ret = get_interface(devInfoSet);

    SetupDiDestroyDeviceInfoList(devInfoSet);
    return ret;
}

int get_interface(HDEVINFO devInfoSet)
{
    SP_DEVICE_INTERFACE_DATA devIface = { sizeof(SP_DEVICE_INTERFACE_DATA) };
    if (!SetupDiEnumDeviceInterfaces(devInfoSet, NULL, &GUID_DEVINTERFACE_DISK, 0, &devIface))
    {
        fprintf(stderr, "SetupDiEnumDeviceInterfaces: Error %lu\n", GetLastError());
        return 1;
    }

    /* ... */
}

(Более полная версия этого примера доступна здесь.)

После запуска этого, SetupDiEnumDeviceInterfaces() не удается с GetLastError() возвращаем ошибку 259 (ERROR_NO_MORE_ITEMS), как будто не было никаких интерфейсов для информации об устройстве, установленной для начала. Кажется, это поведение для всех наборов информации об устройстве, полученных для классов настройки устройства, а не классов интерфейса устройства.

Однако, когда я добавляю DIGCF_DEVICEINTERFACE флаг до последнего аргумента SetupDiGetClassDevsA() вызов, так что набор получен для классов интерфейса, последний завершается с ошибкой 13 (ERROR_INVALID_DATA). Та же самая ошибка обычно возникает в случае классов настройки устройства, когда указанный перечислитель PnP не зарегистрирован в системе. Действительно, когда я заменяю аргумент перечислителя на NULL Интерфейс получен успешно. Согласно MSDN, указав DIGCF_DEVICEINTERFACE flag позволяет использовать идентификатор экземпляра устройства вместо аргумента перечислителя, но мне приходит в голову, что вышеупомянутые идентификаторы экземпляра устройства и NULL единственные варианты SetupDiGetClassDevs() аргумент перечислителя вызова, когда он имеет DIGCF_DEVICEINTERFACE флаг присутствует, с фактическими перечислителями, не имеющими отношения к делу.

Не могли бы вы объяснить мне, что на самом деле здесь происходит? Я не знаком с семантикой SetupAPI, поэтому не могу сказать, какие ограничения будут накладываться на получение информации об устройстве, установленной для классов настройки устройства, в отличие от ограничений для классов интерфейса устройства. Кроме того, может ли здесь быть какое-то поведение, зависящее от версии? Приведенный выше код был протестирован в системе Windows 7 x64, но сам компилировался в 32-разрядный исполняемый файл. Мне нужно знать, будет ли какое-либо конкретное решение, предложенное для этого, работать на хорошей старой Windows XP.

PS Не дублируйте путь получения устройства для CreateFile при перечислении устройств с помощью SetupDiEnumDeviceInfo, несмотря на аналогичную базовую цель.;)

0 ответов

Другие вопросы по тегам