Возможно ли получить locationpath для всех юсб портов, включая те на которых нет подключенного устройства

Рейтинг: 0Ответов: 0Опубликовано: 11.05.2023

Есть такой кусок кода:

HANDLE hVol;
DWORD nbytes;
WCHAR letter;
WCHAR volume[100] = { 0 };
//int i;
STORAGE_DEVICE_NUMBER sdn = { 0 };



WCHAR match[1024] = { 0 };
WCHAR match1[1024] = {0};
GUID guid = { 0xF18A0E88, 0xC30C, 0x11D0, { 0x88, 0x15, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0xD8 } };
/*USB HUB Interface class GUID*/

HDEVINFO deviceInfoHandle = SetupDiGetClassDevs(&guid, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

if (deviceInfoHandle != INVALID_HANDLE_VALUE)
{
    int deviceIndex = 0;
    while (true)
    {
        SP_DEVICE_INTERFACE_DATA deviceInterface = { 0 };
        deviceInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

        //получение всех USB-концентраторов
        if (SetupDiEnumDeviceInterfaces(deviceInfoHandle, 0, &guid, deviceIndex, &deviceInterface))
        {
            
            DWORD cbRequired = 0;

            SetupDiGetDeviceInterfaceDetail(deviceInfoHandle, &deviceInterface, 0, 0, &cbRequired, 0);
            if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
            {
                PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetail =
                    (PSP_DEVICE_INTERFACE_DETAIL_DATA)(new char[cbRequired]);
                memset(deviceInterfaceDetail, 0, cbRequired);
                deviceInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
                
                if (!SetupDiGetDeviceInterfaceDetail(deviceInfoHandle, &deviceInterface,
                    deviceInterfaceDetail, cbRequired, &cbRequired, 0))
                {
                    delete[] deviceInterfaceDetail;
                    deviceIndex++;
                    continue;
                }

                // Initialize the structure before using it.
                memset(deviceInterfaceDetail, 0, cbRequired);
                deviceInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

                // Call the API a second time to retrieve the actual
                // device path string.
                BOOL status = SetupDiGetDeviceInterfaceDetail(
                    deviceInfoHandle,  // Handle to device information set
                    &deviceInterface,     // Pointer to current node in devinfo set
                    deviceInterfaceDetail,   // Pointer to buffer to receive device path
                    cbRequired,   // Length of user-allocated buffer
                    &cbRequired,  // Pointer to arg to receive required buffer length
                    NULL);        // Not interested in additional data

                BOOL res;

                /*Открываем устройство для отправки IOCTL*/
                HANDLE handle = CreateFile(deviceInterfaceDetail->DevicePath, GENERIC_WRITE, FILE_SHARE_WRITE,
                    0, OPEN_EXISTING, 0, 0);

                if (handle != INVALID_HANDLE_VALUE) {

                    DWORD bytes_read = 0;
                    UINT ports = 0;
                    USB_NODE_INFORMATION nodeinfo;
                    USB_NODE_CONNECTION_INFORMATION_EX coninfo = { 0 };
                    const UINT BUFSIZE = 1000;
                    char buffer[BUFSIZE] = { 0 };
                    USB_DESCRIPTOR_REQUEST* req = (USB_DESCRIPTOR_REQUEST*)&buffer;
                    USB_STRING_DESCRIPTOR* desc;

                    ZeroMemory(&nodeinfo, sizeof(nodeinfo));
                    nodeinfo.NodeType = UsbHub;

                    //получаем число портов на концентраторе                         
                    res = DeviceIoControl(handle, IOCTL_USB_GET_NODE_INFORMATION,
                        &nodeinfo, sizeof(nodeinfo), &nodeinfo, sizeof(nodeinfo), &bytes_read, 0);

                    if (res == FALSE)ErrorMes(L"DeviceIoControl");
                    else { ports = (UINT)nodeinfo.u.HubInformation.HubDescriptor.bNumberOfPorts; }

                    for (int j = 1; j <= ports; j++) {
                        ZeroMemory(&coninfo, sizeof(coninfo));
                        coninfo.ConnectionIndex = j;

                        //получаем инфу о порте
                        res = DeviceIoControl(handle, IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX,
                            &coninfo, sizeof(coninfo), &coninfo, sizeof(coninfo), &bytes_read, 0);
                        if (res == FALSE) { ErrorMes(L"DeviceIoControl"); continue; }

                        if (coninfo.ConnectionStatus == 0) continue; //нет устройства



                
                            
                        }
                        

                    }

                    CloseHandle(handle);
                }
                else {
                    ErrorMes(L"CreateFile");//failed to open device
                }//endif


                delete[] deviceInterfaceDetail;
            }
        }
        else
        {
            break;
        }

        ++deviceIndex;
    }


    SetupDiDestroyDeviceInfoList(deviceInfoHandle);
}
else ErrorMes(L"SetupDiGetClassDevs");

который по сути перебирает все порты компьютера.

Вопрос состоит в том, есть ли способ получить locationpath (например, PCIROOT(0)#PCI(1400)#USBROOT(0)#USB(7)) для всех портов, даже для тех, в которые не подключены устройства?

И если есть, то подскажите, каким образом его можно достать.
Если на конце есть устройство, то всё просто решается через SetupDiGetDeviceProperty и &DEVPKEY_Device_LocationPaths, но если нет, то обратиться к такому же свойству самого порта у меня не вышло.

Благодарю за ваше время.

Ответы

Ответов пока нет.