Как узнать guid usb носителя
Перейти к содержимому

Как узнать guid usb носителя

  • автор:

Глобальный уникальный идентификатор класса устройства

GUID класса устройства — глобальный уникальный идентификатор класса устройства. Он обозначает к какому классу принадлежит устройство.

Как узнать GUID класса устройства

С помощью графического интерфейса

Выберите пункт «Диспетчер устройств» (Device Manager)
Раскройте выпадающее меню необходимой категории устройств и выберите необходимое устройство.
Вызовите контекстное меню нажав правой кнопкой мыши
В контекстном меню выберите пункт «Свойства» (Properties)
В открывшемся окне выберите вкладку «Сведения» (Details)
В выпадающем меню выберите пункт «GUID класса» (Class GUID)

GUID можно скопировать из строк «Значение» (Value) нажав «Ctrl+C».

С помощью командной строки

Для получения перечня устройств и GUID’ов их класса запустить командную строку от имени администратора и выполнить нижеуказанную команду

WMIC PATH Win32_PnPSignedDriver GET DeviceName,ClassGuid /format:list

guid_класса_устройства.txt · Последние изменения: 2019/11/01 15:33 — vladimir

Инструменты страницы

  • Показать исходный текст
  • История страницы
  • Ссылки сюда
  • Наверх

История использования USB

RSS

Ни для кого уже не секрет, что информация о разного рода активности многочисленных компонентов операционной системы попадает в реестр и файлы в виде записей заданного формата. При этом, информация эта нередко содержит чувствительные пользовательские данные: историю посещенных браузером страниц, кеш данных программ, информацию о подключаемых устройствах и многое многое другое. Во основном журналирование обеспечивается функциональными особенностями пользовательских программ, которые имеют встроенные алгоритмы сохранения истории операций, отчасти это возможно благодаря архитектурным особенностям ядра/HAL операционной системы, которые, производя конфигурирационные действия с устройствами, сохраняют информацию о последних в виде записей в системном реестре. Из всего многообразия подобной информации, в рамках данной статьи нас будет интересовать исключительно история использования USB устройств.

Следы подключения USB устройств, содержащиеся в виде различных данных в файлах/реестре, принято называть артефактами.

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

Не так давно в нашу жизнь вошел интерфейс USB, привнеся в неё довольно существенные изменения. Неожиданно многие вещи стали проще, отпала необходимость инсталляции устройства во внутренний интерфейсный разъем (шина), или внешний интерфейс, требующий перезагрузки станции для корректной инициализации устройства, да и сам процесс конфигурирования устройств стал, во множестве случаев, тривиальнее. На интерфейсе USB появились тысячи разнообразных по назначению устройств, которые достаточно было подключить к разъему на панели корпуса, после чего от момента подключения до состояния «готов к работе», порой проходили считанные минуты. Наряду с очевидными достоинствами: легкостью конфигурирования/использования, компактностью, функциональностью, подобные устройства сразу стали источником проблем как для безопасности персональных данных самого пользователя, так и безопасности корпоративных сред. Компактный, легко маскируемый «брелок» с интерфейсом USB может запросто явиться той ахиллесовой пятой, которая станет причиной «падения» гиганта корпоративной безопасности. Если порты USB в корпоративных рабочих станциях находятся без надлежащего контроля со стороны политик безопасности, то любое приспособление может запросто выступить в качестве средства для обхода периметра безопасности компании. И тут уж насколько хватит фантазии «взломщика», например, достаточно пронести на флешке свежий, не определяемый антивирусами вредоносный код и выполнить его (умышленно или нет), и вот вам уже прецедент, поскольку даже без локальных административных привилегий учетной записи пользователя сохраняется пространство для маневра. Не меньшую опасность представляют и USB-модемы, которые, в случае установки (а при использовании локальных/доменных политик по умолчанию это достигается достаточно просто), могут выступить в роли неконтролируемого канала передачи данных, по которому может осуществляться передача чувствительной корпоративной информации за пределы защищенного внутреннего периметра. При этом, даже декларируемые (заявленные/согласованные) пользовательские устройства (например, телефоны) могут содержать в своих микропрограммах или операционных системах уязвимости, которые, в случае эксплуатации, наносят вред не только владельцу, но и могут выступать в роли средства несанкционированного доступа к служебным данным. Поэтому, в случае возникновения инцидента информационной безопасности, связанного с эксплуатацией USB-устройств,

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

