IRP_MN_QUERY_SINGLE_INSTANCE
支援 WMI 的所有驅動程式都必須處理此 IRP。 驅動程式可以藉由呼叫 WmiSystemControl 或處理 IRP 本身來處理 WMI IRP,如 處理 WMI 要求中所述。
如果驅動程式呼叫 WmiSystemControl 來處理 IRP_MN_QUERY_SINGLE_INSTANCE 要求,WMI 接著會呼叫該驅動程式的 DpWmiQueryDataBlock 常式。
主要程式碼
傳送時
WMI 會傳送此 IRP 來查詢指定資料區塊的單一實例。
WMI 會在傳送 IRP_MN_EXECUTE_METHOD 之前傳送 IRP_MN_QUERY_SINGLE_INSTANCE。 如果驅動程式支援 IRP_MN_EXECUTE_METHOD,它必須具有執行方法之相同資料區塊 的IRP_MN_QUERY_SINGLE_INSTANCE 處理常式。
WMI 會在 IRQL = PASSIVE_LEVEL任意執行緒內容中傳送此 IRP。
輸入參數
Parameters.WMI.ProviderId 指向應回應要求的驅動程式裝置物件。 此指標位於 IRP 的驅動程式 I/O 堆疊位置。
Parameters.WMI.DataPath 指向可識別要查詢之資料區塊的 GUID。
Parameters.WMI.BufferSize 指出 Parameters.WMI.Buffer的非分頁緩衝區大小上限,指向可識別要查詢之實例 的WNODE_SINGLE_INSTANCE 結構。
輸出參數
如果驅動程式藉由呼叫WmiSystemControl 來處理 WMI IRP,WMI 會以驅動程式的 DpWmiQueryDataBlock常式所提供的資料填入WNODE_SINGLE_INSTANCE結構。
否則,驅動程式會在Parameters.WMI.Buffer填入WNODE_SINGLE_INSTANCE結構,如下所示:
更新WnodeHeader.BufferSize,其大小為位元組,輸出WNODE_SINGLE_INSTANCE結構,包括實例資料。 這個值應該包含實例名稱 (填補的長度,讓實例資料從四邊字界限開始) ,即使查詢的類別已註冊的靜態實例名稱,驅動程式寫入器也不會在維護此 IRP 時明確提供名稱。
將 SizeDataBlock 設定為實例資料的大小,以位元組為單位。 如果靜態實例名稱正在使用中,這個值不應該包含實例名稱的大小。
從DataBlockOffset開始,將實例資料寫入Parameters.WMI.Buffer。 驅動程式不得變更 DataBlockOffset的輸入值。
如果Parameters.WMI.Buffer上的緩衝區太小而無法接收所有資料,驅動程式會在Parameters.WMI.Buffer的WNODE_TOO_SMALL結構中填入所需的大小。 如果緩衝區小於 sizeof (WNODE_TOO_SMALL) ,驅動程式會失敗 IRP 並傳回STATUS_BUFFER_TOO_SMALL。
I/O 狀態欄塊
如果驅動程式藉由呼叫 WmiSystemControl來處理 IRP,WMI 會在 I/O 狀態欄塊中設定 Irp-IoStatus.Status > 和 Irp-IoStatus.Information > 。
否則,驅動程式會將 Irp-IoStatus.Status > 設定為STATUS_SUCCESS或適當的錯誤狀態,如下所示:
STATUS_BUFFER_TOO_SMALL
STATUS_WMI_GUID_NOT_FOUND
STATUS_WMI_INSTANCE_NOT_FOUND
成功時,驅動程式會將 Irp-IoStatus.Information > 設定為輸入 WnodeHeader.BufferSize的值。 此值包含靜態實例名稱的長度。
作業
驅動程式可以藉由呼叫 WmiSystemControl 或處理 IRP 本身來處理 WMI IRP,如 處理 WMI 要求中所述。
如果驅動程式藉由呼叫 WmiSystemControl 來處理 WMI IRP, WmiSystemControl 會呼叫驅動程式的 DpWmiQueryDataBlock 常式。
如果驅動程式處理 IRP_MN_QUERY_SINGLE_INSTANCE 要求本身,只有當 Parameters.WMI.ProviderId 指向與驅動程式呼叫 IoWMIRegistrationControl時所傳遞的指標相同的裝置物件時,才應該這麼做。 否則,驅動程式必須將要求轉送至裝置堆疊中的下一個較低驅動程式。
在處理要求之前,驅動程式必須判斷 Parameters.WMI.DataPath 是否指向驅動程式支援的 GUID。 如果沒有,驅動程式必須失敗 IRP 並傳回STATUS_WMI_GUID_NOT_FOUND。
驅動程式負責驗證所有輸入值。 具體而言,如果驅動程式處理 IRP 要求本身,則必須執行下列動作:
針對靜態名稱,請確認WNODE_SINGLE_INSTANCE結構的InstanceIndex成員是否在資料區塊驅動程式支援的實例索引範圍內。
針對動態名稱,請確認實例名稱字串會識別驅動程式支援的資料區塊實例。
確認 Parameters.WMI.BufferSize 指定足以接收驅動程式將傳回之所有資料的緩衝區。
如果驅動程式支援資料區塊,它會檢查Parameters.WMI.Buffer的輸入WNODE_SINGLE_INSTANCE實例名稱,如下所示:
如果在 WnodeHeader.Flags中設定WNODE_FLAG_STATIC_INSTANCE_NAMES,驅動程式會使用 InstanceIndex 作為該區塊之驅動程式靜態實例名稱清單的索引。 WMI 會從驅動程式註冊區塊時所提供的註冊資料取得索引。
如果在 WnodeHeader.Flags中清除WNODE_FLAG_STATIC_INSTANCE_NAMES,驅動程式會使用 OffsetInstanceName 的位 移,在輸入 WNODE_SINGLE_INSTANCE中尋找實例名稱字串。 OffsetInstanceName 是結構開頭到 USHORT 的位移,以位元組為單位,這是實例名稱字串的長度, (非字元) ,包括如果有終止 Null,後面接著 Unicode 中的實例名稱字串。
如果驅動程式找不到指定的實例,它必須失敗 IRP 並傳回STATUS_WMI_INSTANCE_NOT_FOUND。 對於具有動態實例名稱的實例,此狀態表示驅動程式不支援 實例。 因此,WMI 可以繼續查詢其他資料提供者,並在另一個提供者找到實例但因其他原因而無法處理要求時,傳回適當的錯誤給資料取用者。
如果驅動程式找到 實例,而且可以處理要求,它會在Parameters.WMI.Buffer填入WNODE_SINGLE_INSTANCE結構,其中包含 實例的資料。
如果實例有效,但驅動程式無法處理要求,它可以傳回任何適當的錯誤狀態。
規格需求
標頭 |
Wdm.h (包括 Wdm.h、Ntddk.h 或 Ntifs.h) |