Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Die dynamische Enumeration ist die Fähigkeit eines Treibers, Änderungen an der Anzahl und dem Typ von Geräten zu erkennen und zu melden, die mit dem System verbunden sind, während das System ausgeführt wird.
Bustreiber müssen eine dynamische Enumeration verwenden, wenn die Anzahl oder die Gerätetypen, die mit dem übergeordneten Gerät verbunden sind, von der Konfiguration eines Systems abhängen. Einige dieser Geräte sind möglicherweise immer mit dem System verbunden, und einige werden während des laufenden Betriebs des Systems ein- und ausgesteckt.
Beispielsweise sind die Anzahl und art der Geräte, die an den PCI-Bus eines Systems angeschlossen sind, systemabhängig, aber sie sind dauerhaft, es sei denn, ein Benutzer deaktiviert den Strom, öffnet den Gehäuse und fügt ein Gerät mithilfe eines Schraubenziehers hinzu oder entfernt es. Auf der anderen Seite kann ein Benutzer USB-Geräte hinzufügen oder entfernen, indem er ein Kabel einsteckt oder absteckt, während das System ausgeführt wird.
Dynamische Kindlisten
Das Framework ermöglicht Treibern die Unterstützung der dynamischen Enumeration durch die Bereitstellung von Framework-untergeordneten Listenobjekten. Jedes Objekt der untergeordneten Liste stellt eine Liste von untergeordneten Geräten dar, die mit einem übergeordneten Gerät verbunden sind. Der Bustreiber für das übergeordnete Gerät muss die untergeordneten Geräte des übergeordneten Geräts identifizieren, zur Liste der untergeordneten Geräte des übergeordneten Geräts hinzufügen und für jedes untergeordnete Gerät ein physisches Geräteobjekt (Physical Device Object, PDO) erstellen.
Jedes Mal, wenn ein Treiber ein Framework-Geräteobjekt erstellt, das einen FDO für ein Gerät darstellt, erstellt das Framework eine leere, standardmäßige untergeordnete Liste für das Gerät. Ihr Treiber kann ein Handle für die standardmäßige untergeordnete Liste eines Geräts abrufen, indem er WdfFdoGetDefaultChildList aufruft. Wenn Sie in der Regel einen Bustreiber schreiben, der die untergeordneten Elemente eines Geräts auflistet, kann Ihr Treiber der Standardliste untergeordnete Elemente hinzufügen. Wenn Sie zusätzliche untergeordnete Listen erstellen müssen, kann Ihr Treiber WdfChildListCreate aufrufen.
Bevor ein Treiber eine untergeordnete Liste verwenden kann, muss er das untergeordnete Listenobjekt konfigurieren, indem eine WDF_CHILD_LIST_CONFIG Struktur initialisiert und die Struktur entweder an WdfFdoInitSetDefaultChildListConfig, für die Standard-untergeordnete Liste, oder an WdfChildListCreate, für zusätzliche untergeordnete Listen übergeben wird.
Dynamische Kinderbeschreibungen
Jedes Mal, wenn ein Buscontroller ein untergeordnetes Gerät identifiziert, muss er dessen Beschreibung zu einer Liste untergeordneter Geräte hinzufügen. Eine Kindbeschreibung besteht aus einer notwendigen Identifikationsbeschreibung und einer optionalen Adressbeschreibung.
Identifikationsbeschreibung Eine Identifikationsbeschreibung ist eine Struktur, die Informationen enthält, die jedes Gerät eindeutig identifiziert, das der Treiber aufzählt. Der Treiber definiert diese Struktur, aber sein erstes Element muss eine WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER Struktur sein.
In der Regel enthält eine Identifikationsbeschreibung die Geräteidentifikationszeichenfolgen eines Geräts, möglicherweise eine Seriennummer und Informationen zur Position des Geräts im Bus, z. B. eine Steckplatznummer.
Der Treiber kann die folgenden Rückruffunktionen bereitstellen, mit denen das Framework die Informationen in einer Identifikationsbeschreibung bearbeiten kann:
EvtChildListIdentificationDescriptionCompare, das den Inhalt zweier Identifikationsbeschreibungsstrukturen vergleicht.
EvtChildListIdentificationDescriptionCopy, das den Inhalt einer Identifikationsbeschreibungsstruktur in eine andere kopiert.
EvtChildListIdentificationDescriptionDuplicate, das eine neue Identifikationsbeschreibung erstellt, indem es eine vorhandene Identifikationsbeschreibungsstruktur dupliziert und ggf. zusätzliche Puffer zuordnet.
EvtChildListIdentificationDescriptionCleanup, das Puffer freigibt, die von der Rückruffunktion EvtChildListIdentificationDescriptionDuplicate zugewiesen wurden.
Normalerweise müssen Sie diese Rückruffunktionen bereitstellen, wenn die Beschreibungsstrukturen Ihres Treibers Zeiger auf dynamisch zugeordnete Puffer enthalten. Weitere Informationen zum Zweck dieser Rückruffunktionen finden Sie auf ihren Referenzseiten.
Adressbeschreibung Eine Adressbeschreibung ist eine Struktur, die Informationen enthält, die der Treiber für den Zugriff auf das Gerät auf seinem Bus benötigt, wenn sich die Informationen ändern können, während das Gerät angeschlossen ist. Der Treiber definiert diese Struktur, aber sein erstes Element muss eine WDF_CHILD_ADDRESS_DESCRIPTION_HEADER Struktur sein.
Adressbeschreibungen sind optional. Wenn sich die Adressinformationen eines Geräts zwischen dem Einstecken und dem Herausziehen des Geräts nicht ändern können, können alle Adressinformationen des Geräts in einer Identifikationsbeschreibung gespeichert werden. Usb-Controller weisen z. B. Geräten Adressen zu, wenn die Geräte angeschlossen sind, und diese Adressen werden nicht geändert.
Andererseits verwenden einige Busse Adressinformationen, die sich ändern können. Beispielsweise verwendet der IEEE 1394-Bus einen "Generationszähler", bei dem es sich um die Anzahl der vorgekommenen Busrücksetzungen handelt. Jede asynchrone E/A-Anforderung an ein IEEE 1394-Gerät muss die Generierungsanzahl enthalten. Da sich diese Adressinformationen ändern können, muss ihr Treiber sie in einer Adressbeschreibung speichern.
Um die Informationen in einer Adressbeschreibung zu bearbeiten, kann der Treiber den folgenden Satz von Rückruffunktionen bereitstellen:
EvtChildListAddressDescriptionCopy, das den Inhalt einer Adressbeschreibungsstruktur in eine andere kopiert.
EvtChildListAddressDescriptionDuplicate, das eine neue Adressbeschreibung erstellt, indem eine vorhandene Adressbeschreibungsstruktur dupliziert wird und bei Bedarf zusätzliche Puffer zugeordnet werden.
EvtChildListAddressDescriptionCleanup, die Puffer freigibt, die von der EvtChildListAddressDescriptionDuplicate Callback-Funktion zugewiesen wurden.
In der Regel müssen Sie diese Rückruffunktionen bereitstellen, wenn die Adressbeschreibungsstrukturen Ihres Treibers Zeiger auf dynamisch zugeordnete Puffer enthalten. Weitere Informationen zum Zweck dieser Rückruffunktionen finden Sie auf ihren Referenzseiten.
Hinzufügen von Geräten zu einer dynamischen untergeordneten Liste
Wenn das Framework die EvtDriverDeviceAdd-Rückruffunktion eines Bustreibers aufruft, muss die Rückruffunktion WdfDeviceCreate aufrufen, um einen FDO für das übergeordnete Gerät zu erstellen, bei dem es sich in der Regel um einen Busadapter handelt. Weitere Informationen zum Erstellen eines FDO finden Sie unter Erstellen von Geräteobjekten in einem Funktionstreiber. Der Treiber muss dann die untergeordneten Geräte des übergeordneten Geräts aufzählen und die untergeordneten Geräte einer untergeordneten Liste hinzufügen.
Optionalerweise kann der Treiber WdfDeviceSetBusInformationForChildren aufrufen, um dem Framework Informationen über den Bus bereitzustellen. Es wird empfohlen, dies zu tun, da es für untergeordnete Geräte und Apps einfacher ist, den Bus zu identifizieren.
Um einer untergeordneten Liste Kinder hinzuzufügen, muss ein Treiber für jedes gefundene untergeordnete Gerät WdfChildListAddOrUpdateChildDescriptionAsPresent aufrufen. Dieser Aufruf informiert das Framework darüber, dass ein Treiber ein untergeordnetes Gerät entdeckt hat, das mit einem übergeordneten Gerät verbunden ist. Wenn Ihr Treiber WdfChildListAddOrUpdateChildDescriptionAsPresent aufruft, liefert er eine Identifikationsbeschreibung und optional eine Adressbeschreibung.
Nachdem der Treiber WdfChildListAddOrUpdateChildDescriptionAsPresent aufgerufen hat, um ein neues Gerät zu melden, informiert das Framework den PnP-Manager, dass das neue Gerät vorhanden ist. Der PnP-Manager erstellt einen Gerätestapel und einen Treiberstapel für das neue Gerät. Im Rahmen dieses Prozesses ruft das Framework die Callback-Funktion EvtChildListCreateDevice des Bustreibers auf. Diese Rückruffunktion muss WdfDeviceCreate aufrufen, um einen PDO für das neue Gerät zu erstellen.
In der Regel sind mehrere untergeordnete Geräte mit einem übergeordneten Gerät verbunden, sodass der Bustreiber mehrmals WdfChildListAddOrUpdateChildDescriptionAsPresent aufrufen muss. Die effizienteste Möglichkeit, diesen Prozess zu erledigen, ist die folgende:
Rufen Sie WdfChildListBeginScan auf.
Rufen Sie WdfChildListAddOrUpdateChildDescriptionAsPresent für jedes untergeordnete Gerät auf.
Rufen Sie WdfChildListEndScan auf.
Wenn Sie die dynamische Enumeration Ihres Treibers mit Aufrufen von WdfChildListBeginScan und WdfChildListEndScan umgeben, speichert das Framework alle Änderungen an der Child-Liste. Er benachrichtigt den PnP-Manager über die Änderungen, wenn der Treiber WdfChildListEndScan aufruft. Zu einem späteren Zeitpunkt ruft das Framework die EvtChildListCreateDevice-Rückruffunktion des Bustreibers für jedes Gerät in der untergeordneten Liste auf. Diese Rückruffunktion ruft WdfDeviceCreate auf, um für jedes neue Gerät einen PDO zu erstellen.
Wenn Ihr Treiber WdfChildListBeginScan aufruft, markiert das Framework alle zuvor gemeldeten Geräte als nicht mehr vorhanden. Daher muss der Treiber WdfChildListAddOrUpdateChildDescriptionAsPresent für alle Kind-Elemente aufrufen, die er erkennen kann, nicht nur für neu entdeckte. Um einer untergeordneten Liste ein einzelnes Kind hinzuzufügen, kann der Treiber einen einzelnen Aufruf bei WdfChildListUpdateAllChildDescriptionsAsPresent machen, ohne zuerst WdfChildListBeginScan aufzurufen.
Aktualisieren einer dynamischen Kindliste
Verwenden Sie eine der folgenden Methoden, um die Informationen in einer dynamischen untergeordneten Liste zu aktualisieren:
Wenn ein übergeordnetes Gerät einen Interrupt empfängt, der die Ankunft oder Entfernung eines untergeordneten Geräts angibt, ruft die EvtInterruptDpc-Rückruffunktion WdfChildListAddOrUpdateChildDescriptionAsPresent auf, wenn ein Gerät angeschlossen wird, oder WdfChildListUpdateChildDescriptionAsMissing, wenn ein Gerät entfernt wird.
Der Treiber kann eine EvtChildListScanForChildren-Rückruffunktion bereitstellen, die das Framework jedes Mal aufruft, wenn das übergeordnete Gerät seinen Arbeitsstatus (D0) eingibt. Diese Rückruffunktion sollte alle untergeordneten Geräte aufzählen, indem Sie WdfChildListBeginScan, WdfChildListAddOrUpdateChildDescriptionAsPresent (oder WdfChildListUpdateAllChildDescriptionsAsPresent) und WdfChildListEndScan aufrufen.
Sie können eine oder beide dieser Techniken in Ihrem Treiber verwenden.
Durchlaufen einer dynamischen Kindliste
Um den Inhalt einer untergeordneten Liste zu untersuchen, kann Ihr Treiber die Liste mithilfe einer der folgenden Techniken durchlaufen:
Um den Inhalt jeder untergeordneten Gerätebeschreibung nacheinander zu erhalten, kann der Treiber:
- Rufen Sie WdfChildListBeginIteration auf.
- Rufen Sie WdfChildListRetrieveNextDevice so oft wie nötig auf.
- Rufen Sie WdfChildListEndIteration auf.
Beim Aufrufen von WdfChildListBeginIteration gibt der Treiber ein WDF_RETRIEVE_CHILD_FLAGS-typiertes Flag an, das angibt, ob das Framework alle Gerätebeschreibungen oder nur eine Teilmenge abrufen soll. Wenn WdfChildListRetrieveNextDevice eine Übereinstimmung findet, ruft sie die Identifikations- und Adressbeschreibungen des untergeordneten Geräts sowie ein Handle für sein Geräteobjekt ab.
Um die Adressbeschreibung abzurufen, die derzeit in einer untergeordneten Gerätebeschreibung enthalten ist, kann Ihr Treiber WdfChildListRetrieveAddressDescription aufrufen und eine Identifikationsbeschreibung angeben. Das Framework durchläuft die Kinderliste, bis es ein untergeordnetes Gerät mit einer übereinstimmenden Identifikationsbeschreibung findet. Anschließend wird die Adressbeschreibung abgerufen.
Wenn Sie ein Handle für das Framework-Geräteobjekt abrufen müssen, das einem bestimmten untergeordneten Gerät zugeordnet ist, kann Ihr Treiber WdfChildListRetrievePdo aufrufen. Das Framework durchläuft die Liste der untergeordneten Geräte, bis es ein untergeordnetes Gerät mit einer übereinstimmenden Identifikationsbeschreibung findet und gibt dann ein Geräteobjekthandgriff zurück. Um den Aufrufer vor plötzlicher PnP-Entfernung des PDO in einem anderen Thread zu schützen, schließen Sie den Aufruf mit WdfChildListBeginIteration und WdfChildListEndIteration um.
Zugreifen auf die Identifikations- und Adressbeschreibungen eines PDO
Ihr Treiber kann die folgenden Methoden aufrufen, um auf die Identifikationsbeschreibung oder Adressbeschreibung eines PDO zuzugreifen:
WdfPdoRetrieveIdentificationDescription, die die Identifikationsbeschreibung abruft, die einem PDO zugeordnet ist.
WdfPdoRetrieveAddressDescription, das die Adressbeschreibung abruft, die einem PDO zugeordnet ist.
WdfPdoUpdateAddressDescription, das die Adressbeschreibung aktualisiert, die einem PDO zugeordnet ist.
Behandlung von Neu-Aufzählungsanforderungen
Frameworkbasierte Bustreiber, die die dynamische Enumeration unterstützen, können eine Anforderung empfangen, ein bestimmtes untergeordnetes Gerät über die REENUMERATE_SELF_INTERFACE_STANDARD-Schnittstelle erneut aufzulisten. Weitere Informationen finden Sie unter Behandeln von Enumerationsanforderungen.