В связи со всем перечисленным, достаточно важно не только уметь ограничивать использование устройств, но и иметь доступ к истории USB подключений в системе. Этому вопросу и будет посвящена данная статья. Сразу оговорюсь, что весь список точек создания информации о подключении тех или иных устройство чрезвычайно обширен, поэтому по теме данной статьи мы будем рассматривать лишь историю использования USB устройств.

Перечисление (энумерация) USB устройств

Поскольку я сам в данном вопросе «плаваю», перед тем как перейти к практике, предлагаю немного усилить нашу теоретическую базу и описать терминологию, которая будет использоваться на протяжении всего материала. Сразу оговорюсь, что мы не будем освещать все виды взаимодействия, выполняющиеся на шине USB на аппаратном уровне, а сосредоточимся исключительно на основных понятиях, относящихся к USB-устройствам и требующихся нам для понимания практической стороны вопроса.
Подключение любого нового оборудования сопряжено с выполнением модулями ядра системы Windows предопределенных фаз опроса и инициализации. Начинается всё с того, что при подключении устройства к разъему USB, контроллером USB (встроенным в чипсет на материнской плате) генерируется аппаратное прерывание. Драйвер USB, ответственный за обработку данного прерывания, запрашивает статус порта, и если статус указывает на подключенное устройство, то ответственными подсистемами ядра производится последовательность действий, которую условно можно разделить на две стадии:

  1. Нумерование устройства;
  2. Установка драйвера устройства;

Ядро (?) инициирует к вновь подключенному устройству серию запросов GET_DESCRIPTOR с различными типами запрашиваемых дескрипторов ( Device , Configuration , LangID , iProduct ). Запросы опрашивают устройство на предмет наличия серии дескрипторов, представляющих собой структуры данных, описывающие возможности USB устройства.

Дескрипторы USB — структуры данных, которые позволяют операционной системе получить информацию об устройстве. Каждый дескриптор содержит информацию о устройстве в целом или отдельном элементе в рамках устройства.

Отсюда следует вывод, что любое USB-устройство должно уметь реагировать на запросы от хоста и иные события на шине. В ответ на подобного рода запросы, микрокод устройства возвращает из ПЗУ требуемую информацию. Данные, возвращаемые устройством в ответ на запросы разнообразных дескрипторов, являются важными для операционной системы, поскольку именно часть этих данных представляет собой различного рода идентификаторы, используемые системой в дальнейшем в процессе нумерования устройства. Давайте приведем наиболее значимую информацию:

Название поля Терминология Windows Размер (байт) Комментарий
idVendor VID 2 Идентификатор производителя устройства. При присвоении идентификатора производителя, соответствующее числовое значение вносится в реестр производителей.
idProduct PID 2 Идентификатор продукта. Назначается производителем устройства. Product ID используется для дифференциации продуктов в рамках одного производителя.
bcdDevice REV 2 Идентификатор ревизии. Используется для дифференциации разных аппаратных модификаций в рамках одной модели устройства. Может использоваться при выпуске новой версии платы/контроллера/логики.
bDeviceClass, bFunctionClass, bInterfaceClass Class 1 Класс устройства. Используется для задания класса схожих устройств с общим набором идентичных свойств.
bDeviceSubclass, bFunctionSubClass, bInterfaceSubclass SubClass (SUB) 1 Подкласс устройства. Используется для задания подкласса схожих устройств в рамках класса.
bDeviceProtocol, bFunctionProtocol, bInterfaceProtocol Protocol (Prot, PROTO) 1 Протокол устройства. Используется для задания протокола для устройств в рамках класса и подкласса.
iProduct Product ? Текстовая строка-описатель продукта. Когда устройство подключено к компьютеру, данная информация отображается в Диспетчере устройств.
iSerialNumber Serial ? Серийный номер. Используется для уникализации абсолютно одинаковых устройств, например две одинаковых флешки. Назначается и поддерживается производителем устройства. Связанный механизм носит имя Сериализация. Сериализация так же участвует в уникальной идентификации устройства, поскольку добавляет еще один уровень уникальности.

