共用方式為


IRP_MN_QUERY_DEVICE_RELATIONS

PnP 管理員會傳送此要求來判斷裝置之間的特定關聯性。 下列類型的驅動程式會處理此要求:

  • 匯流排驅動程式必須處理其介面卡或控制器的 BusRelations 要求, (匯流排 FDO) 。 篩選驅動程式可能會處理 BusRelations 要求。

  • 匯流排驅動程式必須處理其子裝置的 TargetDeviceRelation 要求, (子 PDO) 。

  • 函式和篩選驅動程式可能會處理 RemovalRelationsPowerRelations 要求。

  • 匯流排驅動程式可能會處理其子裝置的 退出要求 , (子 PDO) 。

0x07

主要程式碼

IRP_MJ_PNP

傳送時

PnP 管理員會傳送此 IRP 來收集與指定裝置關聯性之裝置的相關資訊。

PnP 管理員會在列舉裝置時查詢裝置的 BusRelations (子裝置) ,而當裝置處於作用中狀態時,例如當驅動程式呼叫 IoInvalidateDeviceRelations 常式時,表示子裝置已抵達或離開。

PnP 管理員會在移除裝置的驅動程式之前查詢裝置的 RemoveRelations 。 PnP 管理員會先查詢 RemovalRelations退出Relations ,再退出裝置。

當驅動程式或使用者模式應用程式在裝置上註冊EventCategoryTargetDeviceChange的 PnP 通知時,PnP 管理員會查詢裝置的TargetDeviceRelation。 PnP 管理員會查詢與特定檔案物件相關聯的裝置。 IRP_MN_QUERY_DEVICE_RELATIONS 是唯一具有有效檔案物件參數的 PnP IRP。 驅動程式可以查詢 TargetDeviceRelation的裝置堆疊。 驅動程式不需要在傳送 TargetDeviceRelation 查詢時提供檔案物件。

當裝置的驅動程式呼叫IoInvalidateDeviceRelations時,PnP 管理員會查詢裝置的PowerRelations,以指出此裝置具有隱含電源管理關聯性的裝置集合已變更。 從 Windows 7 開始支援PowerRelations要求。

對於BusRelations、RemovalRelations、退出RelationsPowerRelations要求,PnP 管理員會在 IRQL = PASSIVE_LEVEL于系統執行緒的內容中傳送IRP_MN_QUERY_DEVICE_RELATIONS

針對 TargetDeviceRelation 要求,PnP 管理員會在 IRQL = PASSIVE_LEVEL任意執行緒內容中傳送此 IRP。

輸入參數

IO_STACK_LOCATION結構的Parameters.QueryDeviceRelations.Type成員會指定要查詢的關聯類型。 可能的值包括BusRelations退出Relations、RemovalRelationsTargetDeviceRelationPowerRelations

只有當Parameters.QueryDeviceRelations.TypeTargetDeviceRelation時,目前IO_STACK_LOCATION結構的FileObject成員才會指向有效的檔案物件。

輸出參數

在 I/O 狀態欄塊中傳回。

I/O 狀態欄塊

驅動程式會將 Irp-IoStatus.Status > 設定為STATUS_SUCCESS或失敗狀態,例如STATUS_INSUFFICIENT_RESOURCES。

成功時,驅動程式會將 Irp-IoStatus.Information > 設定為指向所要求關聯資訊的PDEVICE_RELATIONS指標。 DEVICE_RELATIONS結構的定義如下:

typedef struct _DEVICE_RELATIONS {
  ULONG  Count;
  PDEVICE_OBJECT  Objects[1];  // variable length
} DEVICE_RELATIONS, *PDEVICE_RELATIONS;

作業

如果驅動程式傳回關聯以回應這個 IRP_MN_QUERY_DEVICE_RELATIONS,驅動程式會從包含計數和適當裝置物件指標數目的分頁記憶體配置 DEVICE_RELATIONS 結構。 當不再需要結構時,PnP 管理員會釋出結構。 如果驅動程式取代另一個驅動程式配置的 DEVICE_RELATIONS 結構,驅動程式必須釋放先前的結構。

