WMI-WNODE_XXX strukturen

WMI verwendet eine Reihe von Standarddatenstrukturen namens WNODE_XXX , um Daten zwischen Benutzermodusdatenverbrauchern und Kernelmodusdatenanbietern wie Treibern zu übergeben. Wenn ein Treiber WMI-Anforderungen verarbeitet, indem er WmiSystemControl aufruft, muss der Treiber WNODE_XXX-Strukturen nicht lesen oder schreiben. Andernfalls muss der Treiber die Eingabe WNODE_XXX unter Parameters.WMI.Buffer interpretieren und/oder eine Ausgabe WNODE_XXX an diesen Speicherort schreiben.

In der folgenden Tabelle sind WMI-IRPs und die entsprechenden WNODE_XXX-Strukturen aufgeführt.

WMI IRP Verwandte WNODE_XXX-Struktur

IRP_MN_CHANGE_SINGLE_INSTANCE

WNODE_SINGLE_INSTANCE

IRP_MN_CHANGE_SINGLE_ITEM

WNODE_SINGLE_ITEM

IRP_MN_EXECUTE_METHOD

WNODE_METHOD_ITEM

IRP_MN_QUERY_ALL_DATA

WNODE_ALL_DATA

IRP_MN_QUERY_SINGLE_INSTANCE

WNODE_SINGLE_INSTANCE

Zwei zusätzliche WNODE_XXX-Strukturen , WNODE_EVENT_ITEM und WNODE_EVENT_REFERENCE, werden verwendet, um Benachrichtigungen zu aktivierten Ereignissen zu senden. Ein Treiber, der Ereignisblöcke registriert, sendet, wenn ein Ereignis aktiviert ist und das Ereignis auftritt, eine Benachrichtigung über das Ereignis an WMI, indem Er IoWMIWriteEvent aufruft und eine WNODE_EVENT_XXX-Struktur übergibt. Informationen zum Senden von WMI-Ereignissen finden Sie unter Senden von WMI-Ereignissen.

Jede WNODE_XXX-Struktur besteht aus folgenden Elementen:

  • Eine eingebettete WNODE_HEADER-Struktur, die informationen enthält, die allen WNODE_XXX gemeinsam sind, einschließlich der Größe des Puffers, der GUID, die den Datenblock darstellt, und Flags, die den Typ der WNODE_XXX-Struktur angeben, unabhängig davon, ob statische oder dynamische instance Namen verwendet werden, und andere Merkmale des Blocks.

  • Die festen Member der WNODE_XXX-Struktur, z. B. Offsets für instance Namen und Daten.

Auf eine WNODE_XXX-Struktur in einem IRP-Puffer (Parameters.WMI.Buffer) folgen in der Regel variablen Daten im Zusammenhang mit der Anforderung, z. B. dynamische instance Namennamen, statische instance Namenszeichenfolgen, Eingaben für oder Ausgabe einer Methode oder Daten für eine oder mehrere Instanzen eines Datenblocks. Die Größe des Puffers muss daher sizeof(WNODE_XXX) um die Menge der variablen Daten überschreiten.

Beachten Sie, dass WMI keine Typüberprüfung für variablen Daten durchführt, die von einem Treiber bereitgestellt werden. Der Treiber muss Ausgabedaten an einer entsprechenden Grenze im Ausgabepuffer ausrichten, damit ein Datenverbraucher die Daten richtig analysieren kann. Insbesondere muss jede instance an einer 8-Byte-Grenze beginnen, und jedes seiner Elemente muss an einer natürlichen Grenze gemäß dem zuvor vom Treiber registrierten Datenblockschema ausgerichtet werden. Dynamische instance Namen können an einer 2-Byte-Grenze ausgerichtet werden.

Die folgende Abbildung zeigt ein Blockdiagramm eines IRP-Puffers, der eine WNODE_SINGLE_INSTANCE Struktur enthält, die ein Treiber als Reaktion auf eine IRP_MN_QUERY_SINGLE_INSTANCE Anforderung zurückgibt.

Diagramm, das einen irp-Puffer veranschaulicht, der eine wnode-single-instance enthält.

