共用方式為


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

選擇性旗標。 目前沒有有效的旗標值。

傳回值

如果複製成功完成或NTSTATUS程式代碼,NtCopyFileChunk 會傳回STATUS_SUCCESS,例如下列其中一項:

程式碼 意義
STATUS_PENDING 複製正在進行中。 呼叫端必須等候事件或檔案物件,才能取得最終狀態。
STATUS_[ERROR] 可能會發生類似 NtReadFileNtWriteFile 的各種錯誤。

寫入完成後,即可藉由檢查 IoStatusBlock 的 [狀態] 字段來判斷作業的狀態。

See Remarks for details regarding the handling of synchronous/asynchronous I/O.

備註

NtCopyFileChunk 會使用所要求長度所提供的檔案位移,將數據從來源檔案複製到目的地檔案。 如果長度超過來源檔案上 (EOF) 的結尾, 則 NtCopyFileChunk 只會讀取數據,並將數據複製到目的地到來源的 EOF。 呼叫端可以取得從 IoStatusBlock寫入的實際位元元組數目。

NtCopyFileChunk 包含兩個 I/O 作業:來源檔案的讀取和目的地檔案的寫入。 雖然每個 I/O 在內部都有自己的完成,但如果未提供任何事件,則呼叫端的事件 (或目的地檔句柄) 在複製作業完成時收到訊號。

來源和目的地檔案可以異步或同步開啟。 雖然建議呼叫端在兩個句柄之間保持一致,但並非必要。 根據所提供的句柄, NtCopyFileChunk 會在複製作業的不同點傳回,如下表所指定。

來源句柄 目的地句柄 傳回條件
非同步的 非同步的 讀取成功排入佇列之後,如果佇列讀取之前發生錯誤,則為 OR 。
非同步的 同步 寫入完成後,如果寫入完成之前發生錯誤,則為 。
同步 同步 寫入完成後,如果寫入完成之前發生錯誤,則為 。
同步 非同步的 寫入成功排入佇列后,如果寫入佇列之前發生錯誤,則為 OR。

如果傳回STATUS_PENDING,呼叫者必須等候作業完成,才能查看I/O 狀態區塊以取得最終狀態。 如果傳回STATUS_SUCCESS或 I/O 狀態區塊指出成功,呼叫端應該查看 IoStatusBlock 來判斷複製的位元元組數目。

如果針對非快取 I/O 開啟任一檔案,則呼叫端必須確定要求的長度與開啟為非快取檔案的扇區對齊。 如果兩者都一樣,長度應該與兩者較大的扇區大小對齊。

來自 NtCopyFileChunk 的所有讀取和寫入作業都將具有:

  • IRP 的要求者模式設定為 KernelMode
  • IopCopyInformationType 類型的 IRP 延伸模組。

篩選條件無法直接存取 IRP 延伸模組,但可以檢查此延伸模組是否存在,並藉由呼叫 FltGetCopyInformationFromCallbackData 從回呼數據取得複製資訊。

此復本無法使用快速 IO,因為複製資訊存在於 IRP 延伸模組 (中,而快速 IO 不會) 建立 IRP。

CopyFile 會在內部使用 NtCopyFileChunk,以供大部分形式的複製使用。 目前的例外狀況包括雲端復本、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
程式庫 NtosKrnl.lib
Dll NtosKrnl.exe
IRQL PASSIVE_LEVEL

另請參閱

FltGetCopyInformationFromCallbackData

IO_STATUS_BLOCK

NtCreateFile