IRP_MN_QUERY_INTERFACE

Die IRP_MN_QUERY_INTERFACE-Anforderung ermöglicht es einem Treiber, eine Direktanrufschnittstelle an andere Treiber zu exportieren.

Ein Bustreiber, der eine Schnittstelle exportiert, muss diese Anforderung für seine untergeordneten Geräte (untergeordnete PDOs) verarbeiten. Funktion und Filter können diese Anforderung optional verarbeiten.

Eine "Schnittstelle" besteht in diesem Kontext aus einer oder mehreren Routinen und möglicherweise Daten, die von einem Treiber oder einer Gruppe von Treibern exportiert werden. Eine Schnittstelle verfügt über eine Struktur, die ihren Inhalt beschreibt, und eine GUID, die ihren Typ identifiziert.

Der PCMCIA-Bustreiber exportiert beispielsweise eine Schnittstelle vom Typ GUID_PCMCIA_INTERFACE_STANDARD, die Routinen für Vorgänge enthält, z. B. das Abrufen der Schreibschutzbedingung eines PCMCIA-Speichers Karte. Der Funktionstreiber für einen solchen Speicher Karte kann eine IRP_MN_QUERY_INTERFACE Anforderung an den übergeordneten PCMCIA-Bustreiber senden, um Zeiger auf die PCMCIA-Schnittstellenroutinen abzurufen.

Hinweis

Wenn Sie eine neue Version einer vorhandenen Schnittstelle einführen, erstellen Sie eine neue GUID, anstatt die Felder Größe oder Version der INTERFACE-Struktur zu überarbeiten. Weitere Informationen finden Sie unter Verwenden Driver-Defined Schnittstellen.

In diesem Abschnitt wird das Abfrageschnittstellen-IRP als allgemeiner Mechanismus beschrieben. Treiber, die eine Schnittstelle verfügbar machen, sollten zusätzliche Informationen zu ihrer spezifischen Schnittstelle bereitstellen.

Wert

0x08

Hauptcode

IRP_MJ_PNP

Sendebedingungen

Ein Treiber oder eine Systemkomponente sendet diesen IRP, um Informationen zu einer Schnittstelle abzurufen, die von einem Treiber für ein Gerät exportiert wird.

Ein Treiber oder eine Systemkomponente sendet diesen IRP bei IRQL = PASSIVE_LEVEL in einem beliebigen Threadkontext.

Ein Treiber kann diese IRP jederzeit empfangen, nachdem die AddDevice-Routine des Treibers für das Gerät aufgerufen wurde. Das Gerät wird möglicherweise gestartet oder nicht gestartet, wenn dieses IRP gesendet wird (d. h. Sie können nicht davon ausgehen, dass der Treiber eine IRP_MN_START_DEVICE Anforderung für das Gerät erfolgreich abgeschlossen hat).

Eingabeparameter

Das Parameters.QueryInterface-Element der IO_STACK_LOCATION-Struktur ist selbst eine Struktur, die die angeforderte Schnittstelle beschreibt. Die Struktur enthält die folgenden Informationen:

CONST GUID *InterfaceType;
USHORT Size;
USHORT Version;
PINTERFACE Interface;
PVOID InterfaceSpecificData

Die Elemente der Struktur werden wie folgt definiert:

Interfacetype
Zeigt auf eine GUID, die die angeforderte Schnittstelle identifiziert. Die GUID kann für eine systemdefinierte Schnittstelle wie GUID_BUS_INTERFACE_STANDARD oder eine benutzerdefinierte Schnittstelle verwendet werden. Die GUIDs für systemdefinierte Schnittstellen sind in Wdmguid.h aufgeführt. GUIDs für benutzerdefinierte Schnittstellen sollten mit Uuidgen generiert werden.

Größe
Gibt die Größe der angeforderten Schnittstelle an. Treiber, die diese IRP verarbeiten, dürfen keine INTERFACE-Struktur zurückgeben, die größer als Bytesgröße ist.

Version
Gibt die Version der angeforderten Schnittstelle an.

