Как перечислить концентратор USB, подключенный к первому порту корневого концентратора в Windows Embedded 7

0

Я публикую здесь в первый раз, надеюсь, это будет понятно и понятно.

В настоящее время я пытаюсь проверить наличие USB-устройств во встроенной системе, используя программный интерфейс HCD и порт, используя C++ и Visual Studio 2008.

Идея состоит в том, чтобы передать номер порта и значение hcd в качестве параметров функции, а функция вернет значение true или false, указывающее статус соединения.

Я написал код для заполнения корневого концентратора и докажу, что устройство, подключенное к порту 1 корневого концентратора, является хабом, использующим bool DeviceIsHub из usbioctl.h.

Однако, когда я пытаюсь перечислить концентратор usb, подключенный к порту 1 корня, чтобы я мог проверить состояние соединения портов ниже по потоку для присутствия устройства (порты 1 и 2 этого концентратора usb). Кажется, он не знает, сколько портов в нисходящем потоке имеет концентратор usb.

Я проверил USBVIEW/TreeView, оба приложения говорят мне, что есть устройства, но я не уверен, какой код команды ioctl использовать, чтобы я мог перечислять порты, расположенные ниже по потоку, чтобы я мог проверить состояние соединения.

Структура устройства на основе вида USB и дерева USB обеспечивает следующее.

  • Корневой концентратор - он имеет 7 портов, используется только первый порт.

  • USB-концентратор (он имеет четыре доступных порта) подключен к первому порту корневого концентратора.

  • Два USB-устройства (USB-мышь и USB-клавиатура) подключены к порту 1 и порту 2 USB-концентратора.

Я попробовал IOCTL_USB_GET_CONNECTION_INFORMATION, IOCTL_USB_GET_CONNECTION_NAME, IOCTL_USB_GET_CONNECTION_INFORMATION_EX, IOCTL_USB_PORT_CONNECTOR_PROPERTIES

(который не поддерживается, его можно использовать только в окнах 8, это точный вызов ioctl, который они использовали для перечисления портов).

Пожалуйста, проигнорируйте MessageBoxes, это для меня, чтобы проверить статус пути управления и определить, какой маршрут он выполняет.

Пожалуйста, найдите код, который я написал, пытаясь перечислить/заполнить концентратор usb. Я не включил код корневого концентратора, потому что это сделало бы этот фрагмент слишком большим.

Мои вопросы в основном связаны с процессом перечисления вторичного USB-хаба, на который я верю. Я просто проверил раздел реестра устройства. кажется, что USB-концентратор перечислили и присутствовали на устройстве, поскольку информация отображается в разделе regedit HKLM->System->CurrentControlSet->Enum->USB. Я считаю, что я не перечисляю его правильно в своем тестовом приложении.

Любая помощь будет принята с благодарностью.

Обновить

Наиболее интересной для меня является DeviceIoControl Calls, которая пытается получить размер и фактическое имя этого USB-концентратора.

В настоящее время он занимает только USB_GET_NODE_INFORMATION. Любые другие вызовы ioctl, предназначенные для извлечения имени концентратора, будут сбой в первом DeviceIoControl, где он попытается получить размер имени концентратора, чтобы он знал, сколько памяти выделяется для него.

Обновить часть 2

От наблюдения за открытым исходным кодом usbview, мне кажется, мне нужно сначала перечислить главный контроллер и все устройства, прежде чем проверять наличие устройства. Я сделал вывод, что, не делая перечисления контроллера, он доходит до дерева (в лучшем случае второго слоя, к которому в моем случае подключен внешний концентратор).