驅動程式必須參考它在此 IRP (ObReferenceObject) 中報告之任何裝置的 PDO。 PnP 管理員會在適當時移除參考。

函式或篩選驅動程式應該準備好在裝置的 AddDevice 常式完成之後,隨時處理裝置的這個 IRP。 匯流排驅動程式應該準備好在列舉裝置之後立即處理 BusRelations 的 查詢。

如需處理隨插即用次要 IRP的一般規則,請參閱隨插即用

下列小節說明處理各種查詢的特定動作。

BusRelations 要求

當 PnP 管理員查詢配接器或控制器 (子裝置) 的匯流排關聯時,匯流排驅動程式必須傳回實際存在於匯流排上之任何裝置之 PDO 的指標清單。 無論是否已啟動裝置,匯流排驅動程式都會報告所有裝置。 匯流排驅動程式可能需要啟動其匯流排裝置,以判斷有哪些子系存在。

警告 裝置物件無法傳遞至任何接受 PDO 做為引數的常式,直到 PnP 管理員為該物件建立裝置節點 (devnode) 為止。 (如果驅動程式通過裝置物件,系統會使用 錯誤檢查0xCA檢查錯誤:PNP_DETECTED_FATAL_ERROR.) PnP 管理員會建立開發節點以回應 IRP_MN_QUERY_DEVICE_RELATIONS 要求。 驅動程式可以安全地假設 PDO 的開發節點在收到 IRP_MN_QUERY_RESOURCE_REQUIREMENTS 要求時已建立。

回應此 IRP 的匯流排驅動程式是匯流排介面卡或控制器的函式驅動程式,而不是介面卡或控制器所連接的匯流排父匯流排驅動程式。 非匯流排裝置的函式驅動程式不會處理此查詢。 這類驅動程式只會將 IRP 傳遞至下一個較低的驅動程式。 (請參閱下圖。) 篩選驅動程式通常不會處理此查詢。

在 Windows Vista 和更新版本的作業系統上,建議驅動程式一律將 IRP_MN_QUERY_DEVICE_RELATIONS IRP 畫上筆,並在稍後完成其處理。 此順序可讓系統以非同步方式處理匯流排關聯查詢。 (Windows Vista 之前的作業系統上,驅動程式可以從其分派常式安全地傳回STATUS_PENDING,但 PnP 管理員不會與任何其他作業重迭匯流排關聯查詢。)

下圖顯示驅動程式如何處理匯流排關聯的查詢。

圖表說明處理匯流排關聯查詢的驅動程式。

