WMI WNODE_XXX Structures

WMI utilise un ensemble de structures de données standard appelées WNODE_XXX pour transmettre des données entre les consommateurs de données en mode utilisateur et les fournisseurs de données en mode noyau, tels que les pilotes. Si un pilote gère les requêtes WMI en appelant WmiSystemControl, il n’est pas nécessaire de lire ou d’écrire des structures WNODE_XXX . Sinon, le pilote doit interpréter l’entrée WNODE_XXX sur Parameters.WMI.Buffer et/ou écrire une sortie WNODE_XXX à cet emplacement.

Le tableau suivant répertorie les IIP WMI et leurs structures WNODE_XXX correspondantes.

WMI IRP Structure de WNODE_XXX associée

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

Deux structures WNODE_XXX supplémentaires, WNODE_EVENT_ITEM et WNODE_EVENT_REFERENCE, sont utilisées pour envoyer des notifications des événements activés. Un pilote qui inscrit des blocs d’événements, si un événement est activé et que l’événement se produit, envoie une notification de l’événement à WMI en appelant IoWMIWriteEvent et en transmettant une structure WNODE_EVENT_XXX . Pour plus d’informations sur l’envoi d’événements WMI, consultez Envoi d’événements WMI.

Chaque structure WNODE_XXX se compose des éléments suivants :

  • Structure de WNODE_HEADER incorporée qui contient des informations communes à tous les WNODE_XXX, y compris la taille de la mémoire tampon, le GUID qui représente le bloc de données et les indicateurs qui indiquent le type de structure WNODE_XXX, si elle utilise des noms de instance statiques ou dynamiques et d’autres caractéristiques du bloc.

  • Membres fixes de la structure WNODE_XXX particulière, tels que les décalages sur les noms et les données instance.

Une structure WNODE_XXX dans une mémoire tampon IRP (Parameters.WMI.Buffer) est généralement suivie de données variables liées à la requête, telles que des noms de instance dynamiques, des chaînes de nom statiques instance, une entrée ou une sortie d’une méthode, ou des données pour une ou plusieurs instances d’un bloc de données. La taille de la mémoire tampon doit donc dépasser sizeof(WNODE_XXX) de la quantité de données variables impliquées.

Notez que WMI n’effectue pas de vérification de type sur les données de variable fournies par un pilote. Le pilote doit aligner les données de sortie sur une limite appropriée dans la mémoire tampon de sortie afin qu’un consommateur de données puisse analyser les données correctement. En particulier, chaque instance doit démarrer sur une limite de 8 octets et chacun de ses éléments doit être aligné sur une limite naturelle en fonction du schéma de bloc de données précédemment inscrit par le pilote. Les noms de instance dynamiques peuvent être alignés sur une limite de 2 octets.

La figure suivante montre un diagramme en bloc d’une mémoire tampon IRP contenant une structure WNODE_SINGLE_INSTANCE qu’un pilote peut retourner en réponse à une demande de IRP_MN_QUERY_SINGLE_INSTANCE .

diagramme illustrant une mémoire tampon irp contenant un wnode-single-instance.

En commençant en haut de la figure précédente :

  • La structure WNODE_HEADER au début du WNODE_SINGLE_INSTANCE est contenue dans un membre WnodeHeader . WMI remplit tous les membres du WNODE_HEADER avant d’envoyer la demande. Dans le WNODE_HEADER :

    • WnodeHeader.Buffersize indique la taille du WNODE_SINGLE_INSTANCE, y compris les données qui suivent les membres fixes de la structure. (La valeur de WnodeHeader.Buffersize est généralement inférieure à Parameters.WMI.Buffersize, ce qui indique la taille de la mémoire tampon allouée par WMI pour recevoir la sortie du pilote.)
    • WnodeHeader.Guid contient le GUID qui identifie le bloc de données.
    • Dans cet exemple, WnodeHeader.Flags indique que cette structure est un WNODE_SINGLE_INSTANCE et que le bloc de données utilise des noms de instance statiques.
  • Étant donné que le bloc de données utilise des noms de instance statiques, WMI définit InstanceIndex sur l’index du instance dans la liste des noms de instance statiques passés par le pilote lors de l’inscription du bloc. OffsetInstanceNames n’est pas utilisé.

  • WMI définit DataBlockOffset pour indiquer le décalage entre le début de la mémoire tampon et le premier octet de instance données. (Le pilote ne doit pas modifier cette valeur) Là encore, étant donné que le bloc de données utilise des noms de instance statiques, ce décalage indique le même emplacement que VariableData. Si le bloc de données utilisait des noms de instance dynamiques, les noms instance commencent à VariableData et DataBlockOffset spécifient un décalage plus élevé dans la mémoire tampon.

  • Le pilote définit SizeDataBlock sur le nombre d’octets de données instance retournées.

  • Dans VariableData (après instance données de nom, le cas échéant), le pilote écrit instance données pour le instance demandé dans la mémoire tampon de sortie.

Un pilote lit et écrit WNODE_METHOD_ITEM et WNODE_SINGLE_ITEM structures de la même façon que WNODE_SINGLE_INSTANCE. Ces structures se ressemblent en ce que chacune a les membres fixes OffsetInstanceName, InstanceIndex, DataBlockOffset, SizeDataBlock (ou, dans le cas de WNODE_SINGLE_ITEM, SizeDataItem) et VariableData. WNODE_METHOD_ITEM inclut un MethodId et WNODE_SINGLE_ITEM inclut un ItemId qui WNODE_SINGLE_INSTANCE manque.

WNODE_ALL_DATA diffère des structures précédentes en ce qu’il est utilisé pour passer plusieurs instances d’un bloc de données, y compris éventuellement des noms de instance dynamiques et éventuellement de tailles différentes.

La figure suivante montre un diagramme en bloc d’une mémoire tampon IRP contenant un WNODE_ALL_DATA qu’un pilote peut retourner en réponse à une demande de IRP_MN_QUERY_ALL_DATA .

diagramme illustrant une mémoire tampon irp contenant un wnode-all-data.

En commençant en haut de la figure précédente :

  • Comme décrit dans la figure précédente, la structure WNODE_HEADER au début du WNODE_ALL_DATA est contenue dans un membre WnodeHeader . WnodeHeader.Buffersize et WnodeHeader.Guid indiquent la taille du WNODE_ALL_DATA et le GUID du bloc de données, respectivement.

    Dans cet exemple, WMI définit WnodeHeader.Flags pour indiquer que cette structure est un WNODE_ALL_DATA et que le bloc de données a été inscrit avec des noms de instance dynamiques (autrement dit, WMI efface WNODE_FLAG_STATIC_INSTANCE_NAMES et WNODE_FLAG_PDO_INSTANCE_NAMES). Sur la sortie, le pilote définit WNODE_FLAG_FIXED_INSTANCE_SIZE pour indiquer que toutes les instances ont la même taille.

  • WMI définit DataBlockOffset pour indiquer le décalage entre le début de la mémoire tampon et le premier octet de instance données. (Le pilote ne doit pas modifier cette valeur). Dans cet exemple, instance données suivent les noms instance dans OffsetInstanceNameOffsets.

  • Le pilote définit InstanceCount pour indiquer le nombre d’instances retournées.

  • WNODE_XXX pour les blocs de données qui utilisent des noms de instance dynamiques contiennent toujours les chaînes de nom instance. Étant donné que cet exemple utilise des noms de instance dynamiques, OffsetInstanceNameOffsets indique le décalage entre le début de la mémoire tampon et un tableau de décalages vers des noms de instance dynamiques dans la mémoire tampon.

  • FixedInstanceSize indique le nombre d’octets de données dans chaque instance retournés par le pilote. Si les instances de ce bloc de données devaient varier en taille, le pilote effacerait WNODE_FLAG_FIXED_INSTANCE_SIZE dans WnodeHeader.Flags et affecterait à OffsetInstanceDataAndLength un tableau de structures OFFSETINSTANCEDATAANDLENGTH, chacune spécifiant un décalage par rapport aux données pour une instance et le nombre d’octets dans ce instance au lieu de définir FixedInstanceSize.

Pour plus d’informations sur les structures WNODE_XXX , consultez Structures système.