В настоящее время я пытаюсь перечислить другие устройства и контроллеры в надежде, что смогу добраться до третьего уровня устройства. Я буду продолжать обновлять этот поток, пока не выясню проблему самостоятельно, или кто-то не сможет ответить на мои вопросы.

    //we are connected to the external hub, now we can begin the configuration and enumeration of the external hub.
        ULONG           kBytes = 0;
        USB_HUB_NAME    SubHubName;
    //Create a Handle for the external hub driver
        char Name[16];
             wsprintf(Name, "\\\\.\\HCD%d", HcdSub);
             HANDLE SubHub = CreateFile(Name,
                          GENERIC_WRITE,
                          FILE_SHARE_WRITE,
                          NULL,
                          OPEN_EXISTING,
                          0,
                          NULL);

    //Check to see if the handle was created successfully 
    if (SubHub == INVALID_HANDLE_VALUE)
         {
             MessageBox(NULL,"SubHandle Fail ","TEST",MB_OK);
                 return false;
         }
//Query the SUBHUB/External Hub for the structure, this will tell us the number of down stream ports we need to enumerate
    ioctlSuccess = DeviceIoControl(SubHub,
                      IOCTL_USB_GET_NODE_INFORMATION,
                      0,
                      0,
                      &SubHubName,
                      sizeof(SubHubName),
                      &kBytes,
                      NULL);

    //If the command failed, close the handle and return false.
    if(!ioctlSuccess)
    {
        CloseHandle(SubHub);
        MessageBox(NULL," sub hub size fail ","TEST",MB_OK);
        return false;
    }
    //Prepare to receive the SubHubName
    kBytes = SubHubName.ActualLength;
    USB_HUB_NAME *subHubNameW = (USB_HUB_NAME *) malloc(sizeof(USB_HUB_NAME) * kBytes);
    //Check if the allocation failed, if it did, free the memory allocated and return false.
    if (subHubNameW == NULL)
    {
        free(subHubNameW);
        CloseHandle(SubHub);
        MessageBox(NULL,"SUBHubNameW=NULL ","TEST",MB_OK);
        return false;
    }
    //Send the command to retrieve the name
        ioctlSuccess = DeviceIoControl(SubHub,
                      IOCTL_USB_GET_NODE_INFORMATION,
                      NULL,
                      0,
                      subHubNameW,
                      kBytes,
                      &kBytes,
                      NULL);
    //We no longer need this handle.
    CloseHandle(SubHub);
    if(!ioctlSuccess)
    {
        if(subHubNameW !=NULL)
        {
            free(subHubNameW);
        }
        MessageBox(NULL,"GET NODE INFO FAIL ","TEST",MB_OK);
        return false;
    }

    //Converts the SubHubNAme from widechar to a cahr.
    MessageBox(NULL,"BEGIN CONVERTION","TEST",MB_OK);
    kBytes = wcslen(subHubNameW->HubName) + 1;
    char *subhubname = (char *) malloc(sizeof(char)*kBytes);
    wcstombs(subhubname,subHubNameW->HubName, kBytes);
    //we no longer need subHubNameW the information is now in subhubname.
    if(subHubNameW !=NULL)
    {
        free(subHubNameW);
    }
    //Attempt to open a handle to driver for sub hub.
    int SubhdnSize = strlen(subhubname) + sizeof("\\\\.\\");
    char *subhubnamelength = (char *) malloc(sizeof(char) * SubhdnSize);
    sprintf(subhubnamelength, "\\\\.\\%s", subhubname);
    //We no longer need subhubname, so free it.
    if(subhubname !=NULL) free(subhubname);
    //Attempt to open a handle for enumerating ports on this hub.

    HANDLE ExternalHub = CreateFile(subhubnamelength,
                    GENERIC_WRITE,
                    FILE_SHARE_WRITE,
                    NULL,
                    OPEN_EXISTING,
                    0,
                    NULL);
//we no longer need subhubnamelength, so free it if it is not NULL
    if(subhubnamelength != NULL) free(subhubnamelength);
        //Check and see if the handle was created successfully, if not, return false.
        if(ExternalHub == INVALID_HANDLE_VALUE)
        {
                CloseHandle(ExternalHub);
                MessageBox(NULL,"EXT handle fail ","TEST",MB_OK);
                return false;
        }
    }

