Hinzufügen eines PnP-Geräts zu einem ausgeführten System

In diesem Abschnitt wird die Abfolge von Ereignissen beschrieben, die auftreten, wenn das System ein PnP-Gerät konfiguriert, das ein Benutzer einem ausgeführten Computer hinzugefügt hat. In dieser Diskussion werden die Rollen des PnP-Managers, der Bustreiber sowie der Funktions- und Filtertreiber beim Auflisten und Konfigurieren eines neuen Geräts erläutert.

Die meisten dieser Diskussionen sind auch für die Konfiguration eines PnP-Geräts relevant, das beim Starten des Computers vorhanden ist. Insbesondere Geräte, deren Treiber SERVICE_DEMAND_START in einer INF-Datei gekennzeichnet sind, werden im Wesentlichen auf die gleiche Weise konfiguriert, unabhängig davon, ob das Gerät dynamisch hinzugefügt wird oder zur Startzeit vorhanden ist.

Die folgende Abbildung zeigt die ersten Schritte beim Konfigurieren des Geräts, beginnend mit dem Anschließen der Hardware an den Computer durch den Benutzer.

Diagramm, das das Aufzählen und Melden eines Plug-and-Play-Geräts veranschaulicht.

Die folgenden Hinweise entsprechen den eingekreisten Zahlen in der vorherigen Abbildung:

  1. Ein Benutzer steckt ein PnP-Gerät an einen freien Steckplatz auf einem PnP-Bus an.

    In diesem Beispiel steckt der Benutzer einen PnP-USB-Joystick an den Hub eines USB-Hostcontrollers. Der USB-Hub ist ein PnP-Busgerät, da untergeordnete Geräte daran angeschlossen werden können.

  2. Der Funktionstreiber für das Busgerät bestimmt, dass sich ein neues Gerät auf dem Bus befindet.

    Wie der Treiber dies bestimmt, hängt von der Busarchitektur ab. Bei einigen Bussen erhält der Busfunktionstreiber eine Hot-Plug-Benachrichtigung über neue Geräte. Wenn der Bus keine Hot-Plug-Benachrichtigung unterstützt, muss der Benutzer die entsprechenden Maßnahmen in Systemsteuerung ergreifen, damit der Bus aufgelistet wird.

    In diesem Beispiel unterstützt der USB-Bus die Hot-Plug-Benachrichtigung, sodass der Funktionstreiber für den USB-Bus benachrichtigt wird, dass seine untergeordneten Elemente geändert wurden.

  3. Der Funktionstreiber für das Busgerät benachrichtigt den PnP-Manager, dass sich seine Gruppe von untergeordneten Geräten geändert hat.

    Der Funktionstreiber benachrichtigt den PnP-Manager, indem Er IoInvalidateDeviceRelations mit einem BusRelations-Typaufruft.

  4. Der PnP-Manager fragt die Treiber des Busses nach der aktuellen Liste der Geräte auf dem Bus ab.

    Der PnP-Manager sendet eine IRP_MN_QUERY_DEVICE_RELATIONS Anforderung an den Gerätestapel für den Bus. Der Parameter.QueryDeviceRelations.Type-Wert ist BusRelations, was angibt, dass der PnP-Manager nach der aktuellen Liste der im Bus vorhandenen Geräte fragt (Busbeziehungen).

    Der PnP-Manager sendet den IRP an den obersten Treiber im Gerätestapel für den Bus. Gemäß den Regeln für PnP-IRPs verarbeitet jeder Treiber im Stapel die IRP, falls zutreffend, und übergibt den IRP an den nächsten Treiber.

  5. Der Funktionstreiber für das Busgerät übernimmt die IRP.

    Ausführliche Informationen zur Behandlung dieser IRP finden Sie auf der Referenzseite für IRP_MN_QUERY_DEVICE_RELATIONS .

    In diesem Beispiel verarbeitet der USB-Hubtreiber diese IRP für die Hub-FDO. Der Hubtreiber erstellt ein PDO für das Joystickgerät und enthält einen Verweiszeiger auf den Joystick-PDO in der Liste der untergeordneten Geräte, die mit dem IRP zurückgegeben werden.

    Wenn der übergeordnete Bustreiber des USB-Hubs (das Usb-Hostcontroller-Klasse-/Miniklassentreiberpaar) das IRP abgeschlossen hat, wird der IRP mithilfe aller ioCompletion-Routinen , die von den Hubtreibern registriert wurden, den Gerätestapel zurückversetzt.