Наверняка многие из перечисленных в таблице полей Вам уже встречались в составе значений различных параметров в том же Диспетчере устройств либо в разнообразных системных лог-файлах.
Помимо стандартных дескрипторов, существуют еще так называемые Дескрипторы Microsoft (Microsoft OS Descriptors, MOD), которые содержат специфичную для ОС Windows информацию. Для поддержки производителей, чьи устройства из-за функциональных особенностей не подходят под стандартный набор классов, Майкрософт разработала набор специальных классов и собственных дескрипторов. Пользовательское и системное ПО может идентифицировать устройства, принадлежащие к разработанным Майкрософт классам устройств путем опроса устройства на предмет наличия дескрипторов Microsoft. Помимо поддержки описанных классов устройств, дескрипторы Microsoft имеют и иное применение, например при помощи них можно использовать память устройства для хранения файлов помощи, иконок, списков адресов URL, настроек системного реестра и других данных, используемых для обеспечения прозрачности установки и достижения смежных целей. Устройства, поддерживающие дескрипторы Microsoft, должны хранить специальный строковый дескриптор в прошивке с фиксированным индексом 0xEE . Операционные системы Windows XP SP1 и более поздние запрашивают этот строковый дескриптор у устройства при первом его подключении.

Таким образом, каждое USB устройство должно иметь, как минимум: идентификатор производителя ( VID , Vendor ID), идентификатор продукта ( PID , Product ID), и серийный номер ( Serial ). На основе этих параметров формируется уникальный идентификатор оборудования, тем самым обеспечивается уникализация USB-устройства в пределах системы и вносятся изменения в конфигурацию оборудования.

Более того, использование пары VID / PID в дескрипторе любого USB-устройства предписывается спецификацией, согласно которой данные параметры должны быть уникальны для каждой модели устройства. Ну это, опять же, все в теории, а на практике пару раз встречались экземпляры устройств, при работе с которыми становилось очевидно, что значения VID/PID взяты произвольно, либо взяты свободные значения (!) из реестра производителей. Понятно кому выгодно подобным заниматься 🙂 Ну это скорее редко встречающаяся ситуация, когда производителю хочется сэкономить на внесении в реестр производителей.
Затем, после того, как у устройства запрошены ключевые параметры, для USB устройства создан уникальный идентификатор HardwareID ( CompatibleID ), однозначно идентифицирующий устройство/класс устройства. Драйвер USB-концентратора уведомляет специализированный модуль ядра под названием Диспетчер Plug-n-Play (PnP Manager) о новом устройстве. Диспетчер PnP получает идентификаторы HardwareID и CompatibleID устройства и пытается обнаружить устройства с аналогичными идентификаторами HardwareID/CompatibleID. В этот момент в системе создается узел устройства (devnode), что является, по сути, первым отпечатком USB устройства в системе. Если похожее устройство найдено, то производится установка соответствующих драйверов в автоматическом режиме, если же не найдено, то Диспетчер PnP получается уведомление о новом устройстве и далее действует по определенным правилам, описание которых выходит за рамки данного материала.

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

Эксперимент

