Partilhar via


Estruturas WMI WNODE_XXX

O WMI usa um conjunto de estruturas de dados padrão chamado WNODE_XXX para passar dados entre consumidores de dados de modo de usuário e provedores de dados de modo kernel, como drivers. Se um driver lida com solicitações WMI chamando WmiSystemControl, o driver não é necessário para ler ou gravar WNODE_estruturas XXX. Caso contrário, o driver deve interpretar a entrada WNODE_XXX em Parameters.WMI.Buffer e/ou gravar uma saída WNODE_XXX para esse local.

A tabela a seguir lista IRPs WMI e suas estruturas WNODE_XXX correspondentes.

WMI IRP Estrutura WNODE_XXX relacionada

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

Duas estruturas WNODE_XXX adicionais, WNODE_EVENT_ITEM e WNODE_EVENT_REFERENCE, são usadas para enviar notificações de eventos habilitados. Um driver que registra blocos de eventos irá, se um evento estiver habilitado e o evento ocorrer, enviar notificação do evento para o WMI chamando IoWMIWriteEvent e passando uma estrutura de WNODE_EVENT_XXX. Para obter informações sobre como enviar eventos WMI, consulte Enviando eventos WMI.

Cada estrutura WNODE_XXX consiste no seguinte:

  • Uma estrutura WNODE_HEADER incorporada que contém informações comuns a todos os WNODE_XXX, incluindo o tamanho do buffer, o GUID que representa o bloco de dados e sinalizadores que indicam o tipo de estrutura de WNODE_XXX, se ela usa nomes de instância estáticos ou dinâmicos, e outras características do bloco.

  • Os membros fixos do WNODE_específico XXX estrutura, como deslocamentos para nomes de instância e dados.

Uma estrutura WNODE_XXX em um buffer IRP (Parameters.WMI.Buffer) é normalmente seguida por dados variáveis relacionados à solicitação, como nomes de instância dinâmica, cadeias de caracteres de nome de instância estática, entrada ou saída de um método ou dados para uma ou mais instâncias de um bloco de dados. O tamanho do buffer deve, portanto, exceder tamanho de(WNODE_XXX) pela quantidade de dados variáveis envolvidos.

Observe que o WMI não executa a verificação de tipo em dados variáveis fornecidos por um driver. O driver deve alinhar os dados de saída em um limite apropriado no buffer de saída para que um consumidor de dados possa analisar os dados corretamente. Em particular, cada instância deve começar em um limite de 8 bytes e cada um de seus itens deve ser alinhado em um limite natural de acordo com o esquema de bloco de dados previamente registrado pelo driver. Os nomes de instâncias dinâmicas podem ser alinhados em um limite de 2 bytes.

A figura a seguir mostra um diagrama de blocos de um buffer IRP contendo uma estrutura de WNODE_SINGLE_INSTANCE que um driver pode retornar em resposta a uma solicitação de IRP_MN_QUERY_SINGLE_INSTANCE.

diagrama ilustrando um buffer IRP contendo uma instância única wnode.

Começando no topo da figura anterior:

  • A estrutura WNODE_HEADER no início do WNODE_SINGLE_INSTANCE está contida em um membro WnodeHeader. O WMI preenche todos os membros do WNODE_HEADER antes de enviar a solicitação. No WNODE_HEADER:

    • WnodeHeader.Buffersize indica o tamanho do WNODE_SINGLE_INSTANCE, incluindo os dados que seguem os membros fixos da estrutura. (O valor de WnodeHeader.Buffersize é normalmente menor que Parameters.WMI.Buffersize, que indica o tamanho do buffer alocado pelo WMI para receber a saída do driver.)
    • WnodeHeader.Guid contém o GUID que identifica o bloco de dados.
    • Neste exemplo, WnodeHeader.Flags indica que essa estrutura é um WNODE_SINGLE_INSTANCE e que o bloco de dados usa nomes de instância estáticos.
  • Como o bloco de dados usa nomes de instância estáticos, o WMI define InstanceIndex para o índice da instância na lista de nomes de instância estática passados pelo driver quando ele registrou o bloco. OffsetInstanceNames não é usado.

  • O WMI define DataBlockOffset para indicar o deslocamento do início do buffer para o primeiro byte de dados da instância. (O driver não deve alterar este valor) Novamente como o bloco de dados usa nomes de instância estática, esse deslocamento indica o mesmo local que VariableData. Se o bloco de dados usasse nomes de instância dinâmicos, os nomes de instância começariam em VariableData e DataBlockOffset especificaria um deslocamento maior no buffer.

  • O driver define SizeDataBlock para o número de bytes de dados de instância que estão sendo retornados.

  • Em VariableData (após os dados do nome da instância, se houver), o driver grava dados da instância para a instância solicitada no buffer de saída.

Um motorista lê e escreve WNODE_METHOD_ITEM e WNODE_SINGLE_ITEM estruturas da mesma forma que WNODE_SINGLE_INSTANCE. Essas estruturas se assemelham na medida em que cada uma tem os membros fixos OffsetInstanceName, InstanceIndex, DataBlockOffset, SizeDataBlock (ou, no caso de WNODE_SINGLE_ITEM, SizeDataItem) e VariableData. WNODE_METHOD_ITEM inclui um MethodId e WNODE_SINGLE_ITEM inclui um ItemId que WNODE_SINGLE_INSTANCE não tem.

WNODE_ALL_DATA difere das estruturas anteriores na medida em que é usado para passar várias instâncias de um bloco de dados, possivelmente incluindo nomes de instâncias dinâmicas e possivelmente de tamanhos diferentes.

A figura a seguir mostra um diagrama de blocos de um buffer IRP contendo um WNODE_ALL_DATA que um driver pode retornar em resposta a uma solicitação de IRP_MN_QUERY_ALL_DATA.

diagrama ilustrando um buffer IRP contendo um WNODE-all-data.

Começando no topo da figura anterior:

  • Conforme descrito na figura anterior, a estrutura WNODE_HEADER no início do WNODE_ALL_DATA está contida em um membro WnodeHeader. WnodeHeader.Buffersize e WnodeHeader.Guid indicam o tamanho do WNODE_ALL_DATA e o GUID do bloco de dados, respectivamente.

    Neste exemplo, o WMI define WnodeHeader.Flags para indicar que essa estrutura é um WNODE_ALL_DATA e que o bloco de dados foi registrado com nomes de instância dinâmicos (ou seja, o WMI limpa WNODE_FLAG_STATIC_INSTANCE_NAMES e WNODE_FLAG_PDO_INSTANCE_NAMES). Na saída, o driver define WNODE_FLAG_FIXED_INSTANCE_SIZE para indicar que todas as instâncias são do mesmo tamanho.

  • O WMI define DataBlockOffset para indicar o deslocamento do início do buffer para o primeiro byte de dados da instância. (O driver não deve alterar esse valor). Neste exemplo, os dados da instância seguem os nomes de instância em OffsetInstanceNameOffsets.

  • O driver define InstanceCount para indicar o número de instâncias que estão sendo retornadas.

  • WNODE_XXX para blocos de dados que usam nomes de instância dinâmicos sempre contêm as cadeias de caracteres de nome de instância. Como este exemplo usa nomes de instância dinâmicos, OffsetInstanceNameOffsets indica o deslocamento do início do buffer para uma matriz de deslocamentos para nomes de instância dinâmica no buffer.

  • FixedInstanceSize indica o número de bytes de dados em cada instância que estão sendo retornados pelo driver. Se as instâncias desse bloco de dados variassem em tamanho, o driver limparia WNODE_FLAG_FIXED_INSTANCE_SIZE em WnodeHeader.Flags e definiria OffsetInstanceDataAndLength como uma matriz de estruturas de OFFSETINSTANCEDATAANDLENGTH, cada uma especificando um deslocamento para os dados de uma instância e o número de bytes nessa instância em vez de definir FixedInstanceSize.

Para obter mais informações sobre estruturas WNODE_XXX, consulte System Structures.