將 PnP IRP 傳遞至裝置堆疊
PnP 管理員會使用 IRP 指示驅動程式啟動、停止和移除裝置,以及查詢驅動程式的相關裝置。 所有 PnP IRP 都有主要函式程式碼 IRP_MJ_PNP,而且所有 PnP 驅動程式都必須提供 DispatchPnP 常式來服務此函式程式碼。 PnP 管理員會在傳送 IRP 時,將 Irp-IoStatus.Status > 初始化為STATUS_NOT_SUPPORTED。 如需詳細資訊,請參閱 DispatchPnP 常式。
如需 PnP 次要 IRP 的清單,請參閱隨插即用次要 IRP。
裝置的所有驅動程式都必須有機會回應 PnP IRP,除非堆疊中的驅動程式失敗 IRP。 (請參閱下圖.)
裝置沒有單一驅動程式可以假設它是回應 PnP IRP 的唯一驅動程式。 例如,假設函式驅動程式會回應 IRP_MN_QUERY_CAPABILITIES 要求並完成 IRP,而不需將它傳遞至下一個較低的驅動程式。 不會報告較低驅動程式所支援的功能,例如父匯流排驅動程式所支援的唯一實例識別碼或電源管理功能。
當父匯流排驅動程式呼叫 IoCompleteRequest 時,PnP IRP 會移動備份裝置堆疊,而 I/O 管理員會呼叫函式驅動程式或篩選驅動程式註冊的任何 IoCompletion 常式。
函式或篩選驅動程式在收到 PnP IRP 時必須執行下列動作:
- 如果驅動程式執行動作以回應 IRP:
- 執行適當的動作。
- 將 Irp-IoStatus.Status > 設定為適當的狀態,例如STATUS_SUCCESS。 如果適用于 IRP,請設定 Irp-IoStatus.Information >。
- 使用 IoSkipCurrentIrpStackLocation 或 IoCopyCurrentIrpStackLocationToNext設定下一個堆疊位置。 如果您設定 IoCompletion 常式,請呼叫後者常式。
- 視需要設定 IoCompletion 常式。
- 請勿完成 IRP。 (請勿呼叫 IoCompleteRequest.) 父匯流排驅動程式將會完成 IRP。
- 如果驅動程式未執行此 IRP 的動作,它只會準備將 IRP 傳遞至下一個驅動程式:
- 呼叫 IoSkipCurrentIrpStackLocation ,從 IRP 移除其堆疊位置。
- 請勿在 Irp-IoStatus >中設定任何欄位。
- 請勿設定 IoCompletion 常式。
- 請勿完成 IRP。 (請勿呼叫 IoCompleteRequest.) 父匯流排驅動程式將會完成 IRP。
如果函式或篩選驅動程式未失敗 IRP,它會使用 IoCallDriver將 IRP 傳遞至下一個較低的驅動程式。 驅動程式具有下一個較低驅動程式的指標;該指標是從較高驅動程式AddDevice常式中的IoAttachDeviceToDeviceStack呼叫傳回。
父匯流排驅動程式在執行任何工作以回應 IRP 之後完成 IRP。 在匯流排驅動程式呼叫 IoCompleteRequest之後,I/O 管理員會呼叫由函式或篩選裝置驅動程式註冊的任何 IoCompletion 常式。