Выделение и создание 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 драйверу клиента. Однако вспомогательные подпрограммы нельзя использовать для всех типов запросов.

Корпорация Майкрософт также предоставляет макросы, которые форматирует urb для некоторых типов запросов. Для этих макросов драйвер клиента должен выделить структуру URB путем вызова ExAllocatePoolWithTag или выделить структуру в стеке. Например, после выделения драйвера клиента URB драйвер может вызвать UsbBuildSelectConfigurationRequest , чтобы отформатировать URB для запроса на выборку конфигурации или очистить конфигурацию.

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

После завершения ЗАПРОСА USB драйвер клиента должен освободить структуру URB . Если URB выделена в стеке, она освобождается при выходе из область. Если URB выделена в пуле без страниц, драйвер клиента должен вызвать ExFreePool , чтобы освободить URB.

Выделение URB в Windows 8

WDK для Windows 8 предоставляет новую статическую библиотеку Usbdex.lib, которая экспортирует подпрограммы для выделения, форматирования и освобождения urb. Кроме того, существует новый способ связывания 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.

Подпрограммы выделения в предыдущем списке возвращают указатель на новую структуру 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 со всеми текущими УРБ. Сведения о состоянии также используются стеком драйверов USB, когда драйвер клиента пытается освободить URB. Перед освобождением URB стек usb-драйвера проверяет состояние, чтобы убедиться, что urb не ожидается.

Контекст URB предоставляет официальный механизм для хранения дополнительных сведений urb. Использовать контекст URB предпочтительнее, чем выделять дополнительную память по мере необходимости или хранить дополнительную информацию в зарезервированных элементах структуры URB . Стек драйверов USB выделяет urb и связанный с ними контекст 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 , которая возвращает указатель на новую urb, созданную и отформатированную стеком драйверов 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.