USB_NODE_CONNECTION_ATTRIBUTES *PortConnection = 
(USB_NODE_CONNECTION_ATTRIBUTES *) malloc(sizeof(USB_NODE_CONNECTION_ATTRIBUTES));
PortConnection ->ConnectionIndex = Port;

ioctlSuccess = DeviceIoControl(ExternalHub,
                  IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES,
                  PortConnection,
                  sizeof(USB_NODE_CONNECTION_ATTRIBUTES),
                  PortConnection,
                  sizeof(USB_NODE_CONNECTION_ATTRIBUTES),
                  &kBytes,
                  NULL);

    if(!ioctlSuccess)
    {
        MessageBox(NULL,"DEVICE CONNECTION FAIL ","TEST",MB_OK);
        return false;
    }
    if(PortConnection->ConnectionStatus !=DeviceConnected)
    {
        printf("The Connection Status Returns: %d",PortConnection->ConnectionStatus);
        printf("\n");
        return false;
    }
  • 1
    То есть ваша «встроенная система» работает под управлением Windows?
  • 0
    Да сэр. На нем есть операционная система.
Показать ещё 8 комментариев
Теги:
embedded
usb

2 ответа

0

Вы ничего не можете перечислять. Обычно устройство USB является либо шинным устройством, либо дочерним устройством шины. Чувство, что устройство шины не является съемным, оно автоматически перечисляется acpi.sys корневым устройством во время загрузки или если устройство шины для какого-либо другого устройства подключено к корневому узлу, то это устройство должно пройти некоторое событие, которое означает, что оно обнаруживает устройство, а затем перечисляет его, подключи и играй автоматически ищет драйвер типа устройства, и если он будет установлен, он будет загружать его. Если usb говорит, что имеет 4 фактических USB-разъема, которые управляются с центрального устройства, может быть пара драйверов USB/мини-драйверов. В этом случае драйвер минипорта является дочерним элементом драйвера usb и перечисляется им и прикрепляется к нему. Работа мини-порта - это знать фактическое оборудование, а irp и все остальные io будут из него родителями. Если есть несколько физических подключений, могут быть дополнительные драйверы для детей. Все они управляют оборудованием, и есть горячая вилка. Когда прошивка обнаруживает установку USB-устройства, она передает это драйверу минипорта и по стеку на шину и в конечном итоге обрабатывается подключением и воспроизведением. Затем подключи и играй драйвер мини-порта перечислит его устройство, но ему нужно получить идентификатор оборудования. Затем он может найти драйвер и загрузить его, затем устройство будет установлено и готово к работе.

Не зная стека устройств, неясно, на каком устройстве оно ссылается. Помните, что стек драйверов может не отражать фактическую аппаратную топологию. Есть также такие вещи, которые называются логическими устройствами, которые не представляют собой часть аппаратного обеспечения. Любой из них должен быть принят во внимание, и вам нужно знать, какое устройство соответствует концу узла.

Также одна маленькая деталь. Я не так хорошо знаком с пользовательским режимом api и драйверами, поскольку я являюсь ядром, но кажется, что второй аргумент wsprintf управляет форматом выходного буфера от ввода. Это должно быть %[]%[] были [] - это символ, который представляет формат. Он будет форматировать первый символ в соответствии с первым символом, а затем вторым символом с вторым символом. Кажется, вы делаете что-то другое.

wsprintf(), кажется, что использование wsprintf() теперь устарело вместо других api.

0

Перечисление USB в Windows 7 завершится неудачей, если UAC включен, а приложение не имеет достаточных привилегий. Windows Embedded 7 может также работать с аналогичной задачей.

Существует также возможность перечислить через реестр.

  • 0
    Я на самом деле отключил UAC, хотя он там есть. В целях избежания проблем, вызванных недостаточными правами доступа. Хороший вопрос, хотя.
  • 0
    Я вижу, что вы проверили устройство с помощью regedit в HKLM-> System-> CurrentControlSet-> Enum-> USB. Если он представлен там, простого перечисления листа реестра будет достаточно, чтобы проверить, присутствует ли устройство или нет.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню