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

檔案物件的句柄。 此句柄是由 成功呼叫 NtCreateFileNtOpenFile 所建立。

[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則 LengthByteOffset 參數必須是扇區大小的倍數。

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 原生系統服務例程的 NtXxxZwXxx 版本會以處理和解譯輸入參數的方式,以不同的方式運作。 如需 例程 NtXxxZwXxx 版本之間關聯性的詳細資訊,請參閱 使用原生系統服務例程的 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

另請參閱

KeInitializeEvent

ZwCreateFile

NtQueryInformationFile

NtSetInformationFile

NtWriteFile