在圖中顯示的範例中,PnP 管理員會將BusRelations的IRP_MN_QUERY_DEVICE_RELATIONS傳送至 USB 中樞裝置的驅動程式。 PnP 管理員正在要求中樞裝置的子系列表。

  1. 如同所有 PnP IRP,PnP 管理員會將 IRP 傳送至裝置裝置堆疊中的頂端驅動程式。

  2. 選擇性篩選驅動程式可能是堆疊中的最上層驅動程式。 篩選驅動程式通常不會處理此 IRP;它會將 IRP 向下傳遞至堆疊。 例如,如果驅動程式在匯流排上公開不可列舉的裝置,篩選驅動程式可能會處理此 IRP。

  3. USB 中樞匯流排驅動程式會處理 IRP。

    USB 中樞匯流排驅動程式:

    • 為任何尚未擁有 PDO 的子裝置建立 PDO。

    • 針對任何不再出現在公車上的裝置,將 PDO 標示為非使用中狀態。 公車驅動程式不會刪除這類 PDO。如需刪除 PDO 的時機詳細資訊,請參閱 移除裝置

    • 報告匯流排上存在的任何子裝置。

      對於每個子裝置,匯流排驅動程式會參考 PDO,並將指標放在DEVICE_RELATIONS結構中的 PDO。

      此範例中有兩個 PDO:一個用於搖桿裝置,另一個用於鍵盤裝置。

      匯流排驅動程式應該檢查另一個驅動程式是否已為此 IRP 建立DEVICE_RELATIONS結構。 如果是,匯流排驅動程式必須新增至現有的資訊。

      如果匯流排上沒有子裝置,驅動程式會將DEVICE_RELATIONS結構中的計數設定為零,並傳回成功。

    • 在 I/O 狀態欄塊中設定適當的值,並將 IRP 傳遞至下一個較低的驅動程式。 介面卡或控制器的匯流排驅動程式未完成 IRP。

  4. 如果有的話,選擇性的較低篩選通常不會處理此 IRP。 這類篩選驅動程式會將 IRP 向下傳遞至堆疊。 如果較低篩選驅動程式會處理此 IRP,它可以將 PDO () 新增至子裝置清單,但不得刪除其他驅動程式所建立的任何 PDO。

  5. 父匯流排驅動程式不會處理此 IRP,除非它是裝置堆疊中唯一的驅動程式, (裝置處於原始模式) 。 如同所有 PnP IRP,父匯流排驅動程式會使用 IoCompleteRequest完成 IRP。

    如果裝置堆疊中有一或多個匯流排篩選驅動程式,這類驅動程式可能會處理 IRP 到匯流排驅動程式,並在 IRP 的方式備份裝置堆疊時, (如果有 IoCompletion 常式) 。 根據 PnP IRP 規則,這類驅動程式可以將 PDO 新增至 IRP,並/或修改 IRP 在 IoCompletion 常式中備份堆疊 (的關聯清單) 。

退出Relations 要求

當指定的裝置退出時,驅動程式會傳回任何可能實際從系統移除之裝置之 PDO 的指標。 請勿報告裝置子系的 PDO;PnP 管理員一律會要求在其父裝置之前移除子裝置。

PnP 管理員會將 IRP_MN_EJECT IRP 傳送至即將退出的裝置。 這類裝置的驅動程式也會收到移除 IRP。 裝置的退出關聯會收到 IRP_MN_REMOVE_DEVICE IRP (不是IRP_MN_EJECT IRP )

只有父匯流排驅動程式可以回應其中一個子裝置的 退出Relations 查詢。 函式和篩選驅動程式必須將它傳遞給裝置堆疊中的下一個較低驅動程式。 如果匯流排驅動程式收到此 IRP 作為其配接器或控制器的函式驅動程式,匯流排驅動程式會執行函式驅動程式的工作,而且必須將 IRP 傳遞至下一個較低的驅動程式。

PowerRelations 要求

從 Windows 7 開始, PowerRelations 查詢可讓驅動程式在支援 PnP 列舉的父匯流排與匯流排上列舉子裝置之間的傳統關聯性之外指定電源管理關聯性。 例如,如果匯流排驅動程式無法在公車上列舉子裝置,或裝置是一個以上的匯流排的子系, PowerRelations 查詢可以描述子裝置與匯流排或公車的電源關聯。

當裝置的驅動程式呼叫IoInvalidateDeviceRelations常式,並指定PowerRelationsType參數值時,PnP 管理員會發出裝置的PowerRelations查詢。

為了回應此查詢,目標裝置的驅動程式 (,也就是查詢的目標裝置) 會提供 DEVICE_RELATIONS 結構,其中包含電源管理員開啟之前,電源管理員必須開啟之任何其他裝置之 PDO 的指標。 相反地,只有在關閉目標裝置之後,才必須關閉這些其他裝置。 電源管理員會使用查詢中的資訊,保證這些裝置會以正確的順序開啟和關閉。