В Сети много противоречивой информации относительно истории подключения USB, поэтому давайте проведем собственный эксперимент по выявлению всех возможных системных местоположений, формирующих историю USB подключений. С целью выявления следов подключения USB стоит отследить абсолютно все изменения, происходящие в системе в момент подключения USB устройства. С этой целью на просторах Сети была найдена замечательная утилита под названием SysTracer, которая обладает всем необходимым функционалом. Утилита настолько проста и функциональна, что во многих случаях она окажется незаменимым средством в руках специалиста, поскольку предоставляет возможность сделать КРАЙНЕ полезное действие: создать мгновенный снимок (snapshot) состояния ключевых компонентов системы, таких как реестр и файлы. В качестве системы я использовал чистую инсталляцию Windows 7 Professional, при этом главным требованием было отсутствие каких-либо подключений внешних носителей. Итак, делаем снимок чистой системы, затем вставляем тестовую USB-флешку SanDisk Cruzer mini 1.0Gb и через некоторое время делаем второй снимок. Встроенными средствами утилиты SysTracer сравниваем полученные образы с выводом отчета. В итоге у нас получился некий набор системных изменений, среди которых мы попытаемся выбрать именно те, которые могут относиться к следам подключения USB устройств. Выбранный мною метод имеет и свои недостатки, поскольку наблюдения за активностью системы применительно к USB устройствам не проводилось «в динамике», то есть мы не работали с открытыми с подключаемого носителя файлами (.docx/.xlsx) в различных пользовательских приложениях, а это могло привести к тому, что мы можем упустить факты попадания частей информации с USB-носителя в файлы подкачки, различные временные файлы кеша и файлы иного назначения. Поэтому материал, скорее всего, потребует последующей доработки.

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

История в файлах

После изучения изменений файловой части системных изменений, подтвердился факт того, что в операционной системе Windows 7 все действия над устройствами отражаются в следующих журнальных файлах:

  • %Windir%\setupact.log — содержит сообщения отладки от инсталятора драйверов [режима ядра], сопровождающего процесс установки устройства;
  • %Windir%\inf\setupapi.app.log — содержит сообщения процесса инсталляции приложений;
  • %Windir%\inf\setupapi.dev.log — содержит сообщения процесса инсталляции устройств;

Начнем с файла setupapi.dev.log , по информации из которого мы можем отследить всю историю подключения к компьютеру любых устройств (включая USB). Я приведу фрагмент инсталляции упомянутого мной флеш-накопителя SanDisk Cruzer mini. Сразу предупрежу, что в файле setupapi.dev.log очень много информации, поэтому для поиска в ручном режиме можно отрыть его встроенным Блокнотом и при помощи комбинации клавиш Ctrl + F выполнить поиск словосочетания Device Install или USB\VID_ . Это не самый удобный метод, тем не менее иметь его в арсенале определенно следует. Вот что удалось обнаружить:

Уникальный номер USB-диска (флешки)

У каждого устройства есть серийник, его можно посмотреть через DriveGetSerial. Но проблема в том, что если мы копируем образ, например через ULTRAISO то Serial так же копируется. А необходимо защитить скрипт, дабы он запускался только на конкретной флешке. Может есть у кого идеи?
Спасибо

_Lexa98_
Осваивающий

Сообщения 551 Репутация 25

При запуске прошраммы проверяй, соответствует ли сирийник записанный в файл/код с сирийником диска, если нет, то сразу выхожи из программы

madmasles
Модератор

Глобальный модератор
Сообщения 7,790 Репутация 2,321
_Lexa98_ [?]

При запуске прошраммы проверяй, соответствует ли сирийник записанный в файл/код с сирийником диска, если нет, то сразу выхожи из программы

OffTopic:
Интересно, Вы читаете свои сообщения перед отправкой?

Centrinar
Новичок

Сообщения 100 Репутация 1
И мой вопрос читали?

madmasles
Модератор

Глобальный модератор
Сообщения 7,790 Репутация 2,321
Centrinar [?]
И мой вопрос читали?
Серийный номер.

