Share via


Zuordnen und Erstellen von URBs

Ein USB-Clienttreiber kann WDM-Treiberroutinen (Windows Driver Model) verwenden, um eine URB zuzuordnen und zu formatieren, bevor die Anforderung an den von Microsoft bereitgestellten USB-Treiberstapel gesendet wird.

Der Clienttreiber verwendet eine URB, um alle Informationen zu packen, die von den unteren Treibern im USB-Treiberstapel zum Verarbeiten der Anforderung benötigt werden. Im Windows-Betriebssystem wird eine URB in einer URB-Struktur beschrieben.

Microsoft stellt eine Bibliothek mit Routinen für USB-Clienttreiber bereit. Mithilfe dieser Routinen können USB-Clienttreiber URB-Anforderungen für bestimmte angegebene Vorgänge erstellen und über den USB-Stapel weiterleiten. Wenn Sie möchten, können Sie Ihren Clienttreiber so entwerfen, dass er die Bibliotheksroutinen für die unterstützten Vorgänge aufruft, anstatt eigene URB-Anforderungen zu erstellen.

URB-Zuordnung in Windows 7 und früher

Um eine USB-Anforderung mithilfe von Routinen zu senden, die im Windows Driver Kit (WDK) für Windows 7 und frühere Versionen von Windows enthalten sind, weist ein Clienttreiber in der Regel eine URB-Struktur zu, füllt sie aus, ordnet die URB-Struktur einem neuen IRP zu und sendet den IRP an den USB-Treiberstapel.

Für bestimmte Arten von Anforderungen stellt Microsoft Hilfsroutinen (exportiert von Usbd.sys) bereit, die die URB-Struktur zuordnen und formatieren. Beispielsweise weist die USBD_CreateConfigurationRequestEx Routine Arbeitsspeicher für eine URB-Struktur zu, formatiert die URB für eine Select-Configuration-Anforderung und gibt die Adresse der URB-Struktur an den Clienttreiber zurück. Die Hilfsroutinen können jedoch nicht für alle Arten von Anforderungen verwendet werden.

Microsoft stellt auch Makros bereit, die URBs für einige Arten von Anforderungen formatieren. Für diese Makros muss der Clienttreiber die URB-Struktur durch Aufrufen von ExAllocatePoolWithTag zuordnen oder die Struktur im Stapel zuordnen. Nachdem der Clienttreiber beispielsweise eine URB zugeordnet hat, kann der Treiber UsbBuildSelectConfigurationRequest aufrufen, um die URB für eine Select-Configuration-Anforderung zu formatieren oder die Konfiguration zu löschen.

Für andere Anforderungen muss der Clienttreiber den URB manuell zuordnen und formatieren, indem verschiedene Member der URB-Struktur festgelegt werden, je nach Anforderungstyp.

Wenn eine USB-Anforderung abgeschlossen ist, muss der Clienttreiber die URB-Struktur freigeben. Wenn die URB im Stapel zugeordnet ist, wird die URB freigegeben, wenn sie den Gültigkeitsbereich überschreitet. Wenn die URB im Nicht-Auslagerungspool zugeordnet ist, muss der Clienttreiber ExFreePool aufrufen, um die URB freizugeben.

URB-Zuordnung in Windows 8

WDK für Windows 8 bietet die neue statische Bibliothek Usbdex.lib, die Routinen zum Zuweisen, Formatieren und Freigeben von URBs exportiert. Darüber hinaus gibt es eine neue Möglichkeit, eine URB einem IRP zuzuordnen. Die neuen Routinen können von einem Clienttreiber für Windows Vista und höhere Versionen von Windows aufgerufen werden.

Ein Clienttreiber, der unter Windows Vista und höher ausgeführt wird, muss die neuen Routinen verwenden, damit der zugrunde liegende USB-Treiberstapel bestimmte Leistungs- und Zuverlässigkeitsverbesserungen nutzen kann. Diese Verbesserungen gelten für den neuen USB-Treiberstapel, der in Windows 8 zur Unterstützung von USB 3.0-Geräten und Hostcontrollern eingeführt wurde. Für USB 2.0-Hostcontroller lädt Windows eine frühere Version des Treiberstapels, die die Verbesserungen nicht unterstützt. Unabhängig von der Version des zugrunde liegenden Treiberstapels oder der vom Hostcontroller unterstützten Protokollversion müssen Sie immer die neuen URB-Routinen aufrufen.

Bevor Sie eine der neuen Routinen aufrufen, stellen Sie sicher, dass Sie über ein USBD-Handle für Die Clienttreiberregistrierung beim USB-Treiberstapel verfügen. Rufen Sie USBD_CreateHandle auf, um ein USBD-Handle zu erhalten.

Die folgenden Routinen sind im WDK für Windows 8 verfügbar. Diese Routinen sind in Usbdlib.h definiert.

