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