共用方式為


撰寫 DPC 常式

DpcForIsrCustomDpc常式的主要責任是確保下一個裝置 I/O 作業會立即啟動,並完成目前的 IRP。

任何 DpcForIsrCustomDpc 常式所完成的額外工作取決於驅動程式的設計和裝置本質。 例如, DpcForIsrCustomDpc 常式也可以執行下列任一動作:

  • 重試逾時或失敗的作業。

  • 呼叫 IoAllocateErrorLogEntry、設定錯誤記錄封包來報告裝置 I/O 錯誤,以及呼叫 IoWriteErrorLogEntry

    如需處理 I/O 錯誤的詳細資訊,請參閱 記錄錯誤

  • 如果驅動程式使用 緩衝 I/O,或 IRP 指定裝置控制作業,請在完成 IRP 之前,將讀取的資料從裝置傳輸到 Irp-AssociatedIrp.SystemBuffer > 的系統緩衝區。

  • 如果驅動程式使用 直接 I/O ,而且必須將大型傳輸分成較小的片段、儲存每個剛完成的部分傳輸作業的狀態、計算下一個部分傳輸範圍,並使用驅動程式提供的 SynchCritSection 常式來為裝置進行下一個部分傳輸作業的程式。

    即使使用緩衝 I/O 的驅動程式,如果裝置的傳輸功能有限,可能必須分割傳輸要求。

  • 如果驅動程式使用封包型 DMA,請在每個裝置傳輸作業之後呼叫 FlushAdapterBuffers ,並在完成部分傳輸且滿足完整傳輸要求時呼叫 FreeAdapterChannelFreeMapRegisters

    如果要求的傳輸只由單一 DMA 作業部分滿足, DpcForIsrCustomDpc 常式通常負責設定一或多個 DMA 作業,直到 IRP 的指定位元組數目完全傳輸為止。

    如需使用 DMA 的詳細資訊,請參閱 配接器物件和 DMA

  • 如果驅動程式使用程式化 I/O (PIO) ,則如果目前的 IRP 要求讀取,請在每個傳輸作業結束時呼叫 KeFlushIoBuffers

    如果要求的傳輸只由單一 PIO 作業部分滿足, DpcForIsrCustomDpc 常式通常負責設定一或多個傳輸作業,直到 IRP 的指定位元組數目完全傳輸為止。

    如需使用 PIO 的詳細資訊,請參閱 使用直接 I/O

  • 如果非 WDM 驅動程式有 ControllerControl 常式,請在要求的作業完成時呼叫 IoFreeController

請注意, DpcForIsrCustomDpc 常式通常會執行大部分驅動程式的裝置 I/O 處理,以滿足 IRP。 這些常式也會與驅動程式的分派常式共用將 IRP 排入裝置的一些責任。

請考慮下列一般設計指導方針。

  • 任何 DpcForIsrCustomDpc 常式都應該在可以安全地進行此呼叫時立即呼叫 IoStartNextPacket :也就是說,這不會造成驅動程式 的 StartIo 常式或與 StartIo 常式造成任何其他常式的資源衝突或競爭狀況,或是 StartIo 常式導致執行的任何其他常式。

  • 如果驅動程式管理自己的 IRP 佇列,則其 DpcForIsrCustomDpc 常式應該會在驅動程式安全清除下一個 IRP 並設定裝置以進行下一個要求時立即通知驅動程式。

當可以啟動下一個要求的裝置 I/O 處理時, DpcForIsrCustomDpc 常式必須呼叫 IoStartNextPacket,否則會通知適當的驅動程式常式。 視驅動程式及其裝置而定,這可能會在 DpcForIsrCustomDpc 常式使用 IoCompleteRequest完成目前的 IRP 之前發生,或者可以在此常式完成目前的 IRP 並傳回控制項之前立即發生。