此排序保證僅適用于全域系統睡眠狀態轉換,包括轉換到 S1、S2、S3 (睡眠) 、S4 (休眠) ,以及 S5 (關機) 系統電源狀態。 PowerRelations排序保證不適用於 Dx 裝置電源狀態轉換,而系統在 S0 (執行) 系統狀態時,除非在「導向執行時間電源管理」 (DFx) 轉換的情況下。

如果目標裝置位於特殊檔案的裝置路徑上 (,例如分頁檔案、休眠檔案或損毀傾印檔案) ,則目標裝置的驅動程式必須在處理InPathTRUE的 IRP_MN_DEVICE_USAGE_NOTIFICATION IRP 時執行額外的步驟。 此驅動程式必須確保為 PowerRelations 查詢提供 PDO 的裝置也可以支援在特殊檔案的裝置路徑中。 若要確認此支援,目標裝置的驅動程式必須先將 IRP_MN_DEVICE_USAGE_NOTIFICATION IRP 傳送給每個裝置,而且此 IRP 必須指定與目標裝置相同的 UsageNotification.Type 。 只有在收到此 IRP 的所有裝置都完成 IRP 且狀態碼成功時,目標裝置的驅動程式才能順利完成其 IRP_MN_DEVICE_USAGE_NOTIFICATION IRP。 否則,此驅動程式必須以失敗狀態碼完成此 IRP。

當這個相同的驅動程式處理InPathFALSE的IRP_MN_DEVICE_USAGE_NOTIFICATION IRP 時,驅動程式必須將IRP_MN_DEVICE_USAGE_NOTIFICATION IRP 傳送至相同的相依裝置集,如同InPathTRUE的情況。 不過,當 InPathFALSE時,驅動程式應該永遠不會以失敗狀態碼完成此 IRP。

回應 PowerRelations 查詢的驅動程式應該在提供給 PowerRelations 查詢的所有裝置上註冊目標裝置變更通知。 若要註冊這些通知,驅動程式可以呼叫IoRegisterPlugPlayNotification常式,並指定EventCategoryTargetDeviceChangeEventCategory參數值。

RemovalRelations 要求

當移除指定裝置的驅動程式時,驅動程式必須移除之任何裝置的 PDO 指標。 請勿報告裝置子系的 PDO;PnP 管理員已在移除裝置之前要求移除子裝置。

移除關聯的順序未定義。

裝置堆疊中的任何驅動程式都可以處理這種類型的關聯查詢。 函式或篩選驅動程式會先處理 IRP,再將它傳遞至下一個較低的驅動程式。 匯流排驅動程式會處理 IRP,然後完成它。

TargetDeviceRelation 要求

TargetDeviceRelation查詢可讓 PnP 管理員查詢控制硬體之 PnP 裝置堆疊中 PDO 的非 PnP 裝置堆疊。

一般而言,驅動程式會將 IRP_MN_QUERY_DEVICE_RELATIONS IRP 往下轉送其堆疊,直到 IRP 到達特定裝置堆疊的底部為止。 非 PnP 堆疊底部的驅動程式接著會將 IRP 轉送或重新發出至相關的 PnP 堆疊。 例如,PnP 管理員可能會將 TargetDeviceRelation 查詢傳送至檔案系統堆疊頂端的裝置物件,這是非 PnP 堆疊。 檔案系統堆疊中的每個裝置物件都會將查詢傳遞至其下方的裝置物件,直到查詢到達堆疊底部的裝置物件為止。 堆疊中最低裝置物件會將 TargetDeviceRelation 查詢轉送或重新發出至 PnP 儲存磁片區堆疊頂端的裝置物件,然後查詢會向下傳遞至儲存體磁片區堆疊底部的 PDO。

