IRP_MN_EXECUTE_METHOD
Alle Treiber, die Methoden in Datenblöcken unterstützen, müssen diese IRP verarbeiten. Ein Treiber kann WMI-IRPs entweder durch Aufrufen von WmiSystemControl oder durch Behandeln des IRP selbst verarbeiten, wie unter Behandeln von WMI-Anforderungen beschrieben.
Wenn ein Treiber WmiSystemControl aufruft, um eine IRP_MN_EXECUTE_METHOD-Anforderung zu verarbeiten, ruft WMI wiederum die DpWmiExecuteMethod-Routine dieses Treibers auf.
Hauptcode
Sendebedingungen
WMI sendet dieses IRP, um eine Methode auszuführen, die einem Datenblock zugeordnet ist.
WMI sendet diesen IRP an IRQL = PASSIVE_LEVEL in einem beliebigen Threadkontext.
WMI sendet vor dem Senden einer IRP_MN_EXECUTE_METHOD eine IRP_MN_QUERY_SINGLE_INSTANCE. Wenn ein Treiber IRP_MN_EXECUTE_METHOD muss er über einen IRP_MN_QUERY_SINGLE_INSTANCE-Handler für denselben Datenblock verfügen, dessen Methode ausgeführt wird.
Eingabeparameter
Parameters.WMI.ProviderId verweist auf das Geräteobjekt des Treibers, der auf die Anforderung reagieren soll. Dieser Zeiger befindet sich am E/A-Stapelspeicherort des Treibers im IRP.
Parameters.WMI.DataPath verweist auf eine GUID, die den Datenblock identifiziert, der der auszuführenden Methode zugeordnet ist.
Parameters.WMI.BufferSize gibt die Größe des nicht auslagerten Puffers bei Parameters.WMI.Buffer an, der = sizeof(WNODE_METHOD_ITEM) plus die Größe aller Ausgabedaten für die Methode sein >muss.
Parameters.WMI.Buffer verweist auf eine WNODE_METHOD_ITEM-Struktur , in der MethodID den Bezeichner der auszuführenden Methode und DataBlockOffset den Offset in Bytes vom Anfang der Struktur bis zum ersten Byte der Eingabedaten angibt, falls vorhanden. Parameters.WMI.Buffer:> SizeDataBlock gibt die Größe der Eingabe WNODE_METHOD_ITEM einschließlich Eingabedaten in Byte an, oder null, wenn keine Eingabe vorhanden ist.
Ausgabeparameter
Wenn der Treiber WMI-IRPs durch Aufrufen von WmiSystemControl verarbeitet, füllt WMI die WNODE_METHOD_ITEM mit Daten aus, die von der DpWmiExecuteMethod-Routine des Treibers zurückgegeben werden.
Andernfalls füllt der Treiber die WNODE_METHOD_ITEM-Struktur aus, auf die Parameters.WMI.Buffer wie folgt verweist:
Updates WnodeHeader.BufferSize mit der Größe der Ausgabe WNODE_METHOD_ITEM, einschließlich aller Ausgabedaten.
Updates SizeDataBlock mit der Größe der Ausgabedaten oder null, wenn keine Ausgabedaten vorhanden sind.
Überprüft Parameters.WMI.Buffersize , um zu bestimmen, ob der Puffer groß genug ist, um die Ausgabe WNODE_METHOD_ITEM einschließlich ausgabedaten zu empfangen. Wenn der Puffer nicht groß genug ist, füllt der Treiber die erforderliche Größe in einer WNODE_TOO_SMALL Struktur aus, auf die von Parameters.WMI.Buffer verwiesen wird. Wenn der Puffer kleiner als sizeof(WNODE_TOO_SMALL) ist, schlägt der Treiber die IRP fehl und gibt STATUS_BUFFER_TOO_SMALL zurück.
Schreibt Ausgabedaten(sofern vorhanden) über Eingabedaten ab DataBlockOffset. Der Treiber darf den Eingabewert von DataBlockOffset nicht ändern.
E/A-Statusblock
Wenn der Treiber das IRP durch Aufrufen von WmiSystemControl verarbeitet, legt WMI Irp-IoStatus.Status> und Irp-IoStatus.Information> im E/A-status-Block fest.
Andernfalls legt der Treiber Irp-IoStatus.Status> auf STATUS_SUCCESS oder auf einen geeigneten Fehler fest, status z. B.:
STATUS_BUFFER_TOO_SMALL
STATUS_WMI_GUID_NOT_FOUND
STATUS_WMI_INSTANCE_NOT_FOUND
STATUS_WMI_ITEMID_NOT_FOUND
Bei Erfolg legt ein Treiber Irp-IoStatus.Information> auf die Anzahl der Bytes fest, die unter Parameters.WMI.Buffer in den Puffer geschrieben werden.
Vorgang
Ein Treiber kann WMI-IRPs entweder durch Aufrufen von WmiSystemControl oder durch Behandeln des IRP selbst verarbeiten, wie unter Behandeln von WMI-Anforderungen beschrieben.
Wenn ein Treiber WMI-IRPs durch Aufrufen von WmiSystemControl verarbeitet, ruft diese Routine die DpWmiExecuteMethod-Routine des Treibers auf oder gibt STATUS_INVALID_DEVICE_REQUEST zurück, wenn der Treiber die Routine nicht definiert.
Wenn ein Treiber eine IRP_MN_EXECUTE_METHOD Anforderung selbst verarbeitet, muss er dies nur tun, wenn Parameters.WMI.ProviderId auf dasselbe Geräteobjekt verweist wie der Zeiger, den der Treiber an IoWMIRegistrationControl übergeben hat. Andernfalls muss der Treiber die Anforderung an den nächstniedrigen Treiber weiterleiten.
Der Treiber ist für die Validierung aller Eingabewerte verantwortlich. Insbesondere muss der Treiber die folgenden Schritte ausführen, wenn er die IRP-Anforderung selbst verarbeitet:
Überprüfen Sie bei statischen Namen, ob sich das InstanceIndex-Element der WNODE_METHOD_ITEM-Struktur innerhalb des Bereichs instance Indizes befindet, die vom Treiber für den Datenblock unterstützt werden.
Überprüfen Sie bei dynamischen Namen, ob die instance-Namenszeichenfolge einen Datenblock identifiziert, der vom Treiber unterstützt instance.
Stellen Sie sicher, dass der MethodId-Member der WNODE_METHOD_ITEM-Struktur innerhalb des Bereichs der Methodenbezeichner liegt, die vom Treiber für den Datenblock unterstützt werden, und dass der Aufrufer die Methode ausführen darf.
Stellen Sie sicher, dass die DataBlockOffset- und SizeDataBlock-Member der WNODE_METHOD_ITEM-Struktur einen Puffer beschreiben, der groß genug ist, um die Parameter der angegebenen Methode zu enthalten, und dass die Parameter für die Methode gültig sind.
Stellen Sie sicher, dass Parameters.WMI.Buffersize einen Puffer angibt, der groß genug ist, um die WNODE_METHOD_ITEM-Struktur zu empfangen, nachdem sie mit Ausgabedaten aktualisiert wurde.
Gehen Sie nicht davon aus, dass der Threadkontext dem der initiierenden Benutzermodusanwendung entspricht. Möglicherweise hat ihn ein Treiber auf höherer Ebene geändert.
Vor der Verarbeitung der Anforderung muss der Treiber bestimmen, ob Parameters.WMI.DataPath auf eine vom Treiber unterstützte GUID verweist. Wenn dies nicht der Fall ist, muss der Treiber das IRP nicht ausführen und STATUS_WMI_GUID_NOT_FOUND zurückgeben.
Wenn der Treiber den Datenblock unterstützt, überprüft er die Eingabe WNODE_METHOD_ITEM unter Parameters.WMI.Buffer auf den namen der instance, wie folgt:
Wenn WNODE_FLAG_STATIC_INSTANCE_NAMES in WnodeHeader.Flags festgelegt ist, verwendet der Treiber InstanceIndex als Index in der Liste der statischen instance Namen des Treibers für diesen Block. WMI ruft den Index aus Registrierungsdaten ab, die vom Treiber bei der Registrierung des Blocks bereitgestellt wurden.
Wenn WNODE_FLAG_STATIC_INSTANCE_NAMES in WnodeHeader.Flags eindeutig ist, verwendet der Treiber den Offset unter OffsetInstanceName, um die instance Namenszeichenfolge im Eingabe-WNODE_METHOD_ITEM zu suchen. OffsetInstanceName ist der Offset in Byte vom Anfang der -Struktur bis zu einem USHORT. Dabei handelt es sich um die Länge der instance Namenszeichenfolge in Bytes (keine Zeichen), einschließlich des abschließenden NULL, falls vorhanden, gefolgt von der instance Namenszeichenfolge in Unicode.
Wenn der Treiber die angegebene instance nicht finden kann, muss der IRP fehlschlagen und STATUS_WMI_INSTANCE_NOT_FOUND zurückgeben. Bei einem instance mit einem dynamischen instance Namen gibt diese status an, dass der Treiber die instance nicht unterstützt. WMI kann daher weiterhin andere Datenanbieter abfragen und einen entsprechenden Fehler an den Datenconsumer zurückgeben, wenn ein anderer Anbieter die instance findet, die Anforderung aber aus einem anderen Grund nicht verarbeiten kann.
Der Treiber überprüft dann die Methoden-ID im Eingabe-WNODE_METHOD_ITEM , um zu bestimmen, ob es sich um eine gültige Methode für diesen Datenblock handelt. Andernfalls schlägt der Treiber die IRP fehl und gibt STATUS_WMI_ITEMID_NOT_FOUND zurück.
Wenn die Methode eine Ausgabe generiert, sollte der Treiber die Größe des Ausgabepuffers in Parameters.WMI.BufferSize überprüfen, bevor ein Vorgang ausgeführt wird, der nebenwirkungen hat oder nicht zweimal ausgeführt werden sollte. Wenn z. B. eine Methode die Werte einer Gruppe von Indikatoren zurückgibt und dann die Indikatoren zurücksetzt, sollte der Treiber die Puffergröße überprüfen (und den IRP fehlschlagen, wenn der Puffer zu klein ist), bevor die Leistungsindikatoren zurückgesetzt werden. Dadurch wird sichergestellt, dass WMI die Anforderung mit einem größeren Puffer sicher erneut senden kann.
Wenn die instance und die Methoden-ID gültig sind und der Puffer ausreichend groß ist, führt der Treiber die -Methode aus. Wenn SizeDataBlock im Eingabe-WNODE_METHOD_ITEM ungleich null ist, verwendet der Treiber die Daten ab DataBlockOffset als Eingabe für die -Methode.
Wenn die -Methode eine Ausgabe generiert, schreibt der Treiber die Ausgabedaten ab DataBlockOffset in den Puffer und legt SizeDataBlock in der Ausgabe WNODE_METHOD_ITEM auf die Anzahl von Bytes der Ausgabedaten fest. Wenn die -Methode keine Ausgabedaten enthält, legt der Treiber SizeDataBlock auf 0 (null) fest. Der Treiber darf den Eingabewert von DataBlockOffset nicht ändern.
Wenn der instance gültig ist, der Treiber die Anforderung jedoch nicht verarbeiten kann, kann er einen geeigneten Fehler status zurückgeben.
Anforderungen
Header |
Wdm.h (einschließen Wdm.h, Ntddk.h oder Ntifs.h) |