Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: USB Hub port for USB Mass storage  (Прочитано 12775 раз)
0 Пользователей и 1 Гость смотрят эту тему.
BayE
Гость
« : 15-06-2008 12:40 » 

Всем привет,

Не подскажите, пожалуйста, как для флешки (USB Mass Storage) узнать USB Hab ID и порт, которому она подключена,

- С одной стороны можно пройтись по всех Хостaм и Хабам и собрать всю инфу по ним через  IOCTL_USB_GET_ROOT_HUB_NAME
IOCTL_USB_GET_NODE_INFORMATION,
IOCTL_USB_GET_NODE_CONNECTION_INFORMATION
И, как результат, поиметь VID, PID и т.д -> USB_HUB_DESCRIPTOR
- С другой стороны можно про флешку тоже данные вытащить через IOCTL_STORAGE_QUERY_PROPERTY
и узнать DrivePath, Vendor Name, Product Name и т.д. -> STORAGE_DEVICE_DESCRIPTOR

Но как вот эти данные между собой замапить - ну никак не получается.
Т.е. узнать на каком Хабе (порте хаба) эта флешка сидит м какие у нее VID и PID.

Может, делал кто-нибудь подобное?

Спасибо!

- Егор

 


Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 16-06-2008 08:18 » 

в DDK есть USBVIEW. перечисляет все USB хост контроллеры, USB хабы и присоединенные устройства. и лезет через реестр для определения что - кто.
DDK\DDK3790.1830\src\wdm\usb\usbview\
реализовано в ring-3. но теоретически можно и в драйвер переложить, если очень надо.
может быть есть более простые пути... но тут я не специалист;)
это просто как предложение, я с USB особо не сталкивался.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
BayE
Гость
« Ответ #2 : 16-06-2008 09:15 » 

Спасибо, Ochkarik!

Да - через реестр это можно сделать.
Только фишка в том, что хотелсоь бы без него обойтись.

Просто очень хочется более простой путь найти - должны же как-то USB_HUB_DESCRIPTOR и STORAGE_DEVICE_DESCRIPTOR завязаны быть.
Ведь это , в принципе, про одно и тоже, просто с разных сторон...
Улыбаюсь

Будем копать - если ничего не найду - придется через реестр...

Пасибо!

- BayE

Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 17-06-2008 07:18 » 

на сайте WinDriver:
http://www.jungo.com/st/support/tech_docs/td27.html

Цитата
"How do I detect the location of my USB device on my Windows 2000 PC?

The sequence of operations for detecting the USB device location:
The USB device location is represented by the device's HUB identifier and the port in the HUB: Z&ZZZZZZZ&Z&A. Z&ZZZZZZZ&Z is the HUB identifier or PrefixID, and A is the port/address in the HUB (1 to 8).
In order to retrieve the device location ID, you must first retrieve the device instance ID, represented by the device type, Vendor ID, Product ID, HUB ID and port ID: USB\VID_XXXX&PID_YYYY\Z&ZZZZZZZ&Z&A.
DeviceInstanceId is returned by SetupDiGetDeviceInstanceId().
In order to detect the USB device location:

1. Get the DriverKeyName by calling WinDriver's WDU_GetDeviceRegistryProperty() function (or WD_GetDeviceProperty() - for v8.12 and below) with the WdDevicePropertyDriverKeyName registry property.
2. Get the ClassGUID, by calling WDU_GetDeviceRegistryProperty() (or WD_GetDeviceProperty()) - in v8.12 and below) with the WdDevicePropertyClassGuid property.
3. By using GetDeviceInstanceId() (see later) with the retrieved DriverKeyName and ClassGUID, get the DeviceInstanceId.
4. From the retrieved DeviceInstanceId, get the USB device location, Z&ZZZZZZZ&Z&A."
Код:
/*
   szDriverKeyName is returned by
   WDU_GetDeviceRegistryProperty() /
   WD_GetDeviceProperty().
   It looks like:
   {C671678C-82C1-43F3-D700-0049433E9A4B}\\0017
   szClassGUID is returned by WDU_GetDeviceProperty.
   It looks like:
   {C671678C-82C1-43F3-D700-0049433E9A4B}

   GetDeviceInstanceId() creates a list of the device
   information for all devices of the specified class.
   The function then searches the list for the
   WinDriver device and retrieves the device instance
   ID (*pszDeviceInstanceId).
*/


#include <windows.h>
#include <setupapi.h>
#include <string.h>