下列清單摘要說明您可以在 PnP 裝置堆疊底部安全地取得 PDO 指標的情況:

  • PnP 中的 Device 物件

    在呼叫裝置的 AddDevice 常式時,PnP 裝置堆疊中的裝置物件會瞭解堆疊的 PDO。 如果使用指標與傳入 的IRP_MN_REMOVE_DEVICE 訊息正確同步,則驅動程式可以使用 移除鎖定常式,安全地快取 PDO 的指標。

  • 非 PnP 堆疊中的裝置物件,不在堆疊底部

    對於不在非 PnP 堆疊底部的裝置物件,驅動程式可以傳送 TargetDeviceRelation 查詢,以取得對應 PnP 裝置堆疊底部 PDO 的指標。

  • 裝置的檔案物件

    指定裝置的檔案物件時,驅動程式可以呼叫 IoGetRelatedDeviceObject 以取得裝置物件,然後遵循上述清單專案中的指示。

  • 裝置物件的控制碼

    指定裝置物件的控制碼時,驅動程式可以呼叫 ObReferenceObjectByHandle 來取得裝置的檔案物件,然後遵循上述清單專案中的指示。

父匯流排驅動程式必須處理其子裝置的 TargetDeviceRelation 關聯查詢。 匯流排驅動程式會使用 ObReferenceObject 參考子裝置的 PDO,並傳回 DEVICE_RELATIONS 結構中 PDO 的指標。 這個關聯型別的結構中只有一個 PDO 指標。 當驅動程式或應用程式在裝置上取消註冊通知時,PnP 管理員會移除 PDO 的參考。

只有父匯流排驅動程式會回應 TargetDeviceRelation 查詢。 函式和篩選驅動程式必須將它傳遞至裝置堆疊中的下一個較低驅動程式。 如果匯流排驅動程式收到此 IRP 作為其配接器或控制器的函式驅動程式,則匯流排驅動程式會執行函式驅動程式的工作,而且必須將 IRP 傳遞至下一個較低的驅動程式。

如果驅動程式不在 PDO 型堆疊中,驅動程式會將新的目標裝置關聯查詢 IRP 傳送至與驅動程式執行 I/O 之檔案控制碼相關聯的裝置物件。

傳送此 IRP

驅動程式不得傳送 IRP_MN_QUERY_DEVICE_RELATIONS 以要求 BusRelations。 驅動程式不限於傳送此 IRP 以進行 RemovalRelations退出Relations,但驅動程式不太可能這麼做。

驅動程式可以查詢 TargetDeviceRelation的裝置堆疊。 如需傳送 IRP 的相關資訊,請參閱 處理 IRP 。 下列步驟特別適用于此 IRP:

  • 設定 IRP 下一個 I/O 堆疊位置中的值:將 MajorFunction 設定為 IRP_MJ_PNP、將 MinorFunction 設定為 IRP_MN_QUERY_DEVICE_RELATIONS、將 Parameters.QueryDeviceRelations.Type 設定為 TargetDeviceRelation,並將 Irp-FileObject > 設定為有效的檔案物件。

  • IoStatus.Status 初始化為 STATUS_NOT_SUPPORTED。

如果驅動程式傳送此 IRP 以取得 PDO 以回應驅動程式收到的TargetDeviceRelationIRP_MN_QUERY_DEVICE_RELATIONS,則驅動程式會報告 PDO,並在 IRP 完成時釋放傳回的關聯結構。 如果驅動程式基於另一個原因起始此 IRP,則驅動程式會在 IRP 完成時釋放關聯結構,並在不再需要 PDO 時取值 PDO。

規格需求

標頭

Wdm.h (包括 Wdm.h、Ntddk.h 或 Ntifs.h)

另請參閱

AddDevice

IoCompleteRequest

IoGetRelatedDeviceObject

IoInvalidateDeviceRelations

IoRegisterPlugPlayNotification

IRP_MJ_PNP

IRP_MN_DEVICE_USAGE_NOTIFICATION

IRP_MN_EJECT

IRP_MN_QUERY_RESOURCE_REQUIREMENTS

IRP_MN_REMOVE_DEVICE

IO_STACK_LOCATION

ObReferenceObject

ObReferenceObjectByHandle