Beachten Sie, dass der Busfunktionstreiber eine Änderung in seiner Liste der untergeordneten Geräte meldet, indem er anfordert, dass der PnP-Manager die Liste der untergeordneten Geräte abfragt. Die resultierende IRP_MN_QUERY_DEVICE_RELATIONS Anforderung wird von allen Treibern für das Busgerät angezeigt. In der Regel ist der Busfunktionstreiber der einzige Treiber, der die IRP verarbeitet und untergeordnete Elemente meldet. In einigen Gerätestapeln ist ein Busfiltertreiber vorhanden und beteiligt sich an der Erstellung der Liste der Busbeziehungen. Ein Beispiel ist ACPI, das als Busfiltertreiber für ACPI-Geräte angefügt wird. In einigen Gerätestapeln verarbeiten Nichtbusfiltertreiber die IRP_MN_QUERY_DEVICE_RELATIONS Anforderung, dies ist jedoch nicht typisch.

An diesem Punkt verfügt der PnP-Manager über die aktuelle Liste der Geräte im Bus. Der PnP-Manager bestimmt dann, ob Geräte neu eingetroffen oder entfernt wurden. In diesem Beispiel gibt es ein neues Gerät. Die folgende Abbildung zeigt den PnP-Manager, der einen Devnode für das neue Gerät erstellt und mit der Konfiguration des Geräts beginnt.

Diagramm, das das Erstellen eines Devnodes für ein neues Plug-and-Play-Gerät veranschaulicht.

Die folgenden Hinweise entsprechen den eingekreisten Zahlen in der vorherigen Abbildung:

  1. Der PnP-Manager erstellt Devnodes für alle neuen untergeordneten Geräte auf dem Bus.

    Der PnP-Manager vergleicht die Liste der Busbeziehungen, die im IRP_MN_QUERY_DEVICE_RELATIONS-IRP zurückgegeben werden, mit der Liste der untergeordneten Elemente für den Bus, der derzeit in der PnP-Gerätestruktur aufgezeichnet wird. Der PnP-Manager erstellt einen Devnode für jedes neue Gerät und initiiert die Entfernungsverarbeitung für alle Geräte, die entfernt wurden.

    In diesem Beispiel gibt es ein neues Gerät (einen Joystick), sodass der PnP-Manager einen Devnode für den Joystick erstellt. Zu diesem Zeitpunkt ist der einzige Treiber, der für den Joystick konfiguriert ist, der übergeordnete USB-Hubbustreiber, der die PDO des Joysticks erstellt hat. Alle optionalen Busfiltertreiber sind auch im Gerätestapel vorhanden, aber im Beispiel werden Busfiltertreiber aus Gründen der Einfachheit weggelassen.

    Der breite Pfeil zwischen den beiden Devnodes in der vorherigen Abbildung zeigt an, dass der Joystick devnode ein untergeordnetes Element des USB-Hub-Devnodes ist.

  2. Der PnP-Manager sammelt Informationen zum neuen Gerät und beginnt mit der Konfiguration des Geräts.

    Der PnP-Manager sendet eine Sequenz von IRPs an den Gerätestapel, um Informationen über das Gerät zu sammeln. An diesem Punkt besteht der Gerätestapel nur aus dem PDO, der vom übergeordneten Bustreiber des Geräts erstellt wurde, und filtert DOs nach optionalen Busfiltertreibern. Daher sind bustreiber und Busfiltertreiber die einzigen Treiber, die auf diese IRPs reagieren. In diesem Beispiel ist der einzige Treiber im Joystick-Gerätestapel der übergeordnete Bustreiber, der USB-Hubtreiber.

    Der PnP-Manager sammelt Informationen zu einem neuen Gerät, indem er IRPs an den Gerätestapel sendet. Diese IRPs umfassen Folgendes:

    Der PnP-Manager sendet die oben aufgeführten IRPs in dieser Phase der Verarbeitung eines neuen PnP-Geräts, jedoch nicht unbedingt in der aufgeführten Reihenfolge. Daher sollten Sie keine Annahmen über die Reihenfolge treffen, in der die IRPs gesendet werden. Außerdem sollten Sie nicht davon ausgehen, dass der PnP-Manager nur die oben aufgeführten IRPs sendet.

    Der PnP-Manager überprüft die Registrierung, um festzustellen, ob das Gerät zuvor auf diesem Computer installiert wurde. Der PnP-Manager sucht nach einem <Unterschlüssel Enumerator>\<deviceID> für das Gerät unter dem Enum-Branch . In diesem Beispiel ist das Gerät neu und muss "von Grund auf neu" konfiguriert werden.

  3. Der PnP-Manager speichert Informationen zum Gerät in der Registrierung.

    Der Enum-Branch der Registrierung ist für die Verwendung durch Betriebssystemkomponenten reserviert, und sein Layout kann sich ändern. Treiberautoren müssen Systemroutinen verwenden, um Informationen zu Treibern zu extrahieren. Greifen Sie nicht direkt von einem Treiber aus auf den Enum-Branch zu. Die folgenden Enumerationsinformationen werden nur zu Debugzwecken aufgeführt.

    • Der PnP-Manager erstellt einen Unterschlüssel für das Gerät unter dem Schlüssel für den Enumerator des Geräts.

      Der PnP-Manager erstellt einen Unterschlüssel namens HKLM\System\CurrentControlSet\Enum\<enumerator>\<deviceID>. Der Enumeratorunterschlüssel> wird erstellt<, wenn er noch nicht vorhanden ist.

      Ein Enumerator ist eine Komponente, die PnP-Geräte basierend auf einem PnP-Hardwarestandard ermittelt. Die Aufgaben eines Enumerators werden von einem PnP-Busfahrer in Zusammenarbeit mit dem PnP-Manager ausgeführt. Ein Gerät wird in der Regel von seinem übergeordneten Bustreiber aufgezählt, z. B. PCI oder PCMCIA. Einige Geräte werden von einem Busfiltertreiber aufgezählt, z. B. ACPI.

    • Der PnP-Manager erstellt einen Unterschlüssel für diese instance des Geräts.

      Wenn Capabilities.UniqueID für IRP_MN_QUERY_CAPABILITIES als TRUE zurückgegeben wird, ist die eindeutige ID des Geräts systemübergreifend eindeutig. Andernfalls ändert der PnP-Manager die ID so, dass sie systemweit eindeutig ist.

      Der PnP-Manager erstellt einen Unterschlüssel namens HKLM\System\CurrentControlSet\Enum\<enumerator><\deviceID>\<instanceID>.

    • Der PnP-Manager schreibt Informationen zum Gerät in den Unterschlüssel für das Gerät instance.

      Der PnP-Manager speichert Informationen, einschließlich der folgenden, wenn sie für das Gerät bereitgestellt wurden:

      DeviceDesc – von IRP_MN_QUERY_DEVICE_TEXT

      Standort – von IRP_MN_QUERY_DEVICE_TEXT

      Funktionen – die Flags aus IRP_MN_QUERY_CAPABILITIES

      UINumber – von IRP_MN_QUERY_CAPABILITIES

      HardwareID – von IRP_MN_QUERY_ID

      CompatibleIDs – von IRP_MN_QUERY_ID

      ContainerID – von IRP_MN_QUERY_ID

      LogConf\BootConfig – von IRP_MN_QUERY_RESOURCES

      LogConf\BasicConfigVector – von IRP_MN_QUERY_RESOURCE_REQUIREMENTS

An diesem Punkt ist der PnP-Manager bereit, den Funktionstreiber zu suchen und ggf. Treiber für das Gerät zu filtern. (Siehe folgende Abbildung.)

Diagramm zur Veranschaulichung der Suche nach Funktions- und Filtertreibern.

Die folgenden Hinweise entsprechen den nummerierten Kreisen in der vorherigen Abbildung:

  1. Der PnP-Manager im Kernelmodus koordiniert sich mit dem Benutzermodus-PnP-Manager und den Setupkomponenten des Benutzermodus, um die Funktions- und Filtertreiber für das Gerät zu finden, falls vorhanden.

    Der PnP-Manager im Kernelmodus stellt ein Ereignis im PnP-Manager im Benutzermodus in die Warteschlange und identifiziert ein Gerät, das installiert werden muss. Sobald sich ein privilegierter Benutzer anmeldet, fahren die Benutzermoduskomponenten mit der Suche nach Treibern fort. Informationen zu Setupkomponenten und ihrer Rolle beim Installieren eines Geräts finden Sie in der Übersicht über die Geräteinstallation .

  2. Die Setupkomponenten für den Benutzermodus weisen den Kernelmodus-PnP-Manager an, die Funktions- und Filtertreiber zu laden.

    Die Benutzermoduskomponenten rufen den Kernelmodus zurück, um die Treiber zu laden, wodurch ihre AddDevice-Routinen aufgerufen werden.

Die folgende Abbildung zeigt, wie der PnP-Manager die Treiber (falls zutreffend) lädt, seine AddDevice-Routinen aufruft und die Treiber anweisen, das Gerät zu starten.

Diagramm, das das Aufrufen von adddevice-Routinen und das Starten des neuen Geräts veranschaulicht.