$objWMIService = ObjGet('winmgmts:\\.\root\cimv2') $colItems = $objWMIService.ExecQuery('Select * from Win32_PhysicalMedia') For $objItem In $colItems If $objItem.SerialNumber <> '' Then MsgBox(0, 'HDD serial number', $objItem.SerialNumber & @LF & $objItem.Tag) EndIf Next
Centrinar
Новичок

Сообщения 100 Репутация 1
Не пойму, а как прочитать номер флешки а не HDD

Yashied
Модератор

Команда форума
Глобальный модератор
Сообщения 5,379 Репутация 2,723

Серийный номер, это уникальный номер, присущий только конкретно данному устройству. Такие номера имеют, например, жесткие диски, процессоры, видеокарты (не все). Флешки — нет. Функция DriveGetSerial() возвращает серийный номер файловой системы, который никак не связан с самим устройством. Кроме того, этот номер изменится после форматирования диска или же его можно легко изменить программно.

Единственное, что можно сделать, это идентифицировать флешку по Device ID. Этот номер будет повторяться только для данной модели флешки данного производителя. Его можно посмотреть в свойствах диска, и имеет он примерно следующий вид:

VEN_&PROD_SILICON-POWER&REV_PMAP

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

VEN_&PROD_SILICON-POWER&REV_PMAPNTFS142301716697325515631245248115

Далее, чтобы никто не догадался, берете от этой строки хеш, например MD5, и выводите его в виде GUID:

Это и будет «уникальный» номер вашей флешки. Сделать рабочую копию такой флешки можно только, если скопировать ее образ на точно такую же флешку того же производителя. В принципе, для большинства задач этого будет вполне достаточно. Для еще большего усложнения задачи можете взять редко встречающиеся флешки минимального объема.

Как теперь привязать скрипт к такой флешке? Создаете в корне оной скрытый текстовый или двойчный файл, содержащий соответствующий этой флешке GUID. Далее скрипт пытается прочитать со всех съемных дисков этот файл и сравнить ID с вычесленным значением для этого диска (на котором находится файл).

#Include ConsoleWrite(_UniqueUSBFlashID('G:') & @CR) Func _UniqueUSBFlashID($sDrive) Local $oService, $oItems, $Hash, $Disk = '', $Part = '', $Text = '' $oService = ObjGet('winmgmts:\\.\root\cimv2') If Not IsObj($oService) Then Return SetError(1, 0, '') EndIf $oItems = $oService.ExecQuery('SELECT * FROM Win32_LogicalDiskToPartition') If Not IsObj($oItems) Then Return SetError(2, 0, '') EndIf For $Property In $oItems If StringInStr($Property.Dependent, '"' & $sDrive & '"') Then $Part = StringTrimLeft($Property.Antecedent, StringInStr($Property.Antecedent, '=')) ExitLoop EndIf Next If Not $Part Then Return SetError(3, 0, '') EndIf $oItems = $oService.ExecQuery('SELECT * FROM Win32_DiskDriveToDiskPartition') If Not IsObj($oItems) Then Return SetError(2, 0, '') EndIf For $Property In $oItems If StringInStr($Property.Dependent, $Part) Then $Disk = StringTrimLeft($Property.Antecedent, StringInStr($Property.Antecedent, '=')) ExitLoop EndIf Next If Not $Disk Then Return SetError(3, 0, '') EndIf $oItems = $oService.ExecQuery('SELECT * FROM Win32_DiskDrive WHERE DeviceID = ' & $Disk) If Not IsObj($oItems) Then Return SetError(2, 0, '') EndIf For $Property In $oItems If $Property.InterfaceType = 'USB' Then $Text = StringTrimLeft($Property.PnPDeviceID, StringInStr($Property.PnPDeviceID, '&VEN_')) $Text = StringStripWS(StringLeft($Text, StringInStr($Text, '\', 0, -1) - 1), 8) $Text &= DriveGetFileSystem($sDrive) & DriveGetSerial($sDrive) $Text &= $Property.TotalCylinders $Text &= $Property.TotalHeads $Text &= $Property.TotalSectors $Text &= $Property.TotalTracks ExitLoop EndIf Next If Not $Text Then Return SetError(3, 0, '') EndIf $Hash = StringTrimLeft(_Crypt_HashData($Text, $CALG_MD5), 2) If Not $Hash Then Return SetError(4, 0, '') EndIf Return '' EndFunc ;==>_UniqueUSBFlashID

