IRP_MN_CHANGE_SINGLE_INSTANCE
Alle Treiber, die WMI 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_CHANGE_SINGLE_INSTANCE-Anforderung zu verarbeiten, ruft WMI wiederum die DpWmiSetDataBlock-Routine dieses Treibers auf.
Hauptcode
Sendebedingungen
WMI sendet diesen IRP, um alle Datenelemente in einem einzelnen instance eines Datenblocks zu ändern.
WMI sendet diesen IRP an IRQL = PASSIVE_LEVEL in einem beliebigen Threadkontext.
Eingabeparameter
Parameters.WMI.ProviderId verweist auf das Geräteobjekt des Treibers, der auf die Anforderung reagieren soll. Dieser Zeiger befindet sich in der E/A-Stapelposition des Treibers im IRP.
Parameters.WMI.DataPath verweist auf eine GUID, die den Datenblock identifiziert, der dem zu ändernden instance zugeordnet ist.
Parameters.WMI.BufferSize gibt die Größe des nicht auslagerten Puffers unter Parameters.WMI.Buffer an.
Parameters.WMI.Buffer verweist auf eine WNODE_SINGLE_INSTANCE-Struktur, die die instance identifiziert und neue Datenwerte angibt.
Ausgabeparameter
Keine.
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_WMI_INSTANCE_NOT_FOUND
STATUS_WMI_GUID_NOT_FOUND
STATUS_WMI_READ_ONLY
STATUS_WMI_SET_FAILURE
Bei Erfolg legt der Treiber Irp-IoStatus.Information> auf Null fest.
Vorgang
Wenn ein Treiber WMI-IRPs durch Aufrufen von WmiSystemControl verarbeitet, ruft diese Routine die DpWmiSetDataBlock-Routine des Treibers auf oder gibt STATUS_WMI_READ_ONLY zurück, wenn der Treiber die Routine nicht definiert.
Wenn ein Treiber eine IRP_MN_CHANGE_SINGLE_INSTANCE-Anforderung selbst verarbeitet, geschieht dies nur, wenn der Geräteobjektzeiger bei Parameters.WMI.ProviderId mit dem Zeiger übereinstimmt, der vom Treiber in seinem Aufruf von IoWMIRegistrationControl übergeben wurde. Andernfalls muss der Treiber die Anforderung an den nächstniedrigen Treiber weiterleiten.
Wenn der Treiber die Anforderung verarbeitet, muss er zuerst die GUID unter Parameters.WMI.DataPath überprüfen, um zu ermitteln, ob ein vom Treiber unterstützter Datenblock identifiziert wird. 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, muss er die empfangene WNODE_SINGLE_INSTANCE-Struktur unter Parameters.WMI.Buffer wie folgt auf den namen der instance überprüfen:
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 bei OffsetInstanceName, um die instance Namenszeichenfolge im Eingabe-WNODE_SINGLE_INSTANCE zu suchen. OffsetInstanceName ist der Offset in Bytes vom Anfang der Struktur bis zu einer USHORT-größe Länge der instance Namenszeichenfolge in Bytes (keine Zeichen), einschließlich des abschließenden NULL, falls vorhanden, gefolgt von der instance Namenszeichenfolge in Unicode.
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_SINGLE_INSTANCE-Struktur innerhalb des Bereichs der 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 die DataBlockOffset- und SizeDataBlock-Member der WNODE_SINGLE_INSTANCE-Struktur einen Datenblock mit gültiger Größe beschreiben, einschließlich aller Zwischenspeicherungen zwischen Datenelementen, und ob der Inhalt des Puffers für den Datenblock gültig ist.
Stellen Sie sicher, dass der angegebene Datenblock einer ist, für den der Treiber vom Aufrufer initiierte Änderungen zulässt. Anders ausgedrückt: Der Treiber sollte keine Änderungen an Datenblöcken zulassen, die schreibgeschützt sein sollen.
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.
Wenn der Treiber die angegebene instance nicht finden kann, muss der IRP fehlschlagen und STATUS_WMI_INSTANCE_NOT_FOUND zurückgeben. Wenn der instance einen dynamischen instance Namen hat, gibt dieser 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.
Wenn der Treiber die instance findet und die Anforderung verarbeiten kann, legt er die schreibbaren Datenelemente im instance auf die Werte in der WNODE_SINGLE_INSTANCE-Struktur fest, sodass alle schreibgeschützten Elemente unverändert bleiben. Wenn der gesamte Datenblock schreibgeschützt ist, sollte der Treiber beim IRP fehlschlagen und STATUS_WMI_READ_ONLY zurückgeben.
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) |