Die folgenden Hinweise entsprechen den nummerierten Kreisen in der vorherigen Abbildung:

  1. Treiber mit niedrigerem Filter

    Bevor der Funktionstreiber an den Gerätestapel angefügt wird, verarbeitet der PnP-Manager alle Treiber mit niedrigeren Filtern. Für jeden Treiber mit niedrigeren Filtern ruft der PnP-Manager die DriverEntry-Routine des Treibers auf, wenn der Treiber noch nicht geladen ist. Anschließend ruft der PnP-Manager die AddDevice-Routine des Treibers auf. In seiner AddDevice-Routine erstellt der Filtertreiber ein Filtergeräteobjekt (Filter DO) und fügt es an den Gerätestapel (IoAttachDeviceToDeviceStack) an. Sobald das Geräteobjekt an den Gerätestapel angefügt wurde, wird der Treiber als Treiber für das Gerät verwendet.

    Im USB-Joystick-Beispiel gibt es einen niedrigeren Filtertreiber für das Gerät.

  2. Funktionstreiber

    Nachdem alle niedrigeren Filter angefügt wurden, verarbeitet der PnP-Manager den Funktionstreiber. Der PnP-Manager ruft die DriverEntry-Routine des Funktionstreibers auf, wenn der Treiber noch nicht geladen ist, und ruft die AddDevice-Routine des Funktionstreibers auf. Der Funktionstreiber erstellt ein Funktionsgeräteobjekt (Function Device Object, FDO) und fügt es an den Gerätestapel an.

    In diesem Beispiel ist der Funktionstreiber für den USB-Joystick tatsächlich ein Treiberpaar: der HID-Klassentreiber und der HID-Miniklassentreiber. Die beiden Treiber arbeiten zusammen, um als Funktionstreiber zu dienen. Das Treiberpaar erstellt nur eine FDO und fügt sie an den Gerätestapel an.

  3. Treiber für den oberen Filter

    Nachdem der Funktionstreiber angefügt wurde, verarbeitet der PnP-Manager alle Treiber der oberen Filter.

    In diesem Beispiel gibt es einen Oberen Filtertreiber für das Gerät.

  4. Zuweisen von Ressourcen und Starten des Geräts

    Der PnP-Manager weist dem Gerät bei Bedarf Ressourcen zu und gibt ein IRP aus, um das Gerät zu starten.

    • Zuweisen von Ressourcen

      Früher im Konfigurationsprozess hat der PnP-Manager die Hardwareressourcenanforderungen für das Gerät vom übergeordneten Bustreiber des Geräts erfasst. Nachdem der vollständige Treibersatz für das Gerät geladen wurde, sendet der PnP-Manager eine IRP_MN_FILTER_RESOURCE_REQUIREMENTS Anforderung an den Gerätestapel. Alle Treiber im Stapel haben die Möglichkeit, dieses IRP zu verarbeiten und bei Bedarf die Ressourcenanforderungsliste des Geräts zu ändern.

      Der PnP-Manager weist dem Gerät Ressourcen zu, sofern es für das Gerät erforderlich ist, basierend auf den Anforderungen des Geräts und den derzeit verfügbaren Ressourcen.

      Der PnP-Manager muss möglicherweise die Ressourcenzuweisungen vorhandener Geräte neu anordnen, um die Anforderungen des neuen Geräts zu erfüllen. Diese Neuzuweisung von Ressourcen wird als "Neuausgleich" bezeichnet. Die Treiber für die vorhandenen Geräte erhalten während einer Neuausbalancierung eine Sequenz von Stopp- und Start-IRPs, aber der Ausgleich muss für die Benutzer transparent sein.

      Im Beispiel des USB-Joysticks benötigen USB-Geräte keine Hardwareressourcen, sodass der PnP-Manager die Ressourcenliste auf NULL festlegt.

    • Starten des Geräts (IRP_MN_START_DEVICE)

      Sobald der PnP-Manager dem Gerät Ressourcen zugewiesen hat, sendet er eine IRP_MN_START_DEVICE IRP an den Gerätestapel, um die Treiber anzuweisen, das Gerät zu starten.

    Nachdem das Gerät gestartet wurde, sendet der PnP-Manager drei weitere IRPs an die Treiber für das Gerät:

    • IRP_MN_QUERY_CAPABILITIES

      Nachdem der Start-IRP erfolgreich abgeschlossen wurde, sendet der PnP-Manager eine weitere IRP_MN_QUERY_CAPABILITIES IRP an den Gerätestapel. Alle Treiber für das Gerät haben die Möglichkeit, die IRP zu verarbeiten. Der PnP-Manager sendet diese IRP zu diesem Zeitpunkt, nachdem alle Treiber angefügt und das Gerät gestartet wurde, da die Funktions- oder Filtertreiber möglicherweise auf das Gerät zugreifen müssen, um Funktionsinformationen zu sammeln.

    • IRP_MN_QUERY_PNP_DEVICE_STATE

      Dieses IRP gibt einem Treiber die Möglichkeit, z. B. zu melden, dass das Gerät nicht in Benutzeroberflächen wie Geräte-Manager und dem Hotplug-Programm angezeigt werden soll. Dies ist nützlich für Geräte, die auf einem System vorhanden sind, aber in der aktuellen Konfiguration nicht verwendet werden können, z. B. ein Spielport auf einem Laptop, der nicht verwendet werden kann, wenn der Laptop abgedockt wird.

    • IRP_MN_QUERY_DEVICE_RELATIONS für Busbeziehungen

      Der PnP-Manager sendet diesen IRP, um zu bestimmen, ob das Gerät über untergeordnete Geräte verfügt. Wenn ja, konfiguriert der PnP-Manager jedes untergeordnete Gerät.

Verwenden von GUID_PNP_LOCATION_INTERFACE

Die GUID_PNP_LOCATION_INTERFACE-Schnittstelle stellt die PnP-Geräteeigenschaft (SPDRP_LOCATION_PATHS Plug & Play) für ein Gerät bereit.

Um diese Schnittstelle in Ihrem Treiber zu implementieren, behandeln Sie die IRP_MN_QUERY_INTERFACE IRP mit InterfaceType = GUID_PNP_LOCATION_INTERFACE. Der Treiber stellt einen Zeiger auf eine PNP_LOCATION_INTERFACE-Struktur bereit, die Zeiger auf die einzelnen Routinen der Schnittstelle enthält. Die PnpGetLocationString-Routine stellt den gerätespezifischen Teil der SPDRP_LOCATION_PATHS-Eigenschaft des Geräts bereit.