Wenn ein Treiber mehrere Versionen einer Schnittstelle unterstützt, gibt der Treiber die nächstgelegene unterstützte Version zurück, ohne die angeforderte Version zu überschreiten. Die Komponente, die den IRP gesendet hat, sollte das zurückgegebene Feld Interface.Version untersuchen und basierend auf diesem Wert ermitteln, was zu tun ist.

Schnittstelle
Zeigt auf eine Struktur, in der die angeforderte Schnittstelle zurückgegeben werden soll. Diese Struktur muss eine INTERFACE-Struktur als erstes Element enthalten. Die Komponente, die das IRP sendet, weist diese Struktur aus dem ausgelagerten Arbeitsspeicher zu.

Ein Treiber, der eine Schnittstelle exportiert, definiert einen neuen Strukturtyp, der die INTERFACE-Struktur sowie Member für Routinen und/oder Daten in der Schnittstelle enthält. (Der Treiber definiert auch eine GUID für die Schnittstelle, wie oben im InterfaceType-Member beschrieben.)

Ein Treiber, der eine Schnittstelle exportiert, definiert die Ausführungsumgebung für jede Routine in der Schnittstelle, einschließlich der IRQL, unter der die Routine aufgerufen werden kann usw.

InterfaceSpecificData
Gibt zusätzliche Informationen zur angeforderten Schnittstelle an.

Für einige Schnittstellen gibt die Komponente, die das IRP sendet, zusätzliche Informationen in diesem Feld an. In der Regel ist dieses Feld NULL , und die Schnittstellentyp und Version reichen aus, um die angeforderte Schnittstelle zu identifizieren.

Ausgabeparameter

Bei Erfolg füllt ein Treiber die Member der Parameters.QueryInterface.Interface-Struktur aus.

E/A-Statusblock

Ein Treiber legt Irp-IoStatus.Status> auf STATUS_SUCCESS oder auf einen entsprechenden Fehler status fest.

Bei Erfolg legt ein Bustreiber Irp-IoStatus.Information> auf Null fest.

Wenn ein Funktions- oder Filtertreiber diese IRP nicht verarbeitet, ruft er IoSkipCurrentIrpStackLocation auf und übergibt den IRP an den nächsten Treiber. Ein solcher Treiber darf Irp-IoStatus.Status> nicht ändern und darf die IRP nicht abschließen.

Wenn ein Bustreiber die angeforderte Schnittstelle nicht exportiert und daher diese IRP für ein untergeordnetes PDO nicht verarbeitet, lässt der Bustreiber Irp-IoStatus.Status> unverändert und schließt die IRP ab.

Vorgang

Ein Treiber verarbeitet diese IRP, wenn die Parameter eine Vom Treiber unterstützte Schnittstelle angeben.

Ein Treiber darf diese IRP nicht in die Warteschlange stellen, wenn der IRP eine Schnittstelle anfordert, die der Treiber nicht unterstützt. Ein Treiber muss Parameters.QueryInterface.InterfaceType in seiner IO_STACK_LOCATION Struktur überprüfen. Wenn die Schnittstelle nicht vom Treiber unterstützt wird, muss der Treiber den IRP ohne Blockierung an den nächst niedrigeren Treiber im Gerätestapel übergeben.

Jede Schnittstelle muss InterfaceReference - und InterfaceDereference-Routinen bereitstellen, und der Treiber, der die Schnittstelle exportiert, muss die Adressen dieser Routinen in der INTERFACE-Struktur angeben. Bevor ein Treiber eine Schnittstelle als Reaktion auf das IRP zurückgibt, muss er die Referenzanzahl der Schnittstelle erhöhen, indem er seine InterfaceReference-Routine aufruft. Wenn der Treiber, der die Schnittstelle angefordert hat, die Verwendung abgeschlossen hat, muss dieser Treiber die Referenzanzahl verringern, indem er die InterfaceDereference-Routine der Schnittstelle aufruft.

Wenn der Treiber, der den IRP (Treiber x) sendet, die Schnittstelle später an einen anderen Treiber (Treiber y) weitergibt, muss Treiber x die Referenzanzahl der Schnittstelle erhöhen und Treiber y muss sie dekrementieren.

