NtCopyFileChunk 函数 (ntifs.h)

NtCopyFileChunk 例程将数据从源文件复制到目标文件。

语法

__kernel_entry NTSYSCALLAPI NTSTATUS NtCopyFileChunk(
  [in]           HANDLE           SourceHandle,
  [in]           HANDLE           DestHandle,
  [in, optional] HANDLE           Event,
  [out]          PIO_STATUS_BLOCK IoStatusBlock,
  [in]           ULONG            Length,
  [in]           PLARGE_INTEGER   SourceOffset,
  [in]           PLARGE_INTEGER   DestOffset,
  [in, optional] PULONG           SourceKey,
  [in, optional] PULONG           DestKey,
  [in]           ULONG            Flags
);

参数

[in] SourceHandle

要读取的源文件的 HANDLE。

[in] DestHandle

目标文件的 HANDLE。 SourceHandle 文件中的数据将复制到 DestHandle 的 文件中。 完成端口可用于此句柄。

[in, optional] Event

复制操作完成时要发出信号的可选事件。

[out] IoStatusBlock

指向 IO_STATUS_BLOCK 结构的指针,该结构接收有关复制操作的最终完成状态和其他信息。

[in] Length

要复制的数据的长度(以字节为单位)。

[in] SourceOffset

源文件中开始读取操作的起始字节偏移量。

[in] DestOffset

要开始写入操作的目标文件中的起始字节偏移量。

[in, optional] SourceKey

当存在与源文件关联的 oplock 时要使用的可选密钥。

[in, optional] DestKey

当存在与目标文件关联的 oplock 时要使用的可选密钥。

[in] Flags

可选标志。 目前没有有效的标志值。

返回值

如果复制成功完成,则 NtCopyFileChunk 返回STATUS_SUCCESS,或者返回如下所示的 NTSTATUS 代码之一:

代码 含义
STATUS_PENDING 复制正在进行中。 调用方必须等待事件或文件对象获取最终状态。
STATUS_[ERROR] 各种错误可能发生,类似于 NtReadFileNtWriteFile

写入完成后,可以通过检查 IoStatusBlock“状态”字段来确定操作的状态。

有关处理同步/异步 I/O 的详细信息,请参阅 备注

注解

NtCopyFileChunk 使用请求长度提供的文件偏移量,将数据从源文件复制到目标文件。 如果长度超过源文件上 EOF) 的文件 (结尾,则 NtCopyFileChunk 将仅读取数据并将其复制到源 EOF 的目标位置。 调用方可以获取从 IoStatusBlock 写入的实际字节数。

NtCopyFileChunk 包括两个 I/O 操作:读取源文件和写入目标文件。 虽然每个 I/O 在内部都有其自己的完成,但如果未提供任何事件,则调用方的事件 (或目标文件句柄,) 复制操作完成时会发出信号。

源文件和目标文件可以异步或同步打开。 虽然建议调用方在两个句柄之间保持一致,但这不是必需的。 根据提供的句柄, NtCopyFileChunk 将在下表中指定的复制操作的不同点返回。

源句柄 目标句柄 返回条件
异步 异步 读取成功排队后,或者在排队读取之前出现错误。
异步 同步 写入完成后,如果写入完成之前出现错误,则为 。
同步 同步 写入完成后,如果写入完成之前出现错误,则为 。
同步 异步 写入成功排队后,或者在将写入排队之前出现错误时。

如果返回STATUS_PENDING,则调用的 必须等待操作完成,然后才能查看最终状态的 I/O 状态块。 如果返回STATUS_SUCCESS或 I/O 状态块指示成功,调用方应查看 IoStatusBlock 以确定复制的字节数。

如果为非缓存 I/O 打开了任一文件,则调用方必须确保请求的长度与作为非缓存文件打开的任意文件的扇区一致。 如果两者兼而有之,则长度应与两者的较大扇区大小保持一致。

来自 NtCopyFileChunk 的所有读取和写入操作都将具有:

  • IRP 的请求程序模式设置为 KernelMode
  • IopCopyInformationType 类型的 IRP 扩展。

筛选器不能直接访问 IRP 扩展,但可以检查此扩展的存在,并通过调用 FltGetCopyInformationFromCallbackData 从回调数据获取复制信息。

快速 IO 在此副本中不可用,因为复制信息存在于 IRP 扩展 (并且快速 IO 不会) 创建 IRP。

NtCopyFileChunk 在内部由 CopyFile 用于大多数形式的复制。 当前的异常包括云副本、SMB 卸载和 ODX。

以下示例演示如何使用 NtCopyFileChunk


// Input parameters to NtCopyFileChunk. Opening
// the file handles is done using NtCreateFile
// and creating the event is done with CreateEvent.
// This is not shown in this code sample. 

HANDLE sourceHandle; 
HANDLE destHandle; 
HANDLE event; 
IO_STATUS_BLOCK ioStatusBlock; 
ULONG length; 
LARGE_INTEGER sourceOffset; 
LARGE_INTEGER destOffset; 

// Copy the data 

status = NtCopyFileChunk( sourceHandle, 
                          destHandle, 
                          event, 
                          &ioStatusBlock, 
                          length, 
                          &sourceOffset, 
                          &destOffset, 
                          NULL, 
                          NULL, 
                          0 ); 

// Wait for the copy to complete 

if (status == STATUS_PENDING) { 
    status = NtWaitForSingleObject( event, FALSE, NULL ); 

    if (NT_SUCCESS(status)) { 
        status = ioStatusBlock.Status; 
    } 
}

有关详细信息 ,请参阅内核模式文件复制和检测复制文件方案

要求

要求
最低受支持的客户端 Windows 11 版本 22H2
标头 ntifs.h
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL PASSIVE_LEVEL

另请参阅

FltGetCopyInformationFromCallbackData

IO_STATUS_BLOCK

NtCreateFile