За что отвечает программа usbdeview
Изменить язык
Полная версия
© Valve Corporation. Все права защищены. Все торговые марки являются собственностью соответствующих владельцев в США и других странах. Политика конфиденциальности | Правовая информация | Соглашение подписчика Steam | Refunds

Установить Steam
© 2023 Valve Corporation. Все права защищены. Все торговые марки являются собственностью соответствующих владельцев в США и других странах.
USBDeview Информация о подключенных USB-устройствах




USBDeview это бесплатная программа, которая показывает подробную информацию о всех устройствах, когда-либо подключавшихся и в настоящий момент подключенных к компьютеру через USB разъем (флешки, внешние жесткие диски, карты памяти, мышки, клавиатуры, фотоаппараты, видеокамеры, смартфоны, принтеры, сканеры и прочие). Приложение USBDeview расскажет о типе и производителе устройства, когда USB устройство было подключено в первый и в последний раз к системе, покажет серийный номер устройства, какая служба задействована устройством, файл и версию драйвера, код экземпляра устройства, какова потребляемая мощность устройства, раскроет возможности подключенного устройства к USB разъему.
Подробно о USB-устройствах на компьютере
Помимо подробной информации о USB устройствах, используемых на компьютере, USBDeview умеет запрещать и разрешать работу устройств, отключать и изменять букву устройства, может открыть параметры устройства в редакторе системного реестра, назначить автозапуск устройства, скопировать его свойства в буфер обмена и вывести информацию о нем в виде HTML отчёта. Также USBDeview может назначить выполнение команд при подключении и отключении USB-устройства к порту компьютера.
В архиве для загрузки Вы найдете 32-х и 64-х битную версию программы, а также архив с русификатором. USBDeview не требует установки (portable), для русификации просто скопируйте файл русской локализации в каталог с утилитой.
Скриншоты программы USBDeview
Официальный сайт: http://www.nirsoft.net
Операционные системы: Windows All
Поддерживаемые языки: русский
Версия: 2.42
Лицензия: freeware (бесплатная)
Размер файла 190 Кб
USBDeview
Скачать
прямая ссылка
Предыдущие программы:
- Snappy Driver Installer Поиск, установка и обновление драйверов Windows
- DriverPack Online Поиск и обновление драйверов Windows
- DevID Agent Установка драйверов
Следующие программы:
- Partition Assistant Управление дисками
- Drive The Life Для поиска и установки драйверов
- MiniBin Корзина с удалёнными файлами в трее
Пишем простой драйвер под Windows для блокировки USB-устройств
Вряд ли пользователь домашнего ПК заинтересуется тем, чтобы блокировать устройства на своём ПК. Но если дело касается корпоративной среды, то всё становится иначе. Есть пользователи, которым можно доверять абсолютно во всём, есть такие, которым можно что-то делегировать, и есть те, кому доверять совсем нельзя. Например, вы заблокировали доступ к Интернету одному из пользователей, но не заблокировали устройства этого ПК. В таком случае пользователю достаточно просто принести USB-модем, и Интернет у него будет. Т.е. простым блокированием доступа к Интернету дело не ограничивается.
Однажды примерно такая задача и стояла передо мной. Времени на поиск каких-либо решений в Интернете не было, да и они, как правило, небесплатные. Поэтому мне было проще написать такой драйвер, и его реализация отняла у меня один день.
В этой статье я расскажу немного теоретическую часть, на основе которой все строится, и расскажу принцип самого решения.
Также полные исходные коды могут быть найдены в папке USBLock хранилища git по адресу: https://github.com/anatolymik/samples.git.
Структура DRIVER_OBJECT
Для каждого загруженного драйвера система формирует структуру DRIVER_OBJECT. Этой структурой система активно пользуется, когда отслеживает состояние драйвера. Также драйвер отвечает за её инициализацию, в частности за инициализацию массива MajorFunction. Этот массив содержит адреса обработчиков для всех запросов, за которые драйвер может отвечать. Следовательно, когда система будет посылать запрос драйверу, она воспользуется этим массивом, чтобы определить, какая функция драйвера отвечает за конкретный запрос. Ниже представлен пример инициализации этой структуры.
for ( ULONG i = 0; i MajorFunction[i] = DispatchCommon;
>
DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DispatchCleanup;
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = DispatchAddDevice;
Такая инициализация обычно выполняется при вызове системой точки входа драйвера, прототип которой изображён ниже.
NTSTATUS DriverEntry( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath );
Как видно из примера, сначала весь массив MajorFunction инициализируется одним и тем же обработчиком. В реальности типов запросов больше, чем в примере. Поэтому предварительно весь массив инициализируется так, чтобы запросы, которые не поддерживаются драйвером, обрабатывались корректно. Например, завершались с ошибкой. После инициализации массива обычно инициализируются обработчики для тех запросов, за которые драйвер отвечает.
Также инициализируется поле DriverUnload структуры, которое содержит адрес обработчика, отвечающего за завершение работы драйвера. Это поле может быть оставлено непроинициализированным, в таком случае драйвер становится невыгружаемым.
Обратите внимание на то, что в поле DriverExtension->AddDevice устанавливается адрес обработчика, который вызывается всякий раз, когда система обнаруживает новое устройство, за работу которого драйвер отвечает. Данное поле может быть оставлено непроинициализированным, в таком случае драйвер не сможет обрабатывать это событие.
Структура DEVICE_OBJECT
Структура DEVICE_OBJECT представляет ту или иную функциональность драйвера. Т.е. эта структура может представлять физическое устройство, логическое устройство, виртуальное устройство или просто некий функционал, предоставляемый драйвером. Поэтому когда система будет посылать запросы, то в самом запросе она будет указывать адрес этой структуры. Таким образом, драйвер сможет определить, какой функционал от него запрашивается. Если не использовать такую модель, тогда драйвер может обрабатывать только какую-нибудь одну функциональность, а в современном мире это недопустимо. Прототип функции, которая обрабатывает конкретный запрос, приведена ниже.
NTSTATUS Dispatch( PDEVICE_OBJECT DeviceObject, PIRP Irp );
Массив MajorFunction ранее упомянутой структуры DRIVER_OBJECT содержит адреса обработчиков именно с таким прототипом.
Сама структура DEVICE_OBJECT всегда создаётся драйвером при помощи функции IoCreateDevice. Если система посылает запрос драйверу, то она всегда направляет его какому-либо DEVICE_OBJECT, как это следует из вышепредставленного прототипа. Также, прототип принимает второй параметр, который содержит адрес IRP-структуры. Эта структура описывает сам запрос, и она существует в памяти до тех пор, пока драйвер не завершит его. Запрос отправляется драйверу на обработку при помощи функции IoCallDriver как системой, так и другими драйверами.
Также со структурой DEVICE_OBJECT может быть связано имя. Таким образом, этот DEVICE_OBJECT может быть найден в системе.
Фильтрация
Фильтрация являет собой механизм, который позволяет перехватывать все запросы, направленные к конкретному DEVICE_OBJECT. Чтобы установить такой фильтр, необходимо создать другой экземпляр DEVICE_OBJECT и прикрепить его к DEVICE_OBJECT, запросы которого необходимо перехватывать. Прикрепление фильтра выполняется посредством функции IoAttachDeviceToDeviceStack. Все DEVICE_OBJECT, прикреплённые к перехватываемому DEVICE_OBJECT, вместе с ним формируют так называемый стек устройства, как это изображено ниже.

Стрелкой изображено продвижение запроса. Сначала запрос будет обрабатываться драйвером верхнего DEVICE_OBJECT, затем драйвером среднего и, в конце концов, управление на обработку запроса получит драйвер целевого DEVICE_OBJECT. Также нижний DEVICE_OBJECT называется дном стека, т.к. он ни к кому не прикреплён.
Наличие такого механизма позволяет добавлять функционал, которого нет изначально в драйверах. Например, таким образом, без доработки файловой системы FAT, поставляемой в Windows, можно добавить проверку прав доступа к файлам этой файловой системы.
PnP менеджер
PnP менеджер отвечает за диспетчеризацию устройств всей системы. В его задачи входит обнаружение устройств, сбор информации о них, загрузка их драйверов, вызов этих драйверов, управление аппаратными ресурсами, запуск и остановка устройств и их удаление.
Когда драйвер той или иной шины обнаруживает устройства на своих интерфейсах, то для каждого дочернего устройства он создаёт DEVICE_OBJECT. Этот DEVICE_OBJECT также называют Physical Device Object или PDO. Затем посредством функции IoInvalidateDeviceRelations он уведомляет PnP менеджер о том, что произошли изменения на шине. В ответ на это PnP менеджер посылает запрос с minor кодом IRP_MN_QUERY_DEVICE_RELATIONS с целью запросить список дочерних устройств. В ответ на этот запрос драйвер шины возвращает список PDO. Ниже изображён пример такой ситуации.

Как отражено на рисунке, в данном примере в качестве шины выступает драйвер USB-хаба. Конкретные DEVICE_OBJECT стека устройства этого хаба не изображены для краткости и с целью сохранения последовательности пояснений.
Как только PnP менеджер получит список всех PDO, он по отдельности соберёт всю необходимую информацию об этих устройствах. Например, будет послан запрос с minor кодом IRP_MN_QUERY_ID. Посредством этого запроса PnP менеджер получит идентификаторы устройства, как аппаратные, так и совместимые. Также PnP менеджер соберёт всю необходимую информацию о требуемых аппаратных ресурсах самим устройством. И так далее.
После того, как вся необходимая информация будет собрана, PnP менеджер создаст так называемую DevNode, которая будет отражать состояние устройства. Также PnP создаст ветку реестра для конкретного экземпляра устройства или откроет существующую, если устройство ранее подключалось к ПК.
Следующая задача PnP — это запуск драйвера устройства. Если драйвер не был ранее установлен, тогда PnP будет ожидать установки. Иначе, при необходимости, PnP загрузит его и передаст ему управление. Ранее упоминалось, что поле DriverExtension->AddDevice структуры DRIVER_OBJECT содержит адрес обработчика, который вызывается всякий раз, когда система обнаруживает новое устройство. Прототип этого обработчика изображён ниже.
NTSTATUS DispatchAddDevice(
PDRIVER_OBJECT DriverObject,
PDEVICE_OBJECT PhysicalDeviceObject
);
Т.е. всякий раз, когда PnP обнаруживает устройство, управлением которого занимается тот или иной драйвер, вызывается зарегистрированный обработчик этого драйвера, где ему передаётся указатель на PDO. Информация об установленном драйвере также хранится в соответствующей ветке реестра.
В задачу обработчика входит создание DEVICE_OBJECT и его прикрепление к PDO. Прикреплённый DEVICE_OBJECT также называют Functional Device Object или FDO. Именно этот FDO и будет отвечать за работу устройства и представление его интерфейсов в системе. Ниже представлен пример, когда PnP завершил вызов драйвера, отвечающего за работу устройства.

Как отражено на примере, кроме драйвера самого устройства также могут быть зарегистрированы нижние и верхние фильтры класса устройства. Следовательно, если таковые имеются, PnP также загрузит их драйвера и вызовет их AddDevice обработчики. Т.е. порядок вызова драйверов следующий: сначала загружаются и вызываются зарегистрированные нижние фильтры, затем загружается и вызывается драйвер самого устройства, и в завершении загружаются и вызываются верхние фильтры. Нижние и верхние фильтры являются обычным DEVICE_OBJECT, которые создают драйвера и прикрепляют их к PDO в своих обработчиках AddDevice. Количество нижних и верхних фильтров не ограничено.
В этот момент стеки устройств полностью сформированы и готовы к работе. Поэтому PnP посылает запрос с minor кодом IRP_MN_START_DEVICE. В ответ на этот запрос все драйвера стека устройства должны подготовить устройство к работе. И если в этом процессе не возникло проблем, тогда запрос завершается успешно. В противном случае, если любой из драйверов не может запустить устройство, тогда он завершает запрос с ошибкой. Следовательно, устройство не будет запущено.
Также, когда драйвер шины определяет, что произошли изменения на шине, он посредством функции IoInvalidateDeviceRelations уведомляет PnP о том, что следует заново собрать информацию о подключенных устройствах. В этот момент драйвер не удаляет ранее созданный PDO. Просто при получении запроса с minor кодом IRP_MN_QUERY_DEVICE_RELATIONS он не включит этот PDO в список. Затем PnP на основании полученного списка опознает новые устройства и устройства, которые были отключены от шины. PDO отключенных устройств драйвер удалит тогда, когда PnP пошлёт запрос с minor кодом IRP_MN_REMOVE_DEVICE. Для драйвера этот запрос означает, что устройство более никем не используется, и оно может быть безопасно удалено.
Суть решения
Суть самого решения заключается в создании верхнего фильтра класса USB-шины. Зарезервированные классы можно найти по адресу: https://msdn.microsoft.com/en-us/library/windows/hardware/ff553419(v=vs.85).aspx. Нас интересует класс USB с GUID равным 36fc9e60-c465-11cf-8056-444553540000. Как гласит MSDN, этот класс используется для USB хост контроллеров и хабов. Однако практически это не так, этот же класс используется, например, flash-накопителями. Это немного добавляет нам работы. Код обработчика AddDevice представлен ниже.
NTSTATUS UsbCreateAndAttachFilter(
PDEVICE_OBJECT PhysicalDeviceObject,
bool UpperFilter
) SUSBDevice* USBDevice;
PDEVICE_OBJECT USBDeviceObject = nullptr;
NTSTATUS Status = STATUS_SUCCESS;
// если нижний фильтр уже прикреплен, тогда здесь больше делать нечего
if ( !UpperFilter ) USBDeviceObject = PhysicalDeviceObject;
while ( USBDeviceObject->AttachedDevice ) if ( USBDeviceObject->DriverObject == g_DriverObject ) return STATUS_SUCCESS;
>
USBDeviceObject = USBDeviceObject->AttachedDevice;
>
>
// создаем фильтр
Status = IoCreateDevice(
g_DriverObject,
sizeof( SUSBDevice ),
nullptr,
PhysicalDeviceObject->DeviceType,
PhysicalDeviceObject->Characteristics,
false,
&USBDeviceObject
);
if ( !NT_SUCCESS( Status ) ) < break;
>
// инициализируем флаги созданного устройства, копируем их из объекта к
// которому прикрепились
Flags = PhysicalDeviceObject->Flags &
(DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE);
USBDeviceObject->Flags |= Flags;
// получаем указатель на нашу структуру
USBDevice = (SUSBDevice*)USBDeviceObject->DeviceExtension;
// инициализируем деструктор
USBDevice->DeleteDevice = DetachAndDeleteDevice;
// инициализируем обработчики
for ( ULONG i = 0; i MajorFunction[i] = UsbDispatchCommon;
>
USBDevice->MajorFunction[IRP_MJ_PNP] = UsbDispatchPnp;
USBDevice->MajorFunction[IRP_MJ_POWER] = UsbDispatchPower;
// заполняем структуру
USBDevice->SelfDevice = USBDeviceObject;
USBDevice->BaseDevice = PhysicalDeviceObject;
USBDevice->UpperFilter = UpperFilter;
// инициализируем paging семафор
USBDevice->PagingCount = 0;
KeInitializeEvent( &USBDevice->PagingLock, SynchronizationEvent, true );
// прикрепляем устройство к PDO
USBDevice->LowerDevice = IoAttachDeviceToDeviceStack(
USBDeviceObject,
PhysicalDeviceObject
);
if ( !USBDevice->LowerDevice ) Status = STATUS_NO_SUCH_DEVICE;
break;
>
>
// в зависимости от результата делаем
if ( !NT_SUCCESS( Status ) )
if ( USBDeviceObject ) IoDeleteDevice( USBDeviceObject );
>
// или сбрасываем флаг инициализации
USBDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
static NTSTATUS DispatchAddDevice(
PDRIVER_OBJECT DriverObject,
PDEVICE_OBJECT PhysicalDeviceObject
)
return UsbCreateAndAttachFilter( PhysicalDeviceObject, true );
Как следует из примера, мы создаём DEVICE_OBJECT и прикрепляем его к PDO. Таким образом, мы будем перехватывать все запросы, направленные к USB-шине. В нашу задачу входит перехватывать запросы с minor кодом IRP_MN_START_DEVICE. Код обработчика этого запроса изображён ниже.
static NTSTATUS UsbDispatchPnpStartDevice( SUSBDevice* USBDevice, PIRP Irp )
bool HubOrComposite;
NTSTATUS Status;
// проверить, позволено ли устройству работать, также обновить
// информацию об устройстве, является ли оно хабом или композитным
Status = UsbIsDeviceAllowedToWork( &HubOrComposite, USBDevice );
if ( !NT_SUCCESS( Status ) ) break;
>
USBDevice->HubOrComposite = HubOrComposite;
// продвинуть запрос
Status = ForwardIrpSynchronously( USBDevice->LowerDevice, Irp );
if ( !NT_SUCCESS( Status ) ) break;
>
// завершаем запрос
Irp->IoStatus.Status = Status;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
// и освобождаем устройство
IoReleaseRemoveLock( &USBDevice->Lock, Irp );
Как изображено на рисунке, обработчик вызывает функцию UsbIsDeviceAllowedToWork. Эта функция выполняет все необходимые проверки, чтобы определить, разрешено ли устройству работать. В первую очередь функция позволяет всегда работать хабам и композитным устройствам, клавиатурам и мышам. А также тем устройствам, которые находятся в списке разрешённых. Если функция возвращает неуспешный код возврата, тогда запрос завершается с ошибкой. Таким образом, работа устройства будет заблокирована.
Обратите внимание: функция определяет, является ли устройство хабом или композитным устройством. Это необходимо потому, что, как уже было упомянуто, класс устройств, который используется для хабов и хост контроллеров, используется не только этими устройствами. А нам в первую очередь необходимо контролировать дочерние устройства только хабов, хост контроллеров и композитных устройств. Т.е. для хабов и композитных устройств дополнительно перехватывается запрос перечисления дочерних устройств, на этом этапе, важно также прикрепить ко всем дочерним устройствам фильтр, и этот фильтр будет нижним. В противном случае контроль над дочерними устройствами будет потерян.
Все упомянутые определения выполняются на основе идентификаторов устройств.
Заключение
Несмотря на свою простоту в моем случае данный драйвер достаточно эффективно решает поставленную задачу. Хотя из недостатков следует выделить обязательную перезагрузку после того, как список разрешённых устройств будет обновлён. Чтобы устранить этот недостаток, драйвер потребуется несколько усложнить. Ещё большим недостатком является полное блокирование устройства, а не частичное. Описание, представленное выше, не раскрывает всех деталей реализации. Сделано это было намеренно, и упор был сделан больше на саму концепцию. Желающие разобраться во всем до конца могут ознакомиться с исходным кодом.
USBDeview
Программа для просмотра информации и управления USB-устройствами ПК
Яндекс.Браузер — быстрый браузер с защитой от мошенников и вредоносных сайтов.
- Windows 10
- Windows 8.1
- Windows 8
- Windows 7
- Windows Vista
- Windows XP
Тип лицензии:
Freeware (бесплатное)
Языки: Английский
Снимки экрана 5
![]()
USBDeview — программа для просмотра списка и сведений о USB-устройствах, подключенных в данный момент или когда-либо подключавшихся к компьютеру. Это маленькая, но очень мощная утилита позволяет получать всю имеющуюся информацию об устройствах, а также выполнять над ними ряд стандартных действий.
Программа USBDeview полностью бесплатна для использования, она работает в операционных системах Windows 2000, XP, Vista, 7, 8 и 10. Утилита распространяется в двух версиях — для ОС Windows с архитектурой x86 и x64 (на данной странице можно скачать обе версии по отдельности). Программа поддерживает русский язык, но русификацию требуется выполнить вручную (будет рассмотрено ниже).
Как пользоваться USBDeview?
Основная функция программ USBDeview — считывание и удобное отображение всей возможной технической информации о USB-устройствах. Как отмечалось ранее, утилита способна получать сведения не только об устройствах, подключенных к компьютеру в данный момент, но и тех, что вообще когда-либо использовались на пользовательском ПК. Это говорит о возможности утилиты получать сведения об устройствах из архивов, каталогов, реестра и прочих системных объектов.
При помощи утилиты USBDeview пользователь может получить следующие сведения о USB- устройствах:
- Описание (название, модель и т.д.), тип (флешка, телефон, принтер, камера и т.д.), производитель устройства.
- Выполнялось последнее извлечение устройство безопасным способом (да/нет).
- Подключено ли устройство через USB-концентратор (хаб) либо напрямую к компьютеру.
- Дата первого и последнего подключения устройства к компьютеру.
- Серийный номер, код поставщика, код продукта и версия прошивки устройства.
- Класс, подкласс и протокол USB-интерфейса устройства.
- Имя и описание службы, отвечающей за работу устройства.
- Величина потребляемого устройством тока (в миллиамперах).
- Наименование основного файла, файлов InfSection и InfPath драйвера, а также его версия.
- Код экземпляра устройства и другие.
Пользователю доступен ряд опций, включение и выключение которых позволит просматривать информацию о конкретных категориях USB-устройств, к примеру — отобразить лишь те устройства, для которых не установлены драйверы. Предусмотрено и множество настроек отображения списка.
Дополнительные функции USBDeview
Из дополнительного функционала USBDeview отметим:
- Возможность быстрого включения, выключения и удаление устройств из системы. Эти операции можно выполнять над группой устройств одновременно.
- Возможность перезагрузки USB-концентратора (если используется).
- Просмотр информации о конкретном устройстве в системном реестре.
- Автоматическое открытие окна программы и/или отображение уведомлений при подключении/отключении любого или конкретного устройства.
- Возможность управления и получения любой информации об устройствах через консоль Windows (команды можно найти на официальном сайте разработчиков).
- Отображение информации об устройствах из файла реестра, созданного на любом другом компьютере.
- Возможность получения информации об устройствах с удаленного компьютера (или нескольких одновременно) по сети.
- Экспорт HTML-отчета обо всех или конкретном устройстве и другие возможности.
Смена языка USBDeview
Для установки нужного языка необходимо скопировать языковый файл в ту же папку, где расположена программа (сами файлы можно скачать на официальном сайте). В доступных для скачивания архивах на этой странице языковый файл идет в комплекте. Чтобы установить английский язык, достаточно удалить или переименовать файл «USBDeview_lng.ini».