如果驅動程式未使用緩衝處理或直接 I/O,則 I/O 管理員會在它傳送給驅動程式的 IRP 中傳遞原始使用者空間虛擬位址。 若要安全地存取這些緩衝區,驅動程式必須在呼叫線程的內容中執行。 因此,通常只有最高層級的驅動程式,例如 FSD,才能使用此方法來存取緩衝區。
中繼或最低層級驅動程式不一定符合此條件。 例如,如果要求線程在I/O要求完成時等候,或如果較高層級的驅動程式分層於中繼或最低層級驅動程式,則較低層級驅動程式的例程不太可能在要求線程的內容中呼叫。
I/O 管理員會判斷 I/O 作業不會使用緩衝處理或直接 I/O,如下所示:
針對 IRP_MJ_READ 和 IRP_MJ_WRITE 要求,DO_BUFFERED_IO和DO_DIRECT_IO都不會在 DEVICE_OBJECT 結構的 Flags 成員中設定。 如需詳細資訊,請參閱 初始化裝置物件。
對於 IRP_MJ_DEVICE_CONTROL 和 IRP_MJ_INTERNAL_DEVICE_CONTROL 要求,IOCTL 程式代碼的值會以IOCTL值中的 TransferType 值的形式包含METHOD_NEITHER。 如需詳細資訊,請參閱 定義 I/O 控制程式碼。
當驅動程式收到指定的 IRP,該 IRP 不使用緩衝處理或直接 I/O 來進行 I/O 作業時,它必須執行下列動作:
使用 ProbeForRead 和 ProbeForWrite 支援例程,檢查用戶緩衝區位址範圍的有效性,並檢查是否允許適當的讀取或寫入存取權。 驅動程式必須在驅動程式提供的例外狀況處理程式內,將緩衝區的位址範圍存取封入,如此一來,當驅動程式存取記憶體時,使用者線程便無法變更緩衝區的訪問許可權。 如果探查引發例外狀況,驅動程式應該會傳回錯誤。 驅動程式必須在發出 I/O 要求的線程內容中呼叫這些例程;因此,只有較高層級的驅動程式可以執行這項工作。
以下列其中一種方式管理緩衝區和記憶體作業:
實際上,驅動程式必須在每個 IRP 的基礎上選擇是否要在呼叫線程的內容中執行緩衝 I/O、直接 I/O 或 I/O,而且它必須處理使用者模式線程內容中可能發生的任何例外狀況。 驅動程式必須視需要管理自己的用戶緩衝區存取、雙緩衝作業和記憶體對應,而不是讓 I/O 管理員處理驅動程式的這些作業。