將 PnP 裝置新增至執行中的系統
本節說明當系統設定使用者已新增至執行中電腦的 PnP 裝置時所發生的事件順序。 此討論強調列舉和設定新裝置中 PnP 管理員、匯流排驅動程式和功能及篩選驅動程式的角色。
大部分的討論也與設定機器開機時存在的 PnP 裝置相關。 具體來說,驅動程式在 INF 檔案中標示為SERVICE_DEMAND_START的裝置,基本上與裝置在開機時新增或存在的方式相同。
下圖顯示設定裝置的第一個步驟,從使用者將硬體插入電腦時開始。
下列附注對應至上圖中的圓圈數位:
使用者會將 PnP 裝置插入 PnP 匯流排上的可用位置。
在此範例中,使用者會將 PnP USB 搖桿插入 USB 主機控制器上的中樞。 USB 中樞是 PnP 匯流排裝置,因為子裝置可以連接到它。
匯流排裝置的函式驅動程式會判斷新裝置在其匯流排上。
驅動程式如何判斷此情況取決於匯流排架構。 對於某些匯流排,匯流排函式驅動程式會收到新裝置的熱插即用通知。 如果匯流排不支援熱插即用通知,使用者必須在主控台中採取適當的動作,才能列舉公車。
在此範例中,USB 匯流排支援熱插即用通知,讓 USB 匯流排的函式驅動程式收到其子系已變更的通知。
匯流排裝置的函式驅動程式會通知 PnP 管理員其子裝置集已變更。
函式驅動程式會呼叫類型為BusRelations的IoInvalidateDeviceRelations,以通知 PnP 管理員。
PnP 管理員會查詢公車上目前裝置清單的公車驅動程式。
PnP 管理員會將 IRP_MN_QUERY_DEVICE_RELATIONS 要求傳送至匯流排的裝置堆疊。 Parameters.QueryDeviceRelations.Type值為BusRelations,表示 PnP 管理員要求目前存在於匯流排 (匯流排關聯) 上的裝置清單。
PnP 管理員會將 IRP 傳送至匯流排裝置堆疊中的頂端驅動程式。 根據 PnP IRP 的規則,堆疊中的每個驅動程式會適當地處理 IRP,並將 IRP 向下傳遞至下一個驅動程式。
匯流排裝置的函式驅動程式會處理 IRP。
如需處理此 IRP 的詳細資訊 ,請參閱IRP_MN_QUERY_DEVICE_RELATIONS 的參考頁面。
在此範例中,USB 中樞驅動程式會處理中樞 FDO的這個 IRP。 中樞驅動程式會為搖桿裝置建立 PDO ,並在其 IRP 傳回的子裝置清單中,包含搖桿 PDO 的參考指標。
當 USB 中樞的父匯流排驅動程式 (USB 主機控制器類別/迷你類別驅動程式配對) 完成 IRP 時,IRP 會透過中樞驅動程式所註冊的任何 IoCompletion 常式來備份裝置堆疊。
請注意,匯流排函式驅動程式會要求 PnP 管理員查詢其子裝置清單,以報告其子系列表中的變更。 所有匯流排裝置的驅動程式都會看到產生的 IRP_MN_QUERY_DEVICE_RELATIONS 要求。 一般而言,匯流排函式驅動程式是處理 IRP 和報告子系的唯一驅動程式。 在某些裝置堆疊中,有匯流排篩選驅動程式存在,並參與建構匯流排關聯清單。 其中一個範例是 ACPI,其會附加為 ACPI 裝置的匯流排篩選驅動程式。 在某些裝置堆疊中,非匯流排篩選驅動程式會處理 IRP_MN_QUERY_DEVICE_RELATIONS 要求,但這並不常見。
此時,PnP 管理員在公車上有目前的裝置清單。 接著,PnP 管理員會判斷任何裝置都剛抵達或已移除。 在此範例中,有一個新的裝置。 下圖顯示為新裝置建立開發節點並開始設定裝置的 PnP 管理員。
下列附注對應至上圖中的圓圈數位:
PnP 管理員會為匯流排上的任何新子裝置建立開發節點。
PnP 管理員會將 IRP_MN_QUERY_DEVICE_RELATIONS IRP 中傳回的匯流排關聯清單,與目前記錄在 PnP 裝置樹狀結構中的公車子系列表進行比較。 PnP 管理員會為每個新裝置建立 devnode,並起始已移除之任何裝置的移除處理。
在此範例中,有一個新的裝置 (搖桿) ,因此 PnP 管理員會為搖桿建立開發節點。 此時,為搖桿設定的唯一驅動程式是父 USB 中樞匯流排驅動程式,這會建立搖桿的 PDO。 任何選擇性匯流排篩選驅動程式也會出現在裝置堆疊中,但範例會省略匯流排篩選驅動程式,以求簡單起見。
上圖中兩個 devnode 之間的寬箭號表示搖桿 devnode 是 USB 中樞 devnode 的子系。
PnP 管理員會收集新裝置的相關資訊,並開始設定裝置。
PnP 管理員會將一連串的 IRP 傳送至裝置堆疊,以收集裝置的相關資訊。 此時,裝置堆疊只包含裝置父匯流排驅動程式所建立的 PDO,以及篩選任何選擇性匯流排篩選驅動程式的 DO。 因此,匯流排驅動程式和匯流排篩選驅動程式是唯一回應這些 IRP 的驅動程式。 在此範例中,搖桿裝置堆疊中唯一的驅動程式是父匯流排驅動程式 USB 中樞驅動程式。
PnP 管理員會藉由將 IRP 傳送至裝置堆疊來收集新裝置的相關資訊。 這些 IRP 包括下列各項:
IRP_MN_QUERY_ID,下列每種類型的硬體識別碼都會有個別的 IRP:
BusQueryDeviceID
BusQueryInstanceID
BusQueryHardwareIDs
BusQueryCompatibleIDs
BusQueryContainerID
IRP_MN_QUERY_DEVICE_TEXT,下列每個專案的個別 IRP:
DeviceTextDescription
DeviceTextLocationInformation
PnP 管理員會在處理新 PnP 裝置的這個階段傳送上面所列的 IRP,但不一定依照列出的順序,因此您不應該假設 IRP 的傳送順序。 此外,您不應該假設 PnP 管理員只會傳送上面所列的 IRP。
PnP 管理員會檢查登錄,以判斷裝置先前是否已安裝在這部電腦上。 PnP 管理員會 < 檢查Enum分支下裝置的列舉值> \ <deviceID> 子機碼。 在此範例中,裝置是新的裝置,而且必須設定「從頭開始」。
PnP 管理員會將裝置的相關資訊儲存在登錄中。
登錄的 Enum 分支會保留供作業系統元件使用,且其版面配置可能會變更。 驅動程式寫入器必須使用系統常式來擷取與驅動程式相關的資訊。 請勿直接從驅動程式存取 Enum 分支。 下列 列舉 資訊僅供偵錯之用。
PnP 管理員會在裝置列舉值的金鑰下,為裝置建立子機碼。
PnP 管理員會建立名為HKLM\System\CurrentControlSet\Enum\<enumerator>\<deviceID> 的子機碼。 如果列舉值> 子機碼不存在,它會建立 < 它。
列舉值是一個元件,會根據 PnP 硬體標準來探索 PnP 裝置。 列舉值的工作是由 PnP 匯流排驅動程式與 PnP 管理員合作執行。 裝置通常會由其父匯流排驅動程式列舉,例如 PCI 或 PCMCIA。 某些裝置會由匯流排篩選驅動程式列舉,例如 ACPI。
PnP 管理員會為此裝置實例建立子機碼。
如果Capabilities.UniqueID針對IRP_MN_QUERY_CAPABILITIES傳回為TRUE,則裝置的唯一識別碼在整個系統中是唯一的。 如果沒有,PnP 管理員會修改識別碼,使其是唯一的系統範圍。
PnP 管理員會建立名為HKLM\System\CurrentControlSet\Enum\<enumerator><\deviceID instanceID>>\< 的子機碼。
PnP 管理員會將裝置的相關資訊寫入裝置實例的子機碼。
如果裝置已提供,PnP 管理員會儲存資訊,包括下列資訊:
DeviceDesc — 從IRP_MN_QUERY_DEVICE_TEXT
位置 - 從 IRP_MN_QUERY_DEVICE_TEXT
功能- 來自IRP_MN_QUERY_CAPABILITIES的旗標
UINumber — 從 IRP_MN_QUERY_CAPABILITIES
HardwareID — 從IRP_MN_QUERY_ID
CompatibleIDs - 從 IRP_MN_QUERY_ID
ContainerID — 從 IRP_MN_QUERY_ID
LogConf\BootConfig — 從IRP_MN_QUERY_RESOURCES
LogConf\BasicConfigVector — 從IRP_MN_QUERY_RESOURCE_REQUIREMENTS
此時,PnP 管理員已準備好找出裝置的函式驅動程式和篩選驅動程式。如果有的話。 (請參閱下圖.)
下列附注對應至上圖中編號的圓形:
核心模式 PnP 管理員會與使用者模式 PnP 管理員和使用者模式安裝程式元件協調,以尋找裝置的函式和篩選驅動程式,如果有的話。
核心模式 PnP 管理員會將事件排入使用者模式 PnP 管理員,以識別需要安裝的裝置。 一旦有特殊許可權的使用者登入,使用者模式元件就會繼續尋找驅動程式。 如需安裝裝置元件及其角色的相關資訊,請參閱 裝置安裝概觀 。
使用者模式安裝程式元件會指示核心模式 PnP 管理員載入函式和篩選驅動程式。
使用者模式元件會回呼核心模式以載入驅動程式,導致呼叫其 AddDevice 常式。
下圖顯示如果適當的) 、呼叫其 AddDevice 常式,以及指示驅動程式啟動裝置,則載入驅動程式 (。
下列附注對應至上圖中編號的圓形:
較低篩選驅動程式
在函式驅動程式附加至裝置堆疊之前,PnP 管理員會處理任何較低篩選的驅動程式。 對於每個較低篩選驅動程式,如果驅動程式尚未載入,PnP 管理員會呼叫驅動程式的 DriverEntry 常式。 然後,PnP 管理員會呼叫驅動程式的 AddDevice 常式。 在 AddDevice 常式中,篩選驅動程式會建立篩選裝置物件 (篩選 DO) ,並將它連結至裝置堆疊 (IoAttachDeviceToDeviceStack) 。 一旦將裝置物件附加至裝置堆疊,驅動程式就會成為裝置的驅動程式。
在 USB 搖桿範例中,裝置有一個較低的篩選驅動程式。
函式驅動程式
附加任何較低的篩選之後,PnP 管理員會處理函式驅動程式。 如果驅動程式尚未載入,則 PnP 管理員會呼叫函式驅動程式的 DriverEntry 常式,並呼叫函式驅動程式的 AddDevice 常式。 函式驅動程式會在 FDO) (建立函式裝置物件,並將其連結至裝置堆疊。
在此範例中,USB 搖桿的函式驅動程式實際上是一對驅動程式:HID 類別驅動程式和 HID 迷你類別驅動程式。 這兩個驅動程式會一起運作,以作為函式驅動程式。 驅動程式組只會建立一個 FDO,並將它連結至裝置堆疊。
上方篩選驅動程式
附加函式驅動程式之後,PnP 管理員會處理任何上層篩選驅動程式。
在此範例中,裝置有一個上方篩選驅動程式。
指派資源並啟動裝置
PnP 管理員會視需要將資源指派給裝置,併發出 IRP 來啟動裝置。
指派資源
稍早在設定程式中,PnP 管理員會從裝置的父匯流排驅動程式收集裝置的硬體資源需求。 載入裝置的完整驅動程式集之後,PnP 管理員會將 IRP_MN_FILTER_RESOURCE_REQUIREMENTS 要求傳送至裝置堆疊。 堆疊中的所有驅動程式都有機會處理此 IRP,並視需要修改裝置的資源需求清單。
如果裝置需要任何資源,則 PnP 管理員會根據裝置的需求和目前可用的資源,將資源指派給裝置。
PnP 管理員可能需要重新排列現有裝置的資源指派,以滿足新裝置的需求。 此重新指派的資源稱為「重新平衡」。現有裝置的驅動程式會在重新平衡期間收到一連串的停止和啟動 IRP,但重新平衡對使用者而言必須透明。
在 USB 搖桿範例中,USB 裝置不需要硬體資源,因此 PnP 管理員會將資源清單設定為 Null。
啟動裝置 (IRP_MN_START_DEVICE)
一旦 PnP 管理員將資源指派給裝置,它會將 IRP_MN_START_DEVICE IRP 傳送至裝置堆疊,以指示驅動程式啟動裝置。
啟動裝置之後,PnP 管理員會將三個以上的 IRP 傳送給裝置的驅動程式:
-
啟動 IRP 成功完成之後,PnP 管理員會將另一個 IRP_MN_QUERY_CAPABILITIES IRP 傳送至裝置堆疊。 裝置的所有驅動程式都有處理 IRP 的選項。 PnP 管理員此時會在連結所有驅動程式並啟動裝置之後傳送此 IRP,因為函式或篩選驅動程式可能需要存取裝置以收集功能資訊。
-
例如,此 IRP 可讓驅動程式有機會回報裝置不應該顯示在使用者介面中,例如裝置管理員和 Hotplug 程式。 這適用于存在於系統上但無法用於目前設定的裝置,例如膝上型電腦取消模擬時無法使用的膝上型電腦遊戲連接埠。
匯流排關聯IRP_MN_QUERY_DEVICE_RELATIONS
PnP 管理員會傳送此 IRP 來判斷裝置是否有任何子裝置。 如果是,PnP 管理員會設定每個子裝置。
使用 GUID_PNP_LOCATION_INTERFACE
GUID_PNP_LOCATION_INTERFACE介面提供裝置的 SPDRP_LOCATION_PATHS 隨插即用 (PnP) 裝置屬性。
若要在驅動程式中實作此介面,請使用 InterfaceType = GUID_PNP_LOCATION_INTERFACE 處理IRP_MN_QUERY_INTERFACE IRP。 您的驅動程式會提供PNP_LOCATION_INTERFACE結構的指標,其中包含介面個別常式的指標。 PnpGetLocationString 常式提供裝置SPDRP_LOCATION_PATHS屬性的裝置特定部分。