У меня есть DEVINST, мне нужен путь к устройству - PullRequest
0 голосов
/ 30 мая 2018

Я пытаюсь открыть устройство WinUSB, которое является частью составного устройства.Я нашел правильное дочернее устройство, используя cfgmgr32, и у меня есть его номер DEVINST.Чтобы открыть его с помощью WinUSB, мне нужно сначала вызвать CreateFile, для которого мне нужен путь устройства.

Путь устройства выглядит следующим образом:

\\\\?\\usb#vid_9999&pid_0102#3555303335351909000b0#{a5dcbf10-6530-11d2-901f-00c04fb951ed}

Как я могу получить путь к устройству?

Ответы [ 2 ]

0 голосов
/ 02 июля 2019

Эта функция возвращает список путей к устройствам с нулевым символом в конце (это то, что мы получаем из CM_Get_Device_Interface_List)

Вам необходимо передать ему DEVINST и требуемый интерфейс GUID.

Поскольку указаны и DEVINST, и GUID интерфейса, весьма вероятно, что CM_Get_Device_Interface_List вернет один путь к устройству для этого интерфейса, но технически вы должны быть готовы получить более одного результата.

Я успешно использовал эту функцию в производственном коде для получения интерфейса устройства USB-концентратора (GUID_CLASS_USBHUB): я использовал полученный путь к устройству с помощью CreateFile и успешно открыл его.

Ответственность за вызовdelete[] возвращаемый список, если функция успешно возвращается (код возврата 0)

int GetDevInstInterfaces(DEVINST dev, LPGUID interfaceGUID, wchar_t**outIfaces, ULONG* outIfacesLen)
{
    CONFIGRET cres;
    if (!outIfaces)
        return -1;
    if (!outIfacesLen)
        return -2;

    // Get System Device ID
    WCHAR sysDeviceID[256];
    cres = CM_Get_Device_ID(dev, sysDeviceID, sizeof(sysDeviceID) / sizeof(sysDeviceID[0]), 0);
    if (cres != CR_SUCCESS)
        return -11;

    // Get list size
    ULONG ifaceListSize = 0;
    cres = CM_Get_Device_Interface_List_Size(&ifaceListSize, interfaceGUID, sysDeviceID, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
    if (cres != CR_SUCCESS)
        return -12;

    // Allocate memory for the list
    wchar_t* ifaceList = new wchar_t[ifaceListSize];

    // Populate the list
    cres = CM_Get_Device_Interface_List(interfaceGUID, sysDeviceID, ifaceList, ifaceListSize, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
    if (cres != CR_SUCCESS) {
        delete[] ifaceList;
        return -13;
    }

    // Return list
    *outIfaces = ifaceList;
    *outIfacesLen = ifaceListSize;

    return 0;
}
0 голосов
/ 31 мая 2018

Я рекомендую взглянуть на функцию get_filename_from_devinst_and_guid , которая является частью libusbp .

Основная схема:

  1. Убедитесь, чтоВы знаете GUID интерфейса устройства, который ищете.Это то, что указано в скобках в конце имени файла, которое вы указали.Обычно это происходит из INF-файла, который устанавливает WinUSB, хотя он также может поступать из дескрипторов MS OS на устройстве.Вы можете найти это в реестре.Вы должны упаковать его в Win32 API GUID struct.
  2. Вызвать SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);, чтобы получить список всех существующих (подключенных) устройств, поддерживающих этот GUID интерфейса устройства.
  3. Use SetupDiEnumDeviceInfo для перебора списка, пока вы не найдете элемент, который соответствует найденному DEVINST.
  4. Используйте SetupDiEnumDeviceInterfaces, чтобы получить список интерфейсов для этого элемента.Должна быть только одна запись, потому что вы уже указали интересующий GUID интерфейса устройства.
  5. Используйте SetupDiGetDeviceInterfaceDetail для получения SP_DEVICE_INTERFACE_DETAIL_DATA_A структуры данных.
  6. Имя файла, которое вы ищетев DevicePath член этой структуры.
...