Ein Treiber, der diese IRP verarbeitet, sollte vermeiden, dass der IRP an einen anderen Gerätestapel übergeben wird, um die angeforderte Schnittstelle abzurufen. Ein solcher Entwurf würde Abhängigkeiten zwischen den Gerätestapeln schaffen, die schwer zu verwalten sind. Beispielsweise kann das durch den zweiten Gerätestapel dargestellte Gerät erst entfernt werden, wenn der entsprechende Treiber im ersten Stapel die Schnittstelle dereferenziert.

Schnittstellen können busspezifisch oder busunabhängig sein. Busspezifische Schnittstellen werden in den Headerdateien für diese Busse definiert. Das System definiert eine busunabhängige Schnittstelle BUS_INTERFACE_STANDARD zum Exportieren von Standardbusschnittstellen.

Die allgemeinen Regeln für die Behandlung Plug & Play untergeordneten IRPs finden Sie unter Plug & Play.

Diese IRP wird speziell verwendet, um Routinemäßige Einstiegspunkte zwischen mehrschichtigen Kernelmodustreibern für ein Gerät zu übergeben. Verwechseln Sie die von diesem IRP verfügbar gemachten Schnittstellen nicht mit Geräteschnittstellen. Eine Geräteschnittstelle wird in erster Linie verwendet, um einen Pfad zu einem Gerät zur Verwendung durch Benutzermoduskomponenten oder andere Kernelkomponenten verfügbar zu machen. Weitere Informationen zu Geräteschnittstellen finden Sie unter Geräteschnittstellenklassen.

Senden dieses IRP

Informationen zum Senden von IRPs finden Sie unter Behandeln von IRPs . Die folgenden Schritte gelten speziell für diese IRP:

  • Ordnen Sie eine INTERFACE-Struktur aus einem ausgelagerten Pool zu, und initialisieren Sie sie in Nullen. Wenn die Schnittstelle unter IRQL >= DISPATCH_LEVEL aufgerufen wird, kann der Aufrufer basierend auf dem Schnittstellenvertrag den Inhalt in den Arbeitsspeicher kopieren, der aus einem nicht auslagerten Pool zugeordnet ist.

  • Legen Sie die Werte an der nächsten E/A-Stapelposition des IRP fest: Legen Sie MajorFunction auf IRP_MJ_PNP fest, legen Sie MinorFunction auf IRP_MN_QUERY_INTERFACE fest, und legen Sie die entsprechenden Werte in Parameters.QueryInterface fest.

  • Initialisieren Sie IoStatus.Status , um STATUS_NOT_SUPPORTED.

  • Zuordnung der IRP-Struktur und der INTERFACE-Struktur , wenn sie nicht mehr benötigt werden.

  • Verwenden Sie die Schnittstellenroutinen und den Kontextparameter, wie in der Spezifikation für die Schnittstelle beschrieben.

  • Verringern Sie die Verweisanzahl mithilfe der InterfaceDereference-Routine , wenn die Schnittstelle nicht mehr benötigt wird. Rufen Sie nach der Deferencierung der Schnittstelle keine Schnittstellenroutinen auf.

Ein Treiber sendet diese IRP in der Regel an den oberen Rand des Gerätestapels, an den der Treiber angefügt ist. Wenn ein Treiber diese IRP an einen anderen Gerätestapel sendet, muss sich der Treiber für die Zielgerätebenachrichtigung auf dem anderen Gerät registrieren, wenn das andere Gerät kein Vorgänger des Geräts ist, das vom Treiber gewartet wird. Ein solcher Treiber ruft IoRegisterPlugPlayNotification mit einer EventCategory von EventCategoryTargetDeviceChange auf. Wenn der Treiber eine Benachrichtigung vom Typ GUID_TARGET_DEVICE_QUERY_REMOVE empfängt, muss der Treiber die Schnittstelle ableiten. Der Treiber kann die Schnittstelle erneut abfragen, wenn er eine nachfolgende GUID_TARGET_DEVICE_REMOVE_CANCELLED Benachrichtigung empfängt.

Anforderungen

Header

Wdm.h (einschließlich Wdm.h, Ntddk.h oder Ntifs.h)

Weitere Informationen

BUS_INTERFACE_STANDARD

SCHNITTSTELLE

IoRegisterPlugPlayNotification