Как получить информацию о подключенном устройстве?

введите сюда описание изображения

Я пишу на С++, использую Qt под Windows. Мне надо получить: название модели, изготовителя, серийный номер устройства(видео камеры, фото , квадрокоптера , флешки или SD Card) и путь до устройства. Желательно кроссплатформенное решение. Есть ответ SetupDiGetDeviceProperty. Но тут не кроссплатформенное решение , к тому же я не совсем понимаю как получить путь до устройства. Читал о библиотеки libusb. Но тут не выводятся название модели, изготовителя, серийный номер устройства. То что выводиться :

Dev (bus 2, device 0): 8086 - 1E31 Dev (bus 1, device 4): 04A9 - 1795 Dev (bus 1, device 3): A4Tech - USB Mouse Dev (bus 3, device 0): 8086 - 1E26 Dev (bus 1, device 1): 8087 - 0024 Dev (bus 1, device 0): 8086 - 1E2D Dev (bus 1, device 2): 0BDA - 0151 Dev (bus 1, device 6): Logitech Inc. - Logitech USB Headset H340 Dev (bus 3, device 2): 8087 - 0024 Dev (bus 3, device 3): Logitech - USB Keyboard Dev (bus 3, device 1): 04A9 - 3206 

Хотя была вставлена флешка и подключена камера. Есть изящное решение этой задачи. Если кто сталкивался с такой задачей поделитесь кодом пожалуйста.

Отслеживать
Ivan Triumphov
задан 29 мая 2018 в 16:40
Ivan Triumphov Ivan Triumphov
1,108 1 1 золотой знак 14 14 серебряных знаков 38 38 бронзовых знаков

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

К сожалению, используя библиотеку libusb под Windows нельзя вытянуть всю эту информацию без установки специального драйвера WinUSB. Можно только получить VID и PID (шестнадцатеричные значения типа 8086 — 1E31 в вашем примере), и по ним найти производителя и устройство в таблице известных идентификаторов, например здесь.

Производителя и серийный номер можно получить, используя Setup API и IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION. Букву диска тоже можно получить только средствами Setup API, это несколько сложнее. Для этого нужно вначале построить таблицу номеров дисков для всех используемых букв дисков с помощью IOCTL_STORAGE_GET_DEVICE_NUMBER; затем открыть интересующее устройство (запоминающее устройство, которое является дочерним для USB-устройства), найти его номер тем же IOCTL, сравнить его со значениями из таблицы и таким образом определить букву. Как-то так:

