ZwWriteFile routine
The ZwWriteFile routine 往一个打开的文件里写入数据.
Syntax
NTSTATUS ZwWriteFile(
_In_ HANDLE FileHandle,
_In_opt_ HANDLE Event,
_In_opt_ PIO_APC_ROUTINE ApcRoutine,
_In_opt_ PVOID ApcContext,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_In_ PVOID Buffer,
_In_ ULONG Length,
_In_opt_ PLARGE_INTEGER ByteOffset,
_In_opt_ PULONG Key
);
Parameters
FileHandle [in]
ZwCreateFile or ZwOpenFile调用成功后返回的句柄
Event [in, optional]
可选的一个事件对象的句柄,用于当写文件操作完成后设置这个句柄的信号状态设备和中间层驱动应当设置这个参数为NULL。
ApcRoutine [in, optional]
保留,设备和中间层驱动应当设置这个参数为NULL。
ApcContext [in, optional]
保留,设备和中间层驱动应当设置这个参数为NULL。
IoStatusBlock [out]
指向 IO_STATUS_BLOCK 结构体的指针,它用来接收最终完成状态和写入操作的信息,Information 成员接收实际写入文件的字节数。
Buffer [in]
指向用户申请来存放需要写入文件的数据的缓冲区
Length [in]
Buffer指向的缓冲区的大小,单位为字节。
ByteOffset [in, optional]
指向一个变量,该变量指定了写操作在文件中写入的开始位置。如果 Length 和 ByteOffset 指定了写操作超过了当前EOF的位置,那么ZwWriteFile 自动扩展文件并更新EOF标记。任何未显示写入原EOF和现EOF之间的字节将被填0.如果ZwCreateFile 仅设置 DesiredAccess 为FILE_APPEND_DATA。那么忽略参数 ByteOffset ,在Buffer中长度为Length的数据将写入文件的当前结束位置。
如果调用ZwCreateFile 时设定CreateOptions 为, FILE_SYNCHRONOUS_IO_ALERT 或 FILE_SYNCHRONOUS_IO_NONALERT之一,I/O管理器保管着当前文件位置,这样的话ZwWriteFile 可以指定当前的文件位置而不使用显式的ByteOffset 值。按照以下方法设置这个规范。
·
指定一个LARGE_INTEGER 指针,HighPart 设置为-1,而 LowPart 设置为系统已定义的FILE_USE_FILE_POINTER_POSITION.
·
·
传递一个NULL 给ByteOffset.
·
ZwWriteFile 完成一个写操作时如果使用I/O管理器把持的一个文件位置那么通过增加写入的字节数更新当前文件的位置。即使是I/O管理器把持着当前的文件位置,我们也可以通过传递一个显式的ByteOffset参数值给 ZwWriteFile来重设当前的位置。这样做将自动改变文件当前位置到 ByteOffset 指定的位置,执行写操作,根据实际写入的字节数更新文件位置。这种技术提供调用者自动seek-and-write 的服务。
通过设置ByteOffset 参数指向的LARGE_INTEGER值的HighPart 为-1LowPart 设置为FILE_WRITE_TO_END_OF_FILE同样可以使得一个写操作从文件的当前结尾位置开始执行。这种方式无视I/O管理器是否保持着当前的位置都有效。
Key [in, optional]
Return value
ZwWriteFile 成功返回STATUS_SUCCESS ,否则一个合适的 NTSTATUS error code。
Remarks
调用ZwWriteFile 之前必须已经调用了ZwCreateFile ,且对应的DesiredAccess 参数必须设定为FILE_WRITE_DATA, FILE_APPEND_DATA, 或者是 GENERIC_WRITE 。注意仅有在使用FILE_APPEND_DATA 访问时不允许写入到文件除了结束位置之外的其他任意位置。当使用 FILE_WRITE_DATA 访问一个文件时并不阻止调用者写入数据到文档的结尾之后的地方。
如果之前的ZwCreateFile 设置了CreateOptions 参数为 FILE_NO_INTERMEDIATE_BUFFERING, ZwWriteFile 的Length 和 ByteOffsetparameters 参数必须是一个完整的section大小。更多详见 ZwCreateFile.
ZwWriteFile 写入数据到 ByteOffset,在当前位置, 或者在end-of-file 标志.,ZwWriteFile 在从Buffer写入文件Length 字节长度的数据后结束执行。如果需要它将扩展文件长度并且重设EOF标记。
日过用户打开文件时候指定了DesiredAccess 参数为SYNCHRONIZE 标志。调用者可以等待这个例程设置给定的 FileHandle 变成signaled 状态。
驱动程序应当在以下三种情况下载系统进程上下文中调用 ZwWriteFile
1.
驱动程序传给ZwWriteFileT的文件句柄是驱动程序创建的。
2.
ZwWriteFile 通过驱动程序创建的事件通知驱动程序I/O的完成。
3.
ZwWriteFile 通过一个APC回调通知驱动程序I/O操作的完成。而这个APC是驱动程序传递给ZwWriteFile 的。
文件和事件句柄仅仅在创建它们的进程上下文中有效,因此为了避免安全漏洞,驱动程序应当把所有的文件或事件句柄都在系统进程的上下文中创建,而不是在驱动所在的进程上下文中。另外, 若它通过一个APC通知驱动I/O完成那么ZwWriteFile 应当在系统进程上下文中被调用,这是因为APC们总是在发布I/O请求的线程上下文中被引发,而如果驱动在不是系统进程的进程上下文中调用ZwWriteFile ,APC 可能被无限期推迟,或者它可能根本不会被引发。(因为原始线程可能永远不会进入一个 alertable wait state).
关于文件操作的更多信息,见 Using Files in a Driver.
Callers of ZwWriteFile must be running at IRQL = PASSIVE_LEVEL and with special kernel APCs enabled.
Note 用户模式下使用 "NtWriteFile" 代替 "ZwWriteFile".
Requirements
Target platform | |
Version | Available starting with Windows 2000. |
Header | Wdm.h (include Wdm.h, Ntddk.h, or Ntifs.h) |
Library | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | PASSIVE_LEVEL (see Remarks section) |
DDI compliance rules |
See also