ZwReadFile 函式 (wdm.h)
ZwReadFile 例程會從開啟的檔案讀取數據。
語法
NTSYSAPI NTSTATUS ZwReadFile(
[in] HANDLE FileHandle,
[in, optional] HANDLE Event,
[in, optional] PIO_APC_ROUTINE ApcRoutine,
[in, optional] PVOID ApcContext,
[out] PIO_STATUS_BLOCK IoStatusBlock,
[out] PVOID Buffer,
[in] ULONG Length,
[in, optional] PLARGE_INTEGER ByteOffset,
[in, optional] PULONG Key
);
參數
[in] FileHandle
檔案物件的句柄。 此句柄是由 成功呼叫 ZwCreateFile 或 ZwOpenFile 所建立。
[in, optional] Event
選擇性地,當讀取作業完成之後,事件物件的句柄會設定為已發出訊號的狀態。 裝置和中繼驅動程式應將此參數設定為 NULL。
[in, optional] ApcRoutine
此參數已保留備用。 裝置和中繼驅動程序應該將此指標設定為 NULL。
[in, optional] ApcContext
此參數已保留備用。 裝置和中繼驅動程序應該將此指標設定為 NULL。
[out] IoStatusBlock
接收最終完成狀態和所要求讀取作業相關信息 之IO_STATUS_BLOCK 結構的指標。 Information 成員會接收實際從檔案讀取的位元元組數目。
[out] Buffer
呼叫端配置的緩衝區指標,該緩衝區會接收從檔案讀取的數據。
[in] Length
Buffer 所指向緩衝區的大小,以位元組為單位。
[in, optional] ByteOffset
變數的指標,指定讀取作業開始所在檔案中的起始位移。 如果嘗試讀取超過檔案結尾, ZwReadFile 會傳回錯誤。
如果呼叫 ZwCreateFile 設定 了 CreateOptions 旗標FILE_SYNCHRONOUS_IO_ALERT或FILE_SYNCHRONOUS_IO_NONALERT,I/O 管理員會維護目前的檔案位置。 如果是的話, ZwReadFile 的呼叫端可以指定使用目前的檔案位置位移,而不是明確的 ByteOffset 值。 您可以使用下列其中一種方法來建立此規格:
指定LARGE_INTEGER值的指標, 並將 HighPart 成員設定為 -1, 並將 LowPart 成員設定為系統定義的值FILE_USE_FILE_POINTER_POSITION。
傳遞 ByteOffset 的 NULL 指標。
如果 ZwReadFile 使用 I/O 管理員所維護的目前檔案位置,則新增完成讀取作業時所讀取的位元組數目,以更新目前的檔案位置。
即使 I/O 管理員維護目前的檔案位置,呼叫端還是可以將明確的 ByteOffset 值傳遞至 ZwReadFile 來重設此位置。 這麼做會自動將目前的檔案位置變更為該 ByteOffset 值、執行讀取作業,然後根據實際讀取的位元組數目更新位置。 這項技術會為呼叫端提供不可部分完成的搜尋和讀取服務。
[in, optional] Key
裝置和中繼驅動程序應該將此指標設定為 NULL。
傳回值
ZwReadFile 會傳回STATUS_SUCCESS或適當的NTSTATUS錯誤碼。
備註
ZwReadFile 的呼叫端必須已經呼叫 ZwCreateFile,並在 DesiredAccess 參數中設定FILE_READ_DATA或GENERIC_READ值。
如果上述對 ZwCreateFile 的呼叫將 CreateOptions 參數中的 FILE_NO_INTERMEDIATE_BUFFERING 旗標設定為 ZwCreateFile,則 Length 和 ByteOffset 參數必須是扇區大小的倍數。 如需詳細資訊,請參閱 ZwCreateFile。
ZwReadFile 會從指定的 ByteOffset 或目前檔案位置開始讀取指定的 Buffer。 它會在下列其中一個情況下終止讀取作業:
緩衝區已滿,因為已讀取 Length 參數指定的位元元組數目。 因此,在沒有溢位的情況下,無法再將數據放入緩衝區。
讀取作業期間會到達檔案結尾,因此檔案中沒有其他數據要傳送到緩衝區。
如果呼叫端以 DesiredAccess 中設定的 SYNCHRONIZE 旗標開啟檔案,則呼叫線程可以等候檔句柄 FileHandle 同步至讀取作業完成。 每次在句柄上發出的 I/O 作業完成時,都會發出句柄的訊號。 不過,呼叫端不得等候開啟以進行同步檔案存取的句柄, (FILE_SYNCHRONOUS_IO_NONALERT 或FILE_SYNCHRONOUS_IO_ALERT) 。 在此情況下, ZwReadFile 會代表呼叫端等候,而且在讀取作業完成之前不會傳回。 只有在符合下列三個條件時,呼叫端才能安全地等候檔句柄:
已針對異步存取開啟句柄 (也就是說,FILE_SYNCHRONOUS_IO_XXX 旗標都未指定) 。
句柄一次只能用於一個 I/O 作業。
ZwReadFile 傳回STATUS_PENDING。
如果下列任何條件存在,驅動程式應該在系統進程的內容中呼叫 ZwReadFile :
驅動程式已建立傳遞給 ZwReadFile 的檔案句柄。
ZwReadFile 會透過驅動程式所建立的事件通知驅動程式 I/O 完成。
ZwReadFile 會透過驅動程序傳遞至 ZwReadFile 的 APC 回呼例程,通知驅動程式 I/O 完成。
檔案和事件句柄只有在建立句柄的進程內容中才有效。 因此,若要避免安全漏洞,驅動程式應該建立任何檔案或事件句柄,以在系統進程的內容中傳遞至 ZwReadFile ,而不是驅動程式所在的進程內容。
同樣地,如果 ZwReadFile 透過 APC 通知驅動程式 I/O 完成,則應該在系統進程的內容中呼叫 ZwReadFile ,因為 APC 一律會在發出 I/O 要求的線程內容中引發。 如果驅動程式在系統以外的進程內容中呼叫 ZwReadFile,APC 可能會無限期延遲,或完全不會引發。
如需使用檔案的詳細資訊,請參閱 在驅動程式中使用檔案。
ZwReadFile 的呼叫端必須在 IRQL = PASSIVE_LEVEL,且已啟用特殊核心 APC。
如果在使用者模式中呼叫此函式,您應該使用名稱 「NtReadFile」 而不是 「ZwReadFile」。
規格需求
需求 | 值 |
---|---|
目標平台 | Universal |
標頭 | wdm.h (包括 Wdm.h、Ntddk.h、Ntifs.h) |
程式庫 | NtosKrnl.lib |
Dll | NtosKrnl.exe |
IRQL | PASSIVE_LEVEL (请参阅一节) |
DDI 合規性規則 | BufAfterReqCompletedIntIoctlA (kmdf) 、 BufAfterReqCompletedIoctlA (kmdf) 、 BufAfterReqCompletedReadA (kmdf) (、 BufAfterReqCompletedWriteA (kmdf) 、 HwStorPortProhibitedDDIs (storport) 、 PowerIrpDDis (wdm) |