#include #include #include #include #include #include #include #undef LowSpeed #include #include #pragma comment(lib,"Setupapi.lib") void ErrorMes(LPCTSTR lpszFunction) < // Retrieve the system error message for the last-error code LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); // Display the error message lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen(lpszFunction) + 40) * sizeof(TCHAR)); wprintf(L"%s failed with error %d: %s", lpszFunction, dw, lpMsgBuf); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); >//Поиск номера диска для USB-устройства BOOL FindDiskNumber(LPCWSTR match, STORAGE_DEVICE_NUMBER* lpret)< BOOL retval = FALSE; DEVPROPTYPE dpt=0; wchar_t buffer[1024]=L""; TCHAR id_upper[1024]=L""; DWORD RequiredSize = 0; SP_DEVINFO_DATA devinfo = < 0 >; SP_DEVICE_INTERFACE_DATA deviceInterface = < 0 >; PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetail = NULL; BOOL res; HDEVINFO deviceInfoHandle = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DISK, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (deviceInfoHandle != INVALID_HANDLE_VALUE) < int deviceIndex = 0; while (true) < ZeroMemory(&deviceInterface,sizeof(deviceInterface)); deviceInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); //получение всех дисков if (SetupDiEnumDeviceInterfaces(deviceInfoHandle, 0, &GUID_DEVINTERFACE_DISK, deviceIndex, &deviceInterface)) < DWORD cbRequired = 0; SetupDiGetDeviceInterfaceDetail(deviceInfoHandle, &deviceInterface, 0, 0, &cbRequired, 0); if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) < 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)) < goto Next; >// 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 //получение информации о устройстве ZeroMemory(&devinfo,sizeof(devinfo)); devinfo.cbSize = sizeof(SP_DEVINFO_DATA); BOOL success = SetupDiEnumDeviceInfo(deviceInfoHandle, deviceIndex, &devinfo); if(success==FALSE) res=SetupDiGetDeviceProperty(deviceInfoHandle,&devinfo, &DEVPKEY_Device_Parent,&dpt,(PBYTE)buffer,1000,NULL,0); if(res==FALSE) int len = wcslen(buffer); for(int i=0;i if(wcsstr(id_upper,match)!=NULL)< //если ID родительского устройства содержит нужную строку /*Открываем устройство для отправки IOCTL*/ HANDLE handle = CreateFile(deviceInterfaceDetail->DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); if(handle==INVALID_HANDLE_VALUE) < ErrorMes(L"CreateFile");goto Next; >STORAGE_DEVICE_NUMBER sdn = ; DWORD nbytes = 0; //получение номера диска res = DeviceIoControl(handle, // handle to device IOCTL_STORAGE_GET_DEVICE_NUMBER, // dwIoControlCode NULL, // lpInBuffer 0, // nInBufferSize (LPVOID) &sdn, // output buffer (DWORD) sizeof(sdn), // size of output buffer (LPDWORD) &nbytes, // number of bytes returned NULL // OVERLAPPED structure ); CloseHandle(handle); if(res != FALSE) < //устройство найдено memcpy(lpret,&sdn,sizeof(sdn)); retval = TRUE; >else ErrorMes(L"DeviceIoControl"); > > > else < break; >Next: if(deviceInterfaceDetail != NULL) < delete[] deviceInterfaceDetail; deviceInterfaceDetail = NULL; >if(retval != FALSE) break; //устройство уже найдено deviceIndex++; //следующее устройство > SetupDiDestroyDeviceInfoList(deviceInfoHandle); > else ErrorMes(L"SetupDiGetClassDevs"); return retval; > //таблица номеров для всех дисков bool disk_IsUsed[30]=; STORAGE_DEVICE_NUMBER disk_number[30]=; int _tmain(int argc, _TCHAR* argv[]) < setlocale(LC_ALL,"Russian"); HANDLE hVol; DWORD nbytes; WCHAR letter; WCHAR volume[100]=; int i; STORAGE_DEVICE_NUMBER sdn=; //заполняем таблицу номеров для дисков for(i=0;i <30;i++)< letter = 'A' + i; wsprintf(volume,L"\\\\.\\%c:",letter); disk_IsUsed[i] = FALSE; hVol = CreateFile( volume, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if(hVol == NULL || hVol == INVALID_HANDLE_VALUE)BOOL ret = DeviceIoControl(hVol, // handle to device IOCTL_STORAGE_GET_DEVICE_NUMBER, // dwIoControlCode NULL, // lpInBuffer 0, // nInBufferSize (LPVOID) &(disk_number[i]), // output buffer (DWORD) sizeof(STORAGE_DEVICE_NUMBER), // size of output buffer (LPDWORD) &nbytes, // number of bytes returned NULL // OVERLAPPED structure ); CloseHandle(hVol); if(ret == FALSE) disk_IsUsed[i] = TRUE; > WCHAR match[1024]=; 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=; const UINT BUFSIZE = 1000; char buffer[BUFSIZE]=; 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)if(coninfo.ConnectionStatus==0) continue; //нет устройства printf("\n- Hub %2d, Port %2d: USB v%x device\n",deviceIndex, j,(int)coninfo.DeviceDescriptor.bcdUSB); printf("VID: %04X PID: %04X\n",(int)coninfo.DeviceDescriptor.idVendor ,(int)coninfo.DeviceDescriptor.idProduct); //формируем строку для поиска устройства wsprintf(match,L"VID_%04X&PID_%04X",(UINT)coninfo.DeviceDescriptor.idVendor ,(UINT)coninfo.DeviceDescriptor.idProduct); /*Serial number*/ ZeroMemory(buffer,BUFSIZE); req->ConnectionIndex=j; req->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE SetupPacket.wLength = BUFSIZE - sizeof(USB_DESCRIPTOR_REQUEST); req->SetupPacket.wIndex = 0x409; //US English res=DeviceIoControl(handle,IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION , &buffer,sizeof(buffer),&buffer,sizeof(buffer),&bytes_read,0); if(res==FALSE) desc = (USB_STRING_DESCRIPTOR*)(&req->Data[0]); wprintf(L"Serial: %s\n",desc->bString); /*Vendor*/ ZeroMemory(buffer,BUFSIZE); req->ConnectionIndex=j; req->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE SetupPacket.wLength = BUFSIZE - sizeof(USB_DESCRIPTOR_REQUEST); req->SetupPacket.wIndex = 0x409; //US English res=DeviceIoControl(handle,IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION , &buffer,sizeof(buffer),&buffer,sizeof(buffer),&bytes_read,0); if(res==FALSE) desc = (USB_STRING_DESCRIPTOR*)(&req->Data[0]); wprintf(L"Vendor: %s\n",desc->bString); /*Product*/ ZeroMemory(buffer,BUFSIZE); req->ConnectionIndex=j; req->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE SetupPacket.wLength = BUFSIZE - sizeof(USB_DESCRIPTOR_REQUEST); req->SetupPacket.wIndex = 0x409; //US English res=DeviceIoControl(handle,IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION , &buffer,sizeof(buffer),&buffer,sizeof(buffer),&bytes_read,0); if(res==FALSE) desc = (USB_STRING_DESCRIPTOR*)(&req->Data[0]); wprintf(L"Product: %s\n",desc->bString); /*Disk letter*/ res = FindDiskNumber(match,&sdn); if(res != FALSE) < for(i=0;i<30;i++) if( disk_IsUsed[i] !=FALSE && disk_number[i].DeviceNumber == sdn.DeviceNumber && disk_number[i].DeviceType == sdn.DeviceType) < letter = 'A' + i; printf("Disk letter: %c\n",letter); >> else printf("Disk letter not found\n"); > CloseHandle(handle); >else< ErrorMes(L"CreateFile");//failed to open device >//endif delete[] deviceInterfaceDetail; > > else < break; >++deviceIndex; > SetupDiDestroyDeviceInfoList(deviceInfoHandle); > else ErrorMes(L"SetupDiGetClassDevs"); system("PAUSE"); return 0; > 

Должно вывести подобный результат:

‐ Hub 3, Port 1: USB v200 device
VID: 8564 PID: 1000
Serial: 5B94314A
Vendor: JetFlash
Product: Mass Storage Device
Disk letter: G

‐ Hub 3, Port 4: USB v110 device
VID: 09DA PID: 000A
Serial: ?
Vendor: A4Tech
Product: USB Mouse
Disk letter not found

‐ Hub 3, Port 6: USB v110 device
VID: 046E PID: 5505
Serial: ?
Vendor: BTC
Product: USB Multimedia Keyboard
Disk letter not found

‐ Hub 3, Port 10: USB v200 device
VID: 04E8 PID: 689E
Serial: 1234567890ABCDEF
Vendor: SAMSUNG Electronics Co., Ltd.
Product: Samsung Android USB Device
Disk letter: H

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *