WMI は、WNODE_XXX と呼ばれる一連の標準データ構造を使用して、ユーザー モード のデータ コンシューマーとドライバーなどのカーネル モード データ プロバイダーの間でデータを渡します。 ドライバーが WMISystemControl呼び出すことによって WMI 要求を処理する場合、ドライバーは XXX構造体 WNODE_読み取りまたは書き込みを行う必要はありません。 それ以外の場合、ドライバーは、Parameters.WMI.Buffer で XXX WNODE_入力を解釈するか、XXX WNODE_出力をその場所に書き込む必要があります。
次の表に、WMI IRP とそれに対応する WNODE_XXX 構造体を示します。
WMI IRP | 関連WNODE_XXX構造 |
---|---|
2 つの追加 WNODE_XXX 構造体 (WNODE_EVENT_ITEM と WNODE_EVENT_REFERENCE) は、有効なイベントの通知を送信するために使用されます。 イベント ブロックを登録するドライバーは、イベントが有効になっていて、イベントが発生した場合は、IoWMIWriteEvent呼び出し、WNODE_EVENT_XXX 構造体を渡すことによって、WMI にイベントの通知を送信します。 WMI イベントの送信の詳細については、「WMI イベントの送信」を参照してください。
各 WNODE_XXX 構造体は、次の要素で構成されます。
バッファーのサイズ、データ ブロックを表す GUID、静的インスタンス名と動的インスタンス名のどちらを使用するかに関係なく、XXX構造体の型を示すフラグなど、すべての WNODE_WNODE_XXX に共通する情報を含む埋め込み WNODE_HEADER 構造体。 およびブロックの他の特性。
インスタンス名とデータへのオフセットなど、特定の WNODE_XXX 構造体の固定メンバー。
IRP バッファー (Parameters.WMI.Buffer) 内の WNODE_XXX 構造体には、通常、動的インスタンス名、静的インスタンス名文字列、メソッドの入力または出力、データ ブロックの 1 つ以上のインスタンスのデータなど、要求に関連する変数データが続きます。 したがって、バッファーのサイズは、関係する可変データの量によって sizeof(WNODE_XXX) を超える必要があります。
WMI は、ドライバーによって提供される変数データに対して型チェックを実行しないことに注意してください。 ドライバーは、データ コンシューマーがデータを正しく解析できるように、出力バッファー内の適切な境界に出力データを配置する必要があります。 特に、各インスタンスは 8 バイト境界で開始する必要があり、その各項目は、ドライバーによって以前に登録されたデータ ブロック スキーマに従って自然な境界に配置する必要があります。 動的インスタンス名は、2 バイト境界に配置できます。
次の図は、IRP_MN_QUERY_SINGLE_INSTANCE 要求に応答してドライバーが返す可能性がある WNODE_SINGLE_INSTANCE 構造体を含む IRP バッファーのブロック図を示しています。
前の図の先頭から:
WNODE_SINGLE_INSTANCE の先頭にある WNODE_HEADER 構造体は、WnodeHeader メンバーに含まれています。 WMI は、要求を送信する前に、WNODE_HEADER のすべてのメンバーを入力します。 WNODE_HEADER内:
- WnodeHeader.Buffersize は、構造体の固定メンバーに続くデータを含む、WNODE_SINGLE_INSTANCEのサイズを示します。 (WnodeHeader.Buffersize の値は、通常、Parameters.WMI.Buffersizeより小さく、ドライバーからの出力を受信するために WMI によって割り当てられたバッファーのサイズを示します)。
- WnodeHeader.Guid には、データ ブロックを識別する GUID が含まれています。
- この例では、WnodeHeader.Flags は、この構造体が WNODE_SINGLE_INSTANCE であり、データ ブロックが静的インスタンス名を使用していることを示します。
データ ブロックは静的インスタンス名を使用するため、WMI InstanceIndex を、ドライバーがブロックを登録したときに渡される静的インスタンス名の一覧内のインスタンスのインデックスに設定します。 OffsetInstanceNames は使用されません。
WMI DataBlockOffset を設定して、バッファーの先頭からインスタンス データの最初のバイトまでのオフセットを示します。 (ドライバーはこの値を変更しないでください)データ ブロックは静的インスタンス名を使用するため、このオフセットは VariableData と同じ場所示します。 データ ブロックで動的なインスタンス名が使用されている場合、インスタンス名は variableData で始まり、DataBlockOffset はバッファーへのより大きなオフセットを指定します。
ドライバーは、SizeDataBlock 返されるインスタンス データのバイト数に設定します。
VariableData (インスタンス名データが存在する場合)、ドライバーは要求されたインスタンスのインスタンス データを出力バッファーに書き込みます。
ドライバーは、WNODE_SINGLE_INSTANCEとほぼ同じ方法で WNODE_METHOD_ITEM および WNODE_SINGLE_ITEM 構造体の読み取りと書き込みを行います。 これらの構造体は、OffsetInstanceName 、InstanceIndex、DataBlockOffset、SizeDataBlock (または、WNODE_SINGLE_ITEMの場合は SizeDataItem) VariableData固定メンバーを持つ点で互いに似ています。 WNODE_METHOD_ITEM には MethodId が含まれ、WNODE_SINGLE_ITEM には不足している ItemIdWNODE_SINGLE_INSTANCE 含まれています。
WNODE_ALL_DATA、データ ブロックの複数のインスタンスを渡すために使用されるという点で、上記の構造とは異なります。動的なインスタンス名やサイズが異なる場合があります。
次の図は、ドライバーが IRP_MN_QUERY_ALL_DATA 要求に応答して返される可能性がある WNODE_ALL_DATA を含む IRP バッファーのブロック図を示しています。
前の図の先頭から:
前の図で説明したように、WNODE_ALL_DATA の先頭にある WNODE_HEADER 構造体は、WnodeHeader メンバーに含まれています。 WnodeHeader.Buffersize と WnodeHeader.Guid、WNODE_ALL_DATA のサイズとデータ ブロックの GUID をそれぞれ示します。
この例では、WMI WnodeHeader.Flags を設定して、この構造体が WNODE_ALL_DATA であり、データ ブロックが動的インスタンス名で登録されたことを示します (つまり、WMI はWNODE_FLAG_STATIC_INSTANCE_NAMESとWNODE_FLAG_PDO_INSTANCE_NAMESをクリアします)。 出力時に、ドライバーは、すべてのインスタンスが同じサイズであることを示すWNODE_FLAG_FIXED_INSTANCE_SIZEを設定します。
WMI DataBlockOffset を設定して、バッファーの先頭からインスタンス データの最初のバイトまでのオフセットを示します。 (ドライバーはこの値を変更しないでください)。 この例では、インスタンス データは OffsetInstanceNameOffsetsのインスタンス名に従います。
ドライバーは、返されるインスタンス 数を示す InstanceCount を設定します。
動的インスタンス名を使用するデータ ブロック WNODE_XXX には、常にインスタンス名文字列が含まれます。 この例では動的インスタンス名を使用するため、OffsetInstanceNameOffsets バッファーの先頭からバッファー内の動的インスタンス名へのオフセットの配列へのオフセットを示します。
FixedInstanceSize は、ドライバーによって返される各インスタンスのデータのバイト数を示します。 このデータ ブロックのインスタンスのサイズが異なる場合は、 ドライバーは、WnodeHeader.Flags でWNODE_FLAG_FIXED_INSTANCE_SIZEをクリアし、OffsetInstanceDataAndLength を OFFSETINSTANCEDATAANDLENGTH 構造体の配列に設定し、各インスタンスのデータへのオフセットと、そのインスタンスのバイト数を指定 FixedInstanceSizeを設定します。
XXX構造体 WNODE_詳細については、「システム構造の」を参照してください。