Share via


將 IRP 分派至 I/O 佇列

[適用于 KMDF 和 UMDF]

架構型驅動程式可以動態指定傳入 IRP 的目標佇列。 若要將 IRP 分派至特定佇列,驅動程式必須呼叫 WdfDeviceWdmDispatchIrpToIoQueue 方法。

一般而言,驅動程式會從其EvtDeviceWdmIrpPreprocessEvtDeviceWdmIrpIrpDispatch回呼函式呼叫WdfDeviceWdmDispatchToIoQueue。 為了獲得最佳效能,大部分驅動程式都不提供這兩個回呼函式。

注意 UMDF 驅動程式可以提供 EvtDeviceWdmIrpDispatch 回呼函式,但只有 KMDF 驅動程式可以提供 EvtDeviceWdmIrpPreprocess

如果您的驅動程式已經提供 EvtDeviceWdmIrpPreprocess,您可以使用它來動態選取佇列。 如果沒有,請提供 EvtDeviceWdmIrpDispatch ,並從該回呼函式內呼叫 WdfDeviceWdmDispatchIrpToIoQueue

此外,您應該注意下列事項:

分派非預處理器的 IRP

若要從驅動程式的 EvtDeviceWdmIrpDispatch 回呼函式分派 IRP,請使用下列程式:

  1. 其 EvtDriverDeviceAdd 回呼函式中,驅動程式會呼叫 WdfDeviceConfigureWdmIrpDispatchCallback 來註冊 EvtDeviceWdmIrpDispatch 回呼函式。

    如果目標是父裝置的 I/O 佇列,KMDF 驅動程式必須先呼叫 WdfPdoInitAllowForwardingRequestToParent ,才能呼叫 WdfDeviceCreate。 如果 KMDF 驅動程式也提供 EvtDeviceWdmIrpPreprocess 回呼函式,架構會在 IRP 送達時先呼叫該函式。 在回呼函式預先處理要求之後,它會呼叫 WdfDeviceWdmDispatchPreprocessedIrp ,以將 IRP 傳回至架構。

  2. 架構會呼叫驅動程式的 EvtDeviceWdmIrpDispatch 回呼函式。

  3. EvtDeviceWdmIrpDispatch內,驅動程式可以呼叫 WdfDeviceWdmDispatchIrpToIoQueueWdfDeviceWdmDispatchIrp,但不能同時呼叫這兩者。 KMDF 驅動程式有其他選項可以呼叫這兩種方法,而是完成 IRP 或將其標示為擱置中。

  4. 如果 KMDF 驅動程式已設定WDF_DISPATCH_IRP_TO_IO_QUEUE_INVOKE_INCALLERCTX_CALLBACK旗標,而且未針對目標 I/O 佇列啟用保證的向前進度,則架構會呼叫驅動程式的 EvtIoInCallerCoNtext,如果提供的話。 前置處理要求之後,回呼函式必須藉由呼叫 WdfDeviceEnqueueRequest 將它排入佇列,或藉由呼叫 WdfRequestComplete來完成它。

分派前置處理 IRP

若要將 IRP 從驅動程式的 EvtDeviceWdmIrpPreprocess 回呼函式分派至特定的 I/O 佇列,請使用下列程式:

  1. 驅動程式會藉由呼叫WdfDeviceInitAssignWdmIrpPreprocessCallback來註冊EvtDeviceWdmIrpPreprocessWdmPreprocess函式。
  2. 如果目標是父裝置的 I/O 佇列,驅動程式 會呼叫 WdfPdoInitAllowForwardingRequestToParent
  3. EvtDeviceWdmIrpPreprocess呼叫 WdfDeviceWdmDispatchIrpToIoQueue並將 Flags 設定為 WDF_DISPATCH_IRP_TO_IO_QUEUE_PREPROCESSED_IRP。
  4. 如果驅動程式已設定WDF_DISPATCH_IRP_TO_IO_QUEUE_INVOKE_INCALLERCTX_CALLBACK旗標,而且未針對目標 I/O 佇列啟用保證的向前進度,則架構會呼叫驅動程式的 EvtIoInCallerCoNtext。如果提供的話。 在回呼函式完成前置處理要求之後,它必須藉由呼叫 WdfDeviceEnqueueRequest 將它排入佇列,或藉由呼叫 WdfRequestComplete來完成它。