DispatchPnP-Routinen
Die DispatchPnP-Routine eines Treibers unterstützt Plug & Play, indem IRPs für den IRP_MJ_PNP E/A-Funktionscode verarbeitet werden. Dem IRP_MJ_PNP Funktionscode sind mehrere kleinere E/A-Funktionscodes zugeordnet (siehe Plug & Play Neben-IRPs), von denen einige alle Treiber verarbeiten müssen und von denen einige optional verarbeitet werden können. Der PnP-Manager verwendet diese kleinen Funktionscodes, um Treiber anweisen, Geräte zu starten, zu beenden und zu entfernen und Treiber zu ihren Geräten abzufragen.
Alle Treiber für ein Gerät müssen die Möglichkeit haben, PnP-IRPs für das Gerät zu verarbeiten, außer in einigen Fällen, in denen ein Funktions- oder Filtertreiber das IRP nicht erfolgreich ausführen kann.
Die DispatchPnP-Routine jedes Treibers muss die folgenden Regeln befolgen:
Ein Funktions- oder Filtertreiber muss PnP-IRPs an den nächsten Treiber im Gerätestapel übergeben, es sei denn, die Funktion oder der Filtertreiber verarbeitet den IRP und tritt ein Fehler auf (z. B. aufgrund unzureichender Ressourcen).
Alle Treiber für ein Gerät müssen die Möglichkeit haben, PnP-IRPs für das Gerät zu verarbeiten, es sei denn, bei einem der Treiber tritt ein Fehler auf. Der PnP-Manager sendet IRPs an den obersten Treiber in einem Gerätestapel. Funktions- und Filtertreiber übergeben den IRP an den nächsten Treiber, und der übergeordnete Bustreiber schließt die IRP ab. Weitere Informationen finden Sie unter Übergeben von PnP-IRPs im Gerätestapel .
Ein Treiber kann einen IRP-Fehler verursachen, wenn er versucht, das IRP zu behandeln, und ein Fehler auftritt (z. B. unzureichende Ressourcen). Wenn ein Treiber ein IRP mit einem Code empfängt, den er nicht behandelt, darf der Treiber beim IRP nicht fehlschlagen. Ein solches IRP muss an den nächsten Treiber übergeben werden, ohne die status des IRP zu ändern.
Ein Treiber muss bestimmte PnP-IRPs verarbeiten und kann optional andere verarbeiten.
Jeder PnP-Treiber muss bestimmte IRPs verarbeiten, z. B. IRP_MN_REMOVE_DEVICE, und kann optional andere verarbeiten. Unter Plug & Play Neben-IRPs finden Sie Informationen dazu, welche IRPs für jede Art von Treiber (Funktionstreiber, Filtertreiber und Bustreiber) erforderlich und optional sind.
Ein Treiber kann einen erforderlichen PnP-IRP mit einem entsprechenden Fehler status fehlschlagen, aber ein Treiber darf für eine solche IRP keine STATUS_NOT_SUPPORTED zurückgeben.
Wenn ein Treiber ein PnP-IRP erfolgreich verarbeitet, legt der Treiber die IRP-status auf Erfolg fest. Es ist nicht von einem anderen Treiber im Stapel abhängig, um die status festzulegen.
Ein Treiber legt Irp-IoStatus.Status> auf STATUS_SUCCESS fest, um den PnP-Manager darüber zu informieren, dass der Treiber die IRP erfolgreich verarbeitet hat. Bei einigen IRPs kann sich ein Nicht-Bustreiber möglicherweise auf seinen übergeordneten Bustreiber verlassen, um die status auf Erfolg festzulegen. Dies ist jedoch eine riskante Praxis. Aus Gründen der Konsistenz und Stabilität muss ein Treiber die IRP-status für jeden erfolgreich verarbeiteten PnP-IRP auf Erfolg festlegen.
Wenn bei einem Treiber ein IRP fehlschlägt, schließt der Treiber das IRP mit einem Fehler status ab und übergibt das IRP nicht an den nächsten Treiber.
Wenn ein IRP wie IRP_MN_QUERY_STOP_DEVICE fehlschlägt, legt ein Treiber Irp-IoStatus.Status> auf STATUS_UNSUCCESSFUL fest. Weitere Fehlerwerte status für andere IRPs sind STATUS_INSUFFICIENT_RESOURCES und STATUS_INVALID_DEVICE_STATE.
Treiber legen keine STATUS_NOT_SUPPORTED für IRPs fest, die sie verarbeiten. Dies ist die anfängliche status, die vom PnP-Manager festgelegt wird. Wenn ein IRP mit diesem status abgeschlossen wird, bedeutet dies, dass keine Treiber im Stapel die IRP verarbeitet haben. Alle Treiber haben den IRP gerade an den nächsten Treiber übergeben.
Ein Treiber muss ein PnP-IRP in seiner Dispatchroutine (auf dem Weg nach unten im Gerätestapel des IRP), in einer IoCompletion-Routine (auf dem Weg des IRP, den Gerätestapel zu sichern) oder beides verarbeiten, wie auf der Referenzseite für das IRP angegeben.
Einige PnP-IRPs, z. B. IRP_MN_REMOVE_DEVICE, müssen zuerst vom Treiber oben im Gerätestapel und dann von jedem nächstniedrigen Treiber verarbeitet werden. Andere, z . B. IRP_MN_START_DEVICE, müssen zuerst vom übergeordneten Bustreiber verarbeitet werden. Wieder andere, z . B. IRP_MN_QUERY_CAPABILITIES, können sowohl auf dem Weg nach unten im Gerätestapel als auch auf dem Weg nach oben behandelt werden. Unter Plug & Play Neben-IRPs finden Sie die Regeln, die für die einzelnen PnP-IRP gelten. Informationen zur Behandlung von PnP-IRPs, die zuerst vom übergeordneten Bustreiber verarbeitet werden müssen, finden Sie unter Verschieben der PnP-IRP-Verarbeitung bis zum Ende der niedrigeren Treiber .
Ein Treiber muss einem IRP auf dem IRP-Weg nach unten im Gerätestapel Informationen hinzufügen und Informationen auf dem IRP-Weg nach oben ändern oder entfernen.
Bei der Rückgabe von Informationen als Reaktion auf eine PnP-Abfrage-IRP muss ein Treiber diese Konvention befolgen, um die geordnete Übergabe von Informationen durch die mehrstufigen Treiber für ein Gerät zu ermöglichen.
Sofern nicht explizit dokumentiert, darf ein Treiber nicht davon abhängig sein, dass PnP-IRPs in einer bestimmten Reihenfolge gesendet werden.
Wenn ein Treiber eine PnP-IRP sendet, muss er den IRP an den obersten Treiber im Gerätestapel senden.
Die meisten PnP-IRPs werden vom PnP-Manager gesendet, aber einige können von Treibern gesendet werden (z. B. IRP_MN_QUERY_INTERFACE). Ein Treiber muss eine PnP-IRP an den Treiber am anfang des Gerätestapels senden. Rufen Sie IoGetAttachedDeviceReference auf, um einen Zeiger auf das Geräteobjekt für den Treiber oben im Gerätestapel abzurufen.