NtReadFile 函数
从打开的文件读取数据。
此函数是等效于 Windows 驱动程序工具包 (WDK) 中所述的 ZwReadFile 函数的用户模式。
语法
NTSTATUS NtReadFile(
_In_ HANDLE FileHandle,
_In_opt_ HANDLE Event,
_In_opt_ PIO_APC_ROUTINE ApcRoutine,
_In_opt_ PVOID ApcContext,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_Out_ PVOID Buffer,
_In_ ULONG Length,
_In_opt_ PLARGE_INTEGER ByteOffset,
_In_opt_ PULONG Key
);
参数
-
FileHandle [in]
-
文件对象的句柄。 此句柄是通过成功调用 NtCreateFile 或 NtOpenFile 创建的。
-
事件 [in, 可选]
-
(可选)事件对象的句柄,在读取操作完成后设置为信号状态。 设备和中间驱动程序应将此参数设置为 NULL。
-
ApcRoutine [in, 可选]
-
此参数为保留参数。 设备和中间驱动程序应将此指针设置为 NULL。
-
ApcContext [in, 可选]
-
此参数为保留参数。 设备和中间驱动程序应将此指针设置为 NULL。
-
IoStatusBlock [out]
-
指向 IO_STATUS_BLOCK 结构的指针,该结构接收最终完成状态和有关请求的读取操作的信息。 Information 成员接收实际从文件读取的字节数。
-
Buffer [out]
-
指向调用方分配的缓冲区的指针,该缓冲区接收从文件读取的数据。
-
长度 [in]
-
缓冲区指向的缓冲区的大小(以字节为单位)。
-
ByteOffset [in, 可选]
-
指向变量的指针,该变量指定将开始读取操作的文件中的起始字节偏移量。 如果尝试读取文件末尾以外的内容, 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 管理器维护的当前文件位置,则 NtReadFile 通过添加读取操作时读取的字节数来更新当前文件位置。
即使 I/O 管理器维护当前文件位置,调用方也可以通过将显式 ByteOffset 值传递给 NtReadFile 来重置此位置。 执行此操作会自动将当前文件位置更改为该 ByteOffset 值,执行读取操作,然后根据实际读取的字节数更新位置。 此方法为调用方提供原子查找和读取服务。
-
键 [in, 可选]
-
设备和中间驱动程序应将此指针设置为 NULL。
返回值
NtReadFile 返回STATUS_SUCCESS或相应的 NTSTATUS 错误代码。
备注
NtReadFile 的调用方必须已调用 NtCreateFile,并在 DesiredAccess 参数中设置了FILE_READ_DATA或GENERIC_READ值。
如果前面对 NtCreateFile 的调用将 CreateOptions 参数中的FILE_NO_INTERMEDIATE_BUFFERING标志设置为 NtCreateFile,则 NtReadFile 的 Length 和 ByteOffset 参数必须是扇区大小的倍数。 有关详细信息,请参阅 NtCreateFile。
NtReadFile 开始从给定的 ByteOffset 或当前文件位置读取到给定 缓冲区。 它会在下列条件之一下终止读取操作:
缓冲区已满,因为已读取 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 完成,则应在系统进程的上下文中调用,因为 APC 始终在发出 I/O 请求的线程上下文中触发。 如果驱动程序在非系统进程上下文中调用 NtReadFile ,则 APC 可能会无限期延迟,或者根本无法触发。
有关使用文件的详细信息,请参阅 在驱动程序中使用文件。
NtReadFile 的调用方必须在 IRQL = PASSIVE_LEVEL 运行,并且启用了特殊的内核 APC。
要求
要求 | 值 |
---|---|
最低受支持的客户端 |
Windows 2000 Professional [仅限桌面应用] |
最低受支持的服务器 |
Windows 2000 Server [仅限桌面应用] |
目标平台 |
|
标头 |
|
库 |
|
DLL |
|
另请参阅