BOOL GetDeviceInstanceId(LPCTSTR szClassGUID, LPCTSTR
    szDriverKeyName, PTCHAR *pszDeviceInstanceId)
{
    /* Build class GUID from szClassGUID */
    GUID guid;
    DWORD dwMemberIndex=0;
    SP_DEVINFO_DATA DeviceInfoData;
    BOOL bResult;
    DWORD dwError;
    DWORD dwPropertyBufferSize;
    PTCHAR pbPropertyBuffer;
    DWORD dwRequiredSize;
    DWORD dwPropertyRegDataType;
    HDEVINFO hDeviceInfoSet;

    StringToGUID(szClassGUID,&guid);

    *pszDeviceInstanceId = NULL;

    /* Create a list of the device information for all
       devices of the specified class */
    hDeviceInfoSet = SetupDiGetClassDevs(&guid,;
        NULL, NULL, DIGCF_PRESENT);

    if (INVALID_HANDLE_VALUE == hDeviceInfoSet)
    {
        /* Set error */
        /* ........... */
        return FALSE;
    }

    /* Search the device information list for
       the WinDriver device */

    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    do {
        /* Get the next device in the list */
        bResult =
            SetupDiEnumDeviceInfo(hDeviceInfoSet,
                dwMemberIndex, &DeviceInfoData);

        if (bResult)
        {
            dwRequiredSize = 0;
            /* Check if there is a driver reg path for
               this device */

            /* First get the size only */
            bResult = SetupDiGetDeviceRegistryProperty
                (hDeviceInfoSet,
                &DeviceInfoData,
                SPDRP_DRIVER,
                &dwPropertyRegDataType,
                NULL, 
                0,
                &dwRequiredSize);

            if (bResult && dwRequiredSize > 0)
            {
                dwPropertyBufferSize =
                    dwRequiredSize + 1;

                pbPropertyBuffer =
                    (TCHAR *)malloc(sizeof(TCHAR) *
                    dwPropertyBufferSize);

                ASSERT(pbPropertyBuffer != NULL);

                /* Then get this driver's actual
                   registry path */
                if (SetupDiGetDeviceRegistryProperty
                    (hDeviceInfoSet,
                    &DeviceInfoData,
                    SPDRP_DRIVER,
                    &dwPropertyRegDataType,
                    (PBYTE)pbPropertyBuffer,
                    dwPropertyBufferSize,
                    &dwRequiredSize))
                {
                    /* Check if the reg path is the
                       same as in WinDriver */
                    int iResult = _tcscmp(
                        pbPropertyBuffer,
                        szDriverKeyName);
                  
                    if (iResult == 0)
                    {
                        /* This is the device we are
                           working with in WinDriver */

                        /* Get the device's
                           instance ID */

                        /* First get the size only */
                        dwRequiredSize = 0;

                        bResult =
                            SetupDiGetDeviceInstanceId
                                (hDeviceInfoSet,
                                &DeviceInfoData,
                                NULL,
                                0,
                                &dwRequiredSize);

                        if (bResult && dwRequiredSize)
                        {
                            *pszDeviceInstanceId ==
                                (TCHAR *)malloc(
                                sizeof(TCHAR) *
                                (dwRequiredSize + 1));

                            ASSERT(*pszDeviceInstanceId
                                != NULL);

                            /* Then get the actual
                               device instance id */
                            if (
                            !SetupDiGetDeviceInstanceId
                                (hDeviceInfoSet,
                                &DeviceInfoData,
                                *pszDeviceInstanceId,
                                dwRequiredSize + 1,
                                NULL))
                            {
                                dwError =
                                GetLastError();
                                /* ..... */
                            }
                        }
                    }
                }
                else
                    delete pbPropertyBuffer;             }
        }

        dwMemberIndex++;

    } while(bResult && !*pszDeviceInstanceId);

    SetupDiDestroyDeviceInfoList(hDeviceInfoSet);
    return FALSE;
}

к сожалению давно его потер, так что в функциях посмотреть не могу. а заново ставить - времени жалко(
но думаю там легко будет выдрать суть, из их классов.
по моему это то, что надо)

PS или это все тоже API?
« Последнее редактирование: 17-06-2008 07:28 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
BayE
Гость
« Ответ #4 : 21-06-2008 13:45 » new

Спасибо - пример полезный, но не то, что мне нужно, хотя логика примерно такая же.

Этот код дает USB\VID_XXXX&PID_YYYY\Z&ZZZZZZZ&Z&A. для девайсов.
"A" - devcie location или номер потра хаба 1-8.

А мне нужно было Drive Path, PID, VID.

в общем, после долгих поисков почти идеальный пример все таки нашелся через google:

http://www.eggheadcafe.com/software/aspnet/32416302/how-to-make-link-between.aspx

Немного его проапдейтить и все ОК.


- Baye

P.S. Very big respect to Mr. Ochkarik!
 Улыбаюсь
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines