NtWriteFile 函数 (ntifs.h)

ZwWriteFile 例程将数据写入打开的文件。

Syntax

__kernel_entry NTSYSCALLAPI NTSTATUS NtWriteFile(
  [in]           HANDLE           FileHandle,
  [in, optional] HANDLE           Event,
  [in, optional] PIO_APC_ROUTINE  ApcRoutine,
  [in, optional] PVOID            ApcContext,
  [out]          PIO_STATUS_BLOCK IoStatusBlock,
  [in]           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 结构的指针,该结构接收最终完成状态以及有关请求的写入作的信息。 信息成员接收实际写入文件的字节数。

[in] Buffer

指向调用方分配的缓冲区的指针,该缓冲区包含要写入文件的数据。

[in] Length

缓冲区所指向的缓冲区的大小(以字节为单位)。

[in, optional] ByteOffset

指向一个变量的指针,该变量指定文件中用于开始写入作的起始字节偏移量。 如果 LengthByteOffset 指定超过当前文件结束标记的写入作, 则 NtWriteFile 会自动扩展文件并更新文件结束标记;在此类旧文件标记和新的文件结束标记之间未显式写入的任何字节定义为零。

如果对 NtCreateFile 的调用仅设置 DesiredAccess 标志FILE_APPEND_DATA,则忽略 ByteOffset 。 给定 缓冲区中的数据 (长度字节 )从文件的当前末尾开始写入。

如果对 NtCreateFile 的调用设置了 CreateOptions 标志、FILE_SYNCHRONOUS_IO_ALERT或FILE_SYNCHRONOUS_IO_NONALERT,I/O 管理器将保留当前文件位置。 如果是这样, 则 NtWriteFile 的调用方可以指定使用当前文件位置偏移量,而不是显式 ByteOffset 值。 可以使用以下方法之一来制定此规范:

  • 指定指向 highPart 成员设置为 -1 且 LowPart 成员设置为系统定义值FILE_USE_FILE_POINTER_POSITION LARGE_INTEGER值的指针。
  • 传递 ByteOffset 的 NULL 指针。

如果 NtWriteFile 使用 I/O 管理器维护的当前文件位置,则通过添加写入作时写入的字节数来更新当前文件位置。

即使 I/O 管理器维护当前文件位置,调用方也可以通过将显式 ByteOffset 值传递给 NtWriteFile 来重置此位置。 执行此作会自动将当前文件位置更改为该 ByteOffset 值,执行写入作,然后根据实际写入的字节数更新位置。 此方法为调用方提供原子查找和写入服务。

还可以通过为 ByteOffset 指定指向 highPart 设置为 -1 且 LowPart 设置为FILE_WRITE_TO_END_OF_FILE的LARGE_INTEGER值的指针,使写入作在文件的当前末尾启动。 无论 I/O 管理器是否维护当前文件位置,这都有效。

[in, optional] Key

设备和中间驱动程序应将此指针设置为 NULL。

返回值

NtWriteFile 在成功或失败时返回相应的 NTSTATUS 错误代码STATUS_SUCCESS。

注解

NtWriteFile 的调用方必须已使用 DesiredAccess 参数中设置的 FILE_WRITE_DATA、FILE_APPEND_DATA 或 GENERIC_WRITE 标志调用 NtCreateFile。 请注意,只有对文件的FILE_APPEND_DATA访问权限不允许调用方在文件中的任意位置写入文件,但对文件的FILE_WRITE_DATA访问权限不会阻止调用方在文件末尾写入或超出文件的末尾。

如果上述对 NtCreateFile 的调用FILE_NO_INTERMEDIATE_BUFFERING设置 CreateOptions 标志,则 LengthByteOffset参数必须是扇 区大小的整型。 有关详细信息,请参阅 NtCreateFile

NtWriteFileByteOffset、当前文件位置或文件末尾标记处开始对文件的写入作。 当写入缓冲区中的长度字节时,它会终止写入作。 如有必要,它会扩展文件的长度并重置文件结束标记。

如果调用方打开了设置了 DesiredAccess SYNCHRONIZE 标志的文件,则调用方可以等待此例程将给定 的 FileHandle 设置为信号状态。

在三种情况下,驱动程序应在系统进程的上下文中调用 NtWriteFile

  • 驱动程序创建传递给 NtWriteFile 的文件句柄。
  • NtWriteFile 通过驱动程序创建的事件通知 I/O 完成的驱动程序。
  • NtWriteFile 通过 APC 回调例程向 NtWriteFile 传递的 APC 回调例程通知 I/O 完成的驱动程序。

文件和事件句柄仅在创建句柄的进程上下文中有效。 因此,为了避免安全漏洞,驱动程序应创建在系统进程的上下文中传递给 NtWriteFile 的任何文件或事件句柄,而不是驱动程序所处的进程上下文。

同样,如果 NtWriteFile 通过 APC 通知 I/O 完成的驱动程序,则应在系统进程的上下文中调用 NtWriteFile,因为 APC 始终在发出 I/O 请求的线程上下文中触发。 如果驱动程序在系统进程以外的进程上下文中调用 NtWriteFile,APC 可能会无限期延迟,或者根本无法触发,因为发起线程可能永远不会进入可警报的等待状态。

有关使用文件的详细信息,请参阅 在驱动程序中使用文件

NtWriteFile 的调用方必须在 IRQL = PASSIVE_LEVEL且启用了特殊内核 APC 的情况下运行。

如果在用户模式下调用此函数,则应使用名称“NtWriteFile”而不是“ZwWriteFile”。

对于内核模式驱动程序的调用,NtXxxZwXxx 版本的 Windows 本机系统服务例程的行为方式可能以不同的方式处理和解释输入参数。 有关 NtXxxZwXxx 例程之间的关系的详细信息,请参阅 使用 Nt 和 Zw 版本的本机系统服务例程

要求

Requirement 价值
最低支持的客户端 Windows 2000
目标平台 普遍
Header ntifs.h (包括 Wdm.h、Ntddk.h、Ntifs.h)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL PASSIVE_LEVEL(请参阅“备注”部分)
DDI 符合性规则 HwStorPortProhibitedDDI、PowerIrpDDis

另请参阅

KeInitializeEvent

NtCreateFile

NtQueryInformationFile

NtReadFile

NtSetInformationFile