使用未緩衝處理或直接 I/O
如果驅動程式未使用緩衝處理或直接 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成員中設定。 如需詳細資訊,請參閱 初始化 Device 物件。
對於 IRP_MJ_DEVICE_CONTROL 和 IRP_MJ_INTERNAL_DEVICE_CONTROL 要求,IOCTL 程式碼的值包含 METHOD_NEITHER 作為 IOCTL 值中的 TransferType 值。 如需詳細資訊,請參閱 定義 I/O 控制程式碼。
當驅動程式收到 IRP,該 IRP 指定未使用緩衝處理或直接 I/O 的 I/O 作業時,它必須執行下列動作:
使用 ProbeForRead 和 ProbeForWrite 支援常式,檢查使用者緩衝區的位址範圍是否有效,並檢查是否允許適當的讀取或寫入存取權。 驅動程式必須在驅動程式提供的例外狀況處理常式內封入緩衝區位址範圍的存取權,如此一來,在驅動程式存取記憶體時,使用者執行緒便無法變更緩衝區的存取權限。 如果探查引發例外狀況,驅動程式應該會傳回錯誤。 驅動程式必須在發出 I/O 要求的執行緒內容中呼叫這些常式;因此,只有較高層級的驅動程式可以執行這項工作。
以下列其中一種方式管理緩衝區和記憶體作業:
實際上,驅動程式必須根據每個 IRP 選擇是否要在呼叫執行緒的內容中執行緩衝 I/O、直接 I/O 或 I/O,而且必須處理使用者模式執行緒內容中可能發生的任何例外狀況。 驅動程式必須視需要管理自己的使用者緩衝區存取、雙緩衝作業和記憶體對應,而不是讓 I/O 管理員處理驅動程式的這些作業。