WMI WNODE_XXX 結構

WMI 使用一組稱為WNODE_XXX的標準資料結構,在使用者模式資料取用者和核心模式資料提供者之間傳遞資料,例如驅動程式。 如果驅動程式藉由呼叫WmiSystemControl 來處理 WMI要求,則不需要驅動程式才能讀取或寫入WNODE_XXX結構。 否則,驅動程式必須在Parameters.WMI.Buffer和/或將輸出WNODE_XXX解譯為該位置的輸入WNODE_XXX

下表列出 WMI IRP 及其對應的WNODE_XXX結構。

WMI IRP 相關WNODE_XXX結構

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

另外兩個WNODE_XXX結構WNODE_EVENT_ITEMWNODE_EVENT_REFERENCE,可用來傳送已啟用事件的通知。 註冊事件區塊的驅動程式會在啟用事件且事件發生時傳送事件通知給 WMI,方法是呼叫IoWMIWriteEvent並傳遞WNODE_EVENT_XXX結構。 如需傳送 WMI 事件的詳細資訊,請參閱 傳送 WMI 事件

每個WNODE_XXX結構都包含下列各項:

  • 內嵌WNODE_HEADER結構,其中包含所有WNODE_XXX通用的資訊,包括緩衝區大小、代表資料區塊的 GUID,以及指出WNODE_XXX結構類型的旗標、它是否使用靜態或動態實例名稱,以及區塊的其他特性。

  • 特定WNODE_XXX結構的固定成員,例如實例名稱和資料的位移。

IRP 緩衝區中的WNODE_XXX結構 (Parameters.WMI.Buffer) 通常後面接著與要求相關的變數資料,例如動態實例名稱、靜態實例名稱字串、方法的輸入或輸出,或資料區塊的一或多個實例的資料。 因此,緩衝區的大小必須超過 (WNODE_XXX的大小,) 所涉及的變數資料量。

請注意,WMI 不會對驅動程式所提供的變數資料執行類型檢查。 驅動程式必須在輸出緩衝區中適當界限上對齊輸出資料,以便資料取用者可以正確剖析資料。 特別是,每個實例都必須在 8 位元組界限上啟動,而且每個實例都必須根據驅動程式先前註冊的資料區塊架構,在自然界限上對齊。 動態實例名稱可以在 2 位元組界限上對齊。

下圖顯示 IRP 緩衝區的區塊圖,其中包含驅動程式可能會傳回的 WNODE_SINGLE_INSTANCE 結構,以回應 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 所配置的緩衝區大小,以接收 driver.)
    • WnodeHeader.Guid 包含識別資料區塊的 GUID。
    • 在此範例中, WnodeHeader.Flags 表示這個結構是 WNODE_SINGLE_INSTANCE ,而且資料區塊使用靜態實例名稱。
  • 因為資料區塊使用靜態實例名稱,所以 WMI 會在驅動程式註冊區塊時,將 InstanceIndex 設定為實例清單中的實例索引。 未使用OffsetInstanceNames

  • WMI 會設定 DataBlockOffset ,以指出緩衝區開頭到實例資料的第一個位元組的位移。 (驅動程式不得再次變更此值) ,因為資料區塊使用靜態實例名稱,此位移表示與 VariableData相同的位置。 如果資料區塊使用動態實例名稱,實例名稱會從 VariableData 開始, 而 DataBlockOffset 會指定緩衝區中更大的位移。

  • 驅動程式會將 SizeDataBlock 設定為所傳回實例資料的位元組數目。

  • VariableData (實例名稱資料之後,如果存在) ,驅動程式會在輸出緩衝區中寫入所要求實例的實例資料。

驅動程式會以與WNODE_SINGLE_INSTANCE相同的方式讀取和寫入WNODE_METHOD_ITEMWNODE_SINGLE_ITEM結構。 這些結構彼此類似,其中每個結構都有固定成員 OffsetInstanceNameInstanceIndexDataBlockOffsetSizeDataBlock (,或者,在 WNODE_SINGLE_ITEM的情況下, SizeDataItem) 和 VariableDataWNODE_METHOD_ITEM包含MethodIdWNODE_SINGLE_ITEM包含WNODE_SINGLE_INSTANCE缺少的 ItemId

WNODE_ALL_DATA 與上述結構不同,因為它用來傳遞資料區塊的多個實例,可能包括動態實例名稱,而且可能有不同的大小。

下圖顯示 IRP 緩衝區的區塊圖,其中包含驅動程式可能會傳回的 WNODE_ALL_DATA ,以回應 IRP_MN_QUERY_ALL_DATA 要求。

說明包含 wnode-all-data 之 irp 緩衝區的圖表。

從上圖頂端開始:

  • 如上圖所述, WNODE_ALL_DATA 開頭的 WNODE_HEADER 結構包含在 WnodeHeader 成員中。 WnodeHeader.BuffersizeWnodeHeader.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

如需WNODE_XXX結構的詳細資訊,請參閱系統結構