將 IRP 傳遞至驅動程式堆疊
當驅動程式的分派例程收到 IRP 時,它必須呼叫 IoGetCurrentIrpStackLocation ,以便檢查自己的 I/O 堆棧位置,並判斷任何參數都有效。 如果驅動程式無法滿足並完成要求本身,它可以執行下列其中一項:
將 IRP 傳遞至 ,以供較低層級驅動程式進一步處理。
建立一或多個新的 IRP,並將其向下傳遞至較低層級的驅動程式。
較高層級的驅動程序應該將 I/O 要求傳遞至下一個較低的驅動程式,如下所示:
如果驅動程式會將輸入 IRP 傳遞給下一個較低層級驅動程式,分派例程應該呼叫 IoSkipCurrentIrpStackLocation 或 IoCopyCurrentIrpStackLocationToNext ,以設定下一個較低驅動程式的 I/O 堆棧位置。
如果驅動程式呼叫 IoAllocateIrp 為較低驅動程式配置一或多個額外的 IRP,則分派例程必須依照 處理 Intermediate-Level 驅動程式中的 IRP 中所述的步驟,初始化下一個較低驅動程式的 I/O 堆棧位置。
分派例程可以針對特定要求修改下一個較低驅動程式 I/O 堆疊位置中的某些參數。 例如,當基礎裝置具有傳輸容量的已知限制時,較高層級的驅動程式可能會修改大型傳輸要求的參數,並重複使用 IRP 將部分傳輸要求傳送至基礎設備驅動器。
-
如果分派例程將收到的 IRP 傳遞至下一個較低的驅動程式,則設定 IoCompletion 例程是選擇性的,但很有用,因為例程可以執行這類工作,例如判斷較低驅動程式已完成要求的方式、重複使用 IRP 進行部分傳輸、更新驅動程式追蹤 IRP 時所維護的任何狀態,以及重試傳回錯誤的要求。
如果分派例程已配置新的 IRP,則需要設定 IoCompletion 例程,因為例程必須在較低驅動程式完成之後釋放每個 IRP。
如需 IoCompletion 例程的詳細資訊,請參閱 完成IRP。
呼叫 IoCallDriver ,讓每個 IRP 都由較低的驅動程序處理。
傳回適當的NTSTATUS值,例如:
STATUS_PENDING
如果輸入 IRP 是異步要求,例如IRP_MJ_READ或IRP_MJ_WRITE,驅動程式通常會傳回STATUS_PENDING。
呼叫IoCallDriver的結果
如果輸入 IRP 是同步要求,驅動程式通常會傳回 呼叫 IoCallDriver 的結果,例如 IRP_MJ_CREATE。
最低層級設備驅動器會將它無法在分派例程中完成的任何 IRP 傳遞給其他驅動程式例程,如下所示:
使用輸入 IRP 呼叫 IoMarkIrpPending 。
呼叫 IoStartPacket 將IRP傳遞或排入佇列至驅動程式的 StartIo 例程,除非驅動程式管理自己的內部 IRP 佇列,如驅動程式管理的 IRP 佇列中所述。
如果驅動程式沒有 StartIo 例程,但會處理可取消的 IRP,則必須註冊 Cancel 例程或實作 取消安全的 IRP 佇列。 如需 取消 例程的詳細資訊,請參閱 取消 IRP。
傳回STATUS_PENDING。