移除匯流排驅動程式中的裝置
移除子裝置 (子 PDO) 時,父匯流排驅動程式必須復原其執行的任何作業,才能新增和啟動裝置。
匯流排驅動程式會移除子裝置及其 DispatchPnP 常式中的下列程式:
驅動程式是否已處理此 PDO 的先前 IRP_MN_SURPRISE_REMOVAL 要求?
如果是,請執行任何剩餘的清除,並跳至步驟 4。
驅動程式通常會維護裝置擴充功能中的旗標,指出驅動程式是否已處理裝置 的IRP_MN_SURPRISE_REMOVAL 要求。
完成驅動程式中已排入佇列的任何要求。
如果匯流排驅動程式能夠這麼做,請從裝置移除電源,並藉由呼叫 PoSetPowerState通知電源管理員。
如果可能,匯流排驅動程式會關閉子裝置電源,並通知電源管理員裝置的電源狀態變更。 匯流排驅動程式會執行這項作業,以回應 IRP_MN_REMOVE_DEVICE 要求;裝置的電源原則擁有者不會在移除裝置時傳送 IRP_MN_SET_POWER 要求。 如需詳細資訊,請參閱 電源管理。
如果匯流排驅動程式在最近回應BusRelations的IRP_MN_QUERY_DEVICE_RELATIONS要求中回報此裝置,裝置仍實際存在於電腦上。 在此情況下,匯流排驅動程式:
保留裝置的 PDO,直到實際移除裝置為止。
將 Irp-IoStatus.Status > 設定為 STATUS_SUCCESS。
使用 IoCompleteRequest完成 IRP。
從 DispatchPnP 常式傳回。
匯流排驅動程式必須在後續的列舉中繼續報告此裝置, (IRP_MN_QUERY_DEVICE_RELATIONS BusRelations) ,直到實際移除裝置為止。 PnP 管理員會持續追蹤是否已新增和啟動列舉裝置。
如果匯流排驅動程式最近對BusRelations的IRP_MN_QUERY_DEVICE_RELATIONS要求沒有包含裝置,則匯流排驅動程式會將裝置視為實際從機器中移除。 在此情況下,匯流排驅動程式會執行下列動作:
清除裝置特定的配置、記憶體、事件等等。
將 Irp-IoStatus.Status > 設定為 STATUS_SUCCESS。
使用 IoCompleteRequest完成 IRP。
使用 IoDeleteDevice釋放 PDO。
如果驅動程式從最近的 BusRelations 清單中省略裝置,則匯流排驅動程式必須刪除 PDO。 如果使用者再次將裝置插入電腦,匯流排驅動程式必須建立新的 PDO,以回應下一個 BusRelations 查詢。 如果匯流排驅動程式針對裝置的新實例重複使用相同的 PDO,電腦將無法正常運作。
從 DispatchPnP 常式傳回。
如果 PnP 管理員傳送 IRP_MN_REMOVE_DEVICE 要求時仍存在裝置,則匯流排驅動程式會保留 PDO。 如果稍後從匯流排實際移除裝置,PnP 管理員會傳送另一個 IRP_MN_REMOVE_DEVICE。 收到後續移除 IRP 之後,匯流排驅動程式會刪除裝置的 PDO。
匯流排驅動程式必須能夠處理其已移除之裝置 的IRP_MN_REMOVE_DEVICE ,以及其 PDO 標示為要刪除。 為了回應這類 IRP,匯流排驅動程式可以成功 IRP 或傳回STATUS_NO_SUCH_DEVICE。 此案例中尚未刪除裝置的 PDO,儘管匯流排驅動程式先前呼叫 IoDeleteDevice,因為某些元件仍然具有 物件的參考。 因此,匯流排驅動程式可以在處理第二個移除 IRP 時存取 PDO。 匯流排驅動程式不得第二次呼叫 PDO 的 IoDeleteDevice ;當 PDO 的參考計數達到零時,I/O 系統會刪除 PDO。
在收到裝置 IRP_MN_REMOVE_DEVICE 要求之前,匯流排驅動程式不會移除子裝置的資料結構。 匯流排驅動程式可能會偵測到裝置已移除並呼叫 IoInvalidateDeviceRelations,但除非 PnP 管理員傳送 IRP_MN_REMOVE_DEVICE 要求,否則它不得刪除裝置的 PDO。