Die Zuordnungsroutinen in der vorherigen Liste geben einen Zeiger auf eine neue URB-Struktur zurück, die vom USB-Treiberstapel zugeordnet wird. Abhängig von der Version des von Windows geladenen USB-Treiberstapels kann die URB-Struktur mit einem undurchsichtigen URB-Kontext gekoppelt werden. Ein URB-Kontext ist ein Informationsblock über den URB. Sie können den Inhalt des URB-Headers nicht anzeigen. die Informationen sollen intern vom USB-Treiberstapel verwendet werden, um die NACHVERFOLGUNG und Verarbeitung von URB zu verbessern. Der URB-Kontext wird nur vom USB-Treiberstapel für Windows 8 verwendet. Wenn der URB-Kontext verfügbar ist, wird er vom USB-Treiberstapel verwendet, um die URB-Verarbeitung sicherer und effizienter zu machen. Der USB-Treiberstapel muss beispielsweise sicherstellen, dass der Clienttreiber keine URB übermittelt, und dann versuchen, dieselbe URB wiederzuverwenden, bevor die erste Anforderung abgeschlossen ist. Um diese Art von Fehler zu erkennen, speichert der USB-Treiberstapel Zustandsinformationen im URB-Kontext. Ohne die Statusinformationen müsste der USB-Treiberstapel die eingehende URB mit allen derzeit laufenden URBs vergleichen. Die Statusinformationen werden auch vom USB-Treiberstapel verwendet, wenn der Clienttreiber versucht, die URB freizugeben. Vor der Freigabe der URB überprüft der USB-Treiberstapel den Zustand, um sicherzustellen, dass die URB nicht aussteht.

Der URB-Kontext bietet einen offiziellen Mechanismus zum Speichern zusätzlicher URB-Informationen. Die Verwendung des URB-Kontexts ist besser geeignet, zusätzlichen Arbeitsspeicher nach Bedarf zuzuweisen oder zusätzliche Informationen in reservierten Membern der URB-Struktur zu speichern. Der USB-Treiberstapel ordnet URBs und den zugehörigen URB-Kontext im nicht ausgelagerten Pool zu, sodass in Zukunft, wenn ein größerer URB-Kontext erforderlich ist, die einzige erforderliche Anpassung die Größe einer Poolzuordnung ist.

URB-Routinemigration

In der folgenden Tabelle sind die Änderungen an URB-Routinen zusammengefasst.

Anwendungsfall Verfügbar im WDK für Windows 7 und früher Verfügbar im WDK für Windows 8 und höher
  Ziel: Windows 7 und frühere Versionen des Betriebssystems Ziel Windows 8 und höherer Versionen des Betriebssystems
So erstellen Sie eine URB... Der Clienttreiber ordnet eine URB-Struktur zu und formatiert die Struktur abhängig von der Anforderung.

Der Clienttreiber ordnet die URB-Struktur im Stapel zu, oder der Treiber ordnet die Struktur im nicht ausgelagerten Pool zu, indem ExAllocatePoolWithTag aufgerufen wird.
Der Clienttreiber ruft USBD_UrbAllocate auf und empfängt einen Zeiger auf die neue URB-Struktur , die vom USB-Treiberstapel zugeordnet wird. Die URB kann einem URB-Kontext zugeordnet sein, abhängig von der USBD-Schnittstellenversion des zugrunde liegenden USB-Treiberstapels.
So erstellen Sie eine URB für eine Select-Configuration-Anforderung... Der Clienttreiber ruft die USBD_CreateConfigurationRequestEx Routine auf, die einen Zeiger auf die neue URB zurückgibt, die vom USB-Treiberstapel erstellt und formatiert wird. Der Clienttreiber ruft USBD_SelectConfigUrbAllocateAndBuild auf und empfängt einen Zeiger auf die neue URB-Struktur , die (für die Select-Configuration-Anforderung) vom USB-Treiberstapel zugeordnet und formatiert wird. Die URB kann einem URB-Kontext zugeordnet sein, abhängig von der USBD-Schnittstellenversion des zugrunde liegenden USB-Treiberstapels.
So erstellen Sie eine URB für eine Select-Interface-Anforderung... Der Clienttreiber ordnet eine URB-Struktur zu und verwendet die _URB_SELECT_INTERFACE-Struktur , um das Format eines Select Interface-Befehls für ein USB-Gerät zu definieren. Der Clienttreiber ruft USBD_SelectInterfaceUrbAllocateAndBuild auf und empfängt einen Zeiger auf die neue URB-Struktur , die (für die Select-Interface-Anforderung) vom USB-Treiberstapel zugeordnet und formatiert wird. Die URB kann einem URB-Kontext zugeordnet sein, abhängig von der USBD-Schnittstellenversion des zugrunde liegenden USB-Treiberstapels.
So ordnen Sie eine URB einem IRP zu... Der Clienttreiber ruft durch Aufrufen von IoGetNextIrpStackLocation einen Zeiger auf den nächsten IRP-Stapelspeicherort ab. Anschließend legt der Clienttreiber den Parameter.Others.Argument1-Member des Stapelspeicherorts manuell auf die Adresse der URB-Struktur fest. Der Clienttreiber ruft durch Aufrufen von IoGetNextIrpStackLocation einen Zeiger auf den nächsten IRP-Stapelspeicherort ab. Anschließend ruft der Clienttreiber USBD_AssignUrbToIoStackLocation auf, um eine URB dem Stapelspeicherort zuzuordnen.
So geben Sie eine URB frei... Wenn der Clienttreiber eine URB im Stapel zuordnet, wird die Variable nach Abschluss der Anforderung aus dem Gültigkeitsbereich entfernt.

Um eine URB-Struktur freizugeben, die der Clienttreiber oder der USB-Treiberstapel im nicht ausgelagerten Pool zugeordnet ist, ruft der Clienttreiber ExFreePool auf.
Der Clienttreiber ruft USBD_UrbFree auf.