將 IRP 傳遞至驅動程式堆疊

當驅動程式的分派例程收到 IRP 時,它必須呼叫 IoGetCurrentIrpStackLocation ,以便檢查自己的 I/O 堆棧位置,並判斷任何參數都有效。 如果驅動程式無法滿足並完成要求本身,它可以執行下列其中一項:

  • 將 IRP 傳遞至 ,以供較低層級驅動程式進一步處理。

  • 建立一或多個新的 IRP,並將其向下傳遞至較低層級的驅動程式。

較高層級的驅動程序應該將 I/O 要求傳遞至下一個較低的驅動程式,如下所示:

  1. 如果驅動程式會將輸入 IRP 傳遞給下一個較低層級驅動程式,分派例程應該呼叫 IoSkipCurrentIrpStackLocationIoCopyCurrentIrpStackLocationToNext ,以設定下一個較低驅動程式的 I/O 堆棧位置。

    如果驅動程式呼叫 IoAllocateIrp 為較低驅動程式配置一或多個額外的 IRP,則分派例程必須依照 處理 Intermediate-Level 驅動程式中的 IRP 中所述的步驟,初始化下一個較低驅動程式的 I/O 堆棧位置。

    分派例程可以針對特定要求修改下一個較低驅動程式 I/O 堆疊位置中的某些參數。 例如,當基礎裝置具有傳輸容量的已知限制時,較高層級的驅動程式可能會修改大型傳輸要求的參數,並重複使用 IRP 將部分傳輸要求傳送至基礎設備驅動器。

  2. 呼叫 IoSetCompletionRoutine

    如果分派例程將收到的 IRP 傳遞至下一個較低的驅動程式,則設定 IoCompletion 例程是選擇性的,但很有用,因為例程可以執行這類工作,例如判斷較低驅動程式已完成要求的方式、重複使用 IRP 進行部分傳輸、更新驅動程式追蹤 IRP 時所維護的任何狀態,以及重試傳回錯誤的要求。

    如果分派例程已配置新的 IRP,則需要設定 IoCompletion 例程,因為例程必須在較低驅動程式完成之後釋放每個 IRP。

    如需 IoCompletion 例程的詳細資訊,請參閱 完成IRP

  3. 呼叫 IoCallDriver ,讓每個 IRP 都由較低的驅動程序處理。

  4. 傳回適當的NTSTATUS值,例如:

    • STATUS_PENDING

      如果輸入 IRP 是異步要求,例如IRP_MJ_READ或IRP_MJ_WRITE,驅動程式通常會傳回STATUS_PENDING

    • 呼叫IoCallDriver的結果

      如果輸入 IRP 是同步要求,驅動程式通常會傳回 呼叫 IoCallDriver 的結果,例如 IRP_MJ_CREATE

最低層級設備驅動器會將它無法在分派例程中完成的任何 IRP 傳遞給其他驅動程式例程,如下所示:

  1. 使用輸入 IRP 呼叫 IoMarkIrpPending

  2. 呼叫 IoStartPacket 將IRP傳遞或排入佇列至驅動程式的 StartIo 例程,除非驅動程式管理自己的內部 IRP 佇列,如驅動程式管理的 IRP 佇列中所述。

    如果驅動程式沒有 StartIo 例程,但會處理可取消的 IRP,則必須註冊 Cancel 例程或實作 取消安全的 IRP 佇列。 如需 取消 例程的詳細資訊,請參閱 取消 IRP

  3. 傳回STATUS_PENDING。