Beginnend am Anfang der vorherigen Abbildung:

  • Die WNODE_HEADER-Struktur am Anfang der WNODE_SINGLE_INSTANCE ist in einem WnodeHeader-Element enthalten. WMI füllt alle Member des WNODE_HEADER aus, bevor die Anforderung gesendet wird. Im WNODE_HEADER:

    • WnodeHeader.Buffersize gibt die Größe des WNODE_SINGLE_INSTANCE an, einschließlich Der Daten, die den festen Elementen der Struktur folgen. (Der Wert von WnodeHeader.Buffersize ist in der Regel kleiner als Parameters.WMI.Buffersize, was die Größe des Puffers angibt, der von WMI zum Empfangen der Ausgabe vom Treiber zugewiesen wird.)
    • WnodeHeader.Guid enthält die GUID, die den Datenblock identifiziert.
    • In diesem Beispiel gibt WnodeHeader.Flags an, dass es sich bei dieser Struktur um eine WNODE_SINGLE_INSTANCE handelt und dass der Datenblock statische instance Namen verwendet.
  • Da der Datenblock statische instance Namen verwendet, legt WMI InstanceIndex auf den Index der instance in der Liste der statischen instance Namen fest, die vom Treiber bei der Registrierung des Blocks übergeben wurden. OffsetInstanceNames wird nicht verwendet.

  • WMI legt DataBlockOffset fest, um den Offset vom Anfang des Puffers bis zum ersten Byte instance Daten anzugeben. (Der Treiber darf diesen Wert nicht ändern.) Da der Datenblock statische instance Namen verwendet, gibt dieser Offset denselben Speicherort wie VariableData an. Wenn der Datenblock dynamische instance Namen verwendet, würden die instance Namen bei VariableData beginnen, und DataBlockOffset würde einen größeren Offset im Puffer angeben.

  • Der Treiber legt SizeDataBlock auf die Anzahl der Bytes von instance zurückgegebenen Daten fest.

  • Bei VariableData (nach instance Namensdaten, falls vorhanden) schreibt der Treiber instance Daten für die angeforderte instance in den Ausgabepuffer.

Ein Treiber liest und schreibt WNODE_METHOD_ITEM und WNODE_SINGLE_ITEM Strukturen auf die gleiche Weise wie WNODE_SINGLE_INSTANCE. Diese Strukturen ähneln sich gegenseitig, da sie über die festen Elemente OffsetInstanceName, InstanceIndex, DataBlockOffset, SizeDataBlock (oder im Fall von WNODE_SINGLE_ITEM, SizeDataItem) und VariableData verfügen. WNODE_METHOD_ITEM enthält eine MethodId und WNODE_SINGLE_ITEM enthält eine ItemId , die WNODE_SINGLE_INSTANCE fehlt.

WNODE_ALL_DATA unterscheidet sich von den vorherigen Strukturen darin, dass es verwendet wird, um mehrere Instanzen eines Datenblocks zu übergeben, einschließlich dynamischer instance Namen und möglicherweise unterschiedlicher Größe.

Die folgende Abbildung zeigt ein Blockdiagramm eines IRP-Puffers, der eine WNODE_ALL_DATA enthält, die ein Treiber als Reaktion auf eine IRP_MN_QUERY_ALL_DATA Anforderung zurückgeben kann.

Abbildung eines irp-Puffers, der eine wnode-all-data-Datei enthält.

Beginnend am Anfang der vorherigen Abbildung:

  • Wie in der vorherigen Abbildung beschrieben, ist die WNODE_HEADER-Struktur am Anfang der WNODE_ALL_DATA in einem WnodeHeader-Element enthalten. WnodeHeader.Buffersize und WnodeHeader.Guid geben die Größe des WNODE_ALL_DATA bzw. der GUID des Datenblocks an.

    In diesem Beispiel legt WMI WnodeHeader.Flags fest, um anzugeben, dass es sich bei dieser Struktur um eine WNODE_ALL_DATA handelt und dass der Datenblock mit dynamischen instance Namen registriert wurde (d. h. WMI löscht WNODE_FLAG_STATIC_INSTANCE_NAMES und WNODE_FLAG_PDO_INSTANCE_NAMES). Bei der Ausgabe legt der Treiber WNODE_FLAG_FIXED_INSTANCE_SIZE fest, um anzugeben, dass alle Instanzen dieselbe Größe haben.

  • WMI legt DataBlockOffset fest, um den Offset vom Anfang des Puffers bis zum ersten Byte instance Daten anzugeben. (Der Treiber darf diesen Wert nicht ändern.) In diesem Beispiel folgen instance Daten den instance Namen unter OffsetInstanceNameOffsets.

  • Der Treiber legt InstanceCount fest, um die Anzahl der zurückgegebenen Instanzen anzugeben.

  • WNODE_XXX für Datenblöcke, die dynamische instance-Namen verwenden, enthalten immer die instance Namenszeichenfolgen. Da in diesem Beispiel dynamische instance Namen verwendet werden, gibt OffsetInstanceNameOffsets den Offset vom Anfang des Puffers auf ein Array von Offsets bis hin zu dynamischen instance Namen im Puffer an.

  • FixedInstanceSize gibt die Anzahl der Datenbytes in jedem instance an, die vom Treiber zurückgegeben werden. Wenn Instanzen dieses Datenblocks in der Größe variieren würden, würde der Treiber WNODE_FLAG_FIXED_INSTANCE_SIZE in WnodeHeader.Flags löschen und OffsetInstanceDataAndLength auf ein Array von OFFSETINSTANCEDATAANDLENGTH-Strukturen festlegen, die jeweils einen Offset für die Daten für eine instance und die Anzahl der Bytes in diesem instance festlegen, anstatt FixedInstanceSize festzulegen.

Weitere Informationen zu WNODE_XXX-Strukturen finden Sie unter Systemstrukturen.