Выделение и создание URI
Драйвер USB-клиента может использовать подпрограммы драйверов Windows (WDM) для выделения и форматирования URB перед отправкой запроса в стек USB-драйверов, предоставленный Корпорацией Майкрософт.
Драйвер клиента использует URB для упаковки всех сведений, необходимых более низким драйверам в стеке USB-драйверов для обработки запроса. В операционной системе Windows URB описывается в структуре URB .
Корпорация Майкрософт предоставляет библиотеку подпрограмм для драйверов USB-клиента. С помощью этих подпрограмм драйверы USB-клиента могут создавать запросы URB для определенных указанных операций и пересылать их в стек USB. Если вы предпочитаете, вы можете разработать драйвер клиента, чтобы вызвать подпрограммы библиотеки для поддерживаемых операций, а не создавать собственные запросы URB.
Выделение URB в Windows 7 и более ранних версиях
Чтобы отправить USB-запрос с помощью подпрограмм, включенных в комплект драйверов Windows (WDK) для Windows 7 и более ранних версий Windows, драйвер клиента обычно выделяет и заполняет структуру URB, связывает структуру URB с новым IRP и отправляет IRP в стек USB-драйверов.
Для определенных типов запросов корпорация Майкрософт предоставляет вспомогательные подпрограммы (экспортированные Usbd.sys), которые выделяют и форматируют структуру URB . Например, подпрограмма USBD_CreateConfigurationRequestEx выделяет память для структуры URB , форматирует URB для запроса на выборку конфигурации и возвращает адрес структуры URB драйверу клиента. Однако вспомогательные подпрограммы нельзя использовать для всех типов запросов.
Корпорация Майкрософт также предоставляет макросы, которые форматирует URI для некоторых типов запросов. Для этих макросов драйвер клиента должен выделить структуру URB путем вызова ExAllocatePoolWithTag или выделения структуры в стеке. Например, когда драйвер клиента выделяет URB, драйвер может вызвать UsbBuildSelectConfigurationRequest, чтобы отформатировать URB для запроса на выборку конфигурации или очистить конфигурацию.
Для других запросов драйвер клиента должен выделить и отформатировать URB вручную, задав различные члены структуры URB в зависимости от типа запроса.
После завершения USB-запроса драйвер клиента должен освободить структуру URB . Если URB выделяется в стеке, URB освобождается при выходе из область. Если URB выделяется в нестраничном пуле, драйвер клиента должен вызвать ExFreePool , чтобы освободить URB.
Выделение URB в Windows 8
WDK для Windows 8 предоставляет новую статическую библиотеку Usbdex.lib, которая экспортирует подпрограммы для выделения, форматирования и выпуска URI. Кроме того, существует новый способ связывания URB с IRP. Новые подпрограммы можно вызывать клиентским драйвером, предназначенным для Windows Vista и более поздних версий Windows.
Драйвер клиента, работающий в Windows Vista и более поздних версиях, должен использовать новые подпрограммы, чтобы базовый стек USB-драйверов может использовать определенные улучшения производительности и надежности. Эти улучшения применяются к новому стеку USB-драйверов, появившихся в Windows 8 для поддержки устройств USB 3.0 и контроллеров узлов. Для контроллеров узла USB 2.0 Windows загружает более раннюю версию стека драйверов, которая не поддерживает улучшения. Независимо от версии базового стека драйверов или версии протокола, поддерживаемой контроллером узла, необходимо всегда вызывать новые подпрограммы URB.
Перед вызовом любой из новых подпрограмм убедитесь, что у вас есть USBD-дескриптор для регистрации драйвера клиента с стеком USB-драйверов. Чтобы получить дескриптор USBD, вызовите USBD_CreateHandle.
Следующие подпрограммы доступны в WDK для Windows 8. Эти подпрограммы определены в Usbdlib.h.
- USBD_UrbAllocate
- USBD_IsochUrbAllocate
- USBD_SelectConfigUrbAllocateAndBuild
- USBD_SelectInterfaceUrbAllocateAndBuild
- USBD_UrbFree
- USBD_AssignUrbToIoStackLocation
Подпрограммы выделения в предыдущем списке возвращают указатель на новую структуру URB , которая выделяется стеком USB-драйверов. В зависимости от версии стека USB-драйвера, загруженного Windows, структура URB может быть связана с непрозрачным контекстом URB. Контекст URB — это блок сведений о URB. Невозможно просмотреть содержимое заголовка URB; Сведения предназначены для внутреннего использования стеком USB-драйверов для улучшения отслеживания и обработки URB. Контекст URB используется только стеком USB-драйверов для Windows 8. Если контекст URB доступен, стек USB-драйверов использует его для более безопасной и эффективной обработки URB. Например, стек USB-драйверов должен убедиться, что драйвер клиента не отправляет URB, а затем пытается повторно использовать тот же URB до завершения первого запроса. Чтобы обнаружить такую ошибку, стек USB-драйверов сохраняет сведения о состоянии в контексте URB. Без сведений о состоянии стек USB-драйверов должен был бы сравнить входящие URB со всеми URIB в настоящее время. Сведения о состоянии также используются стеком USB-драйверов, когда драйвер клиента пытается освободить URB. Перед выпуском URB стек USB-драйверов проверяет состояние, чтобы убедиться, что URB не ожидается.
Контекст URB предоставляет официальный механизм хранения дополнительных сведений URB. Использование контекста URB предпочтительно для выделения дополнительной памяти по мере необходимости или хранения дополнительных сведений в зарезервированных элементах структуры URB . Стек USB-драйверов выделяет URI и связанный контекст URB в нестраничном пуле, чтобы в будущем, если требуется более крупный контекст URB, единственное необходимое изменение будет размером выделения пула.
Обычная миграция URB
В следующей таблице перечислены изменения в подпрограммах URB.
Вариант использования | Доступно в WDK для Windows 7 и более ранних версий | Доступно в WDK для Windows 8 и более поздних версий |
---|---|---|
Предназначено для Windows 7 и более ранних версий операционной системы. | Предназначено для Windows 8 и более поздних версий операционной системы. | |
Создание URB... | Драйвер клиента выделяет структуру URB и форматирует структуру в зависимости от запроса. Драйвер клиента выделяет структуру URB в стеке или драйвер выделяет структуру в нестраничном пуле путем вызова ExAllocatePoolWithTag. |
Драйвер клиента вызывает USBD_UrbAllocate и получает указатель на новую структуру URB, которая выделяется стеком USB-драйверов. URB может быть связан с контекстом URB в зависимости от версии интерфейса USBD базового стека USB-драйверов. |
Создание URB для запроса на выборку конфигурации... | Драйвер клиента вызывает подпрограмму USBD_CreateConfigurationRequestEx , которая возвращает указатель на новый URIB, созданный и отформатированный стеком USB-драйверов. | Драйвер клиента вызывает USBD_SelectConfigUrbAllocateAndBuild и получает указатель на новую структуру URB, выделенную и отформатированную (для запроса на выборку конфигурации) стеком USB-драйверов. URB может быть связан с контекстом URB в зависимости от версии интерфейса USBD базового стека USB-драйверов. |
Создание URB для запроса на выборку интерфейса... | Драйвер клиента выделяет структуру URB и использует структуру _URB_SELECT_INTERFACE для определения формата команды интерфейса выбора для USB-устройства. | Драйвер клиента вызывает USBD_SelectInterfaceUrbAllocateAndBuild и получает указатель на новую структуру URB, выделенную и отформатированную (для запроса на выборку интерфейса) стеком USB-драйверов. URB может быть связан с контекстом URB в зависимости от версии интерфейса USBD базового стека USB-драйверов. |
Связывание URB с IRP... | Драйвер клиента получает указатель на следующее расположение стека IRP путем вызова IoGetNextIrpStackLocation. Затем драйвер клиента вручную задает элемент Parameters.Others.Argument1 в расположении стека адрес структуры URB . | Драйвер клиента получает указатель на следующее расположение стека IRP путем вызова IoGetNextIrpStackLocation. Затем драйвер клиента вызывает USBD_AssignUrbToIoStackLocation связать URB с расположением стека. |
Чтобы освободить URB... | Если драйвер клиента выделяет URB в стеке, переменная выходит из область после завершения запроса. Чтобы освободить структуру URB, выделенную драйвером клиента или стеком USB-драйверов, выделенным в нестраничном пуле, драйвер клиента вызывает ExFreePool. |
Драйвер клиента вызывает USBD_UrbFree. |