共用方式為


在匯流排驅動程式中移除裝置

當移除子裝置(子 PDO)時,父總線驅動程式必須撤銷先前為了新增及啟動該裝置所執行的所有操作。

總線驅動程式會移除子裝置,其 DispatchPnP 例程中的程式如下:

  1. 驅動程式是否已處理此 PDO 的先前 IRP_MN_SURPRISE_REMOVAL 要求?

    如果是,執行所有剩餘的清理,並跳至步驟 4。

    驅動程式通常會在裝置擴展中維護一個旗標,以指示驅動程式是否已經處理過該裝置的 IRP_MN_SURPRISE_REMOVAL 請求。

  2. 完成驅動程式中佇列的任何要求。

  3. 如果總線驅動程式能夠這麼做,請從裝置移除電源,並呼叫 PoSetPowerState來通知電源管理員。

    如果可能,總線驅動程式會關閉子裝置電源,並通知電源管理員裝置電源狀態的變更。 巴士司機會執行這項作業,以回應 IRP_MN_REMOVE_DEVICE 要求;裝置的電源原則擁有者不會在移除裝置時傳送 IRP_MN_SET_POWER 要求。 如需詳細資訊,請參閱 電源管理

  4. 如果總線驅動程式在最近回應 BusRelationsIRP_MN_QUERY_DEVICE_RELATIONS 要求時回報此裝置,則該裝置仍存在於計算機上。 在此情況下,公交車司機:

    • 裝置的 PDO 將被保留,直到裝置實際被移除。

    • Irp->IoStatus.Status 設定為 STATUS_SUCCESS。

    • 使用 IoCompleteRequest完成 IRP。

    • DispatchPnP 例程返回。

    在實際移除裝置之前,總線驅動程式必須在後續列舉中繼續報告此裝置(IRP_MN_QUERY_DEVICE_RELATIONSBusRelations)。 PnP 管理員會追蹤是否已新增和啟動列舉裝置。

  5. 如果裝置未包含在總線驅動程式最近回應 BusRelationsIRP_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。 在此情況下,儘管總線驅動程式已經先前呼叫了 IoDeleteDevice,但由於某些元件仍然持有對該物件的參考,裝置的 PDO 仍未被刪除。 因此,總線驅動程式可以在處理第二個移除 IRP 時存取 PDO。 公交車司機不得第二次呼叫 IoDeleteDevice PDO;當 PDO 的參考計數達到零時,I/O 系統就會刪除 PDO。

在收到裝置 IRP_MN_REMOVE_DEVICE 要求之前,總線驅動程式不會移除其子裝置的數據結構。 總線驅動程式可能會偵測到裝置已移除,並呼叫 IoInvalidateDeviceRelations,但在 PnP 管理員傳送 IRP_MN_REMOVE_DEVICE 要求之前,它不得刪除裝置的 PDO。