NtWriteFile 函式 (ntifs.h)
ZwWriteFile 例程會將數據寫入開啟的檔案。
語法
__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
檔案物件的句柄。 此句柄是由成功呼叫 NtCreateFile 或 NtOpenFile 所建立。
[in, optional] Event
選擇性地,在寫入作業完成之後,要設定為訊號狀態的事件物件句柄。 裝置和中繼驅動程序應該將此參數設定為 NULL。
[in, optional] ApcRoutine
此參數已保留備用。 裝置和中繼驅動程序應該將此指標設定為 NULL。
[in, optional] ApcContext
此參數已保留備用。 裝置和中繼驅動程序應該將此指標設定為 NULL。
[out] IoStatusBlock
接收最終完成狀態和所要求寫入作業相關信息 之IO_STATUS_BLOCK 結構的指標。 Information 成員會接收實際寫入檔案的位元元組數目。
[in] Buffer
呼叫端配置的緩衝區指標,其中包含要寫入檔案的數據。
[in] Length
Buffer 所指向之緩衝區的大小,以位元組為單位。
[in, optional] ByteOffset
變數的指標,指定檔案中開始寫入作業的起始位移。 如果 Length 和 ByteOffset 指定超過目前檔案結尾標記的寫入作業, 則 NtWriteFile 會自動擴充檔案並更新檔尾標記;未明確寫入這類舊檔案尾標記和新檔尾標記的任何位元組都會定義為零。
如果對 NtCreateFile 的呼叫只設定 DesiredAccess 旗標FILE_APPEND_DATA,則會忽略 ByteOffset 。 指定 緩衝區中的數據,針對 Length 位元組,會從檔案的目前結尾開始寫入。
如果呼叫 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 設定為 LARGE_INTEGER FILE_WRITE_TO_END_OF_FILE,讓寫入作業從檔案的目前結尾開始。 不論 I/O 管理員是否維護目前的檔案位置,這都能運作。
[in, optional] Key
裝置和中繼驅動程序應該將此指標設定為 NULL。
傳回值
NtWriteFile 會在成功時傳回STATUS_SUCCESS,或在失敗時傳回適當的 NTSTATUS 錯誤碼。
備註
NtWriteFile 的呼叫端必須已經使用 DesiredAccess 參數中設定的 FILE_WRITE_DATA、FILE_APPEND_DATA 或 GENERIC_WRITE 旗標呼叫 NtCreateFile。 請注意,只有FILE_APPEND_DATA檔案的存取權不允許呼叫端在檔案中的任何位置寫入,但目前檔案的結尾標記除外,而對檔案的存取FILE_WRITE_DATA並不會防止呼叫端寫入檔案結尾或超過檔案結尾。
如果上述 對 NtCreateFile 的呼叫將 CreateOptions 旗標設定FILE_NO_INTERMEDIATE_BUFFERING, 則 Length 和 ByteOffset參數必須是扇 區大小的整數。 如需詳細資訊,請參閱 NtCreateFile。
NtWriteFile 會在 ByteOffset、目前檔案位置或檔案結尾標記開始對檔案的寫入作業。 從 Buffer 寫入 Length 位元節時,它會終止寫入作業。 如有必要,它會擴充檔案的長度,並重設檔尾標記。
如果呼叫端已開啟已設定 DesiredAccess SYNCHRONIZE 旗標的檔案,則呼叫端可以等候此例程將指定的 FileHandle 設定為已發出訊號的狀態。
驅動程式應該在系統進程的內容中呼叫 NtWriteFile ,但有三種情況:
- 驅動程式會建立傳遞至 NtWriteFile 的檔案句柄。
- NtWriteFile 會透過驅動程式所建立的事件通知驅動程式 I/O 完成。
- NtWriteFile 會透過驅動程式傳遞至 NtWriteFile 的 APC 回呼例程,通知 I/O 完成的驅動程式。
檔案和事件句柄只有在建立句柄的進程內容中才有效。 因此,若要避免安全漏洞,驅動程式應該建立任何檔案或事件句柄,以在系統進程的內容中傳遞至 NtWriteFile ,而不是驅動程式所在的進程內容。
同樣地,如果 NtWriteFile 透過 APC 通知 I/O 完成的驅動程式,則應該在系統進程的內容中呼叫 NtWriteFile ,因為 APC 一律會在發出 I/O 要求的線程內容中引發。 如果驅動程式在系統進程以外的進程內容中呼叫 NtWriteFile,APC 可能會無限期延遲,或可能完全不會引發,因為原始線程可能永遠不會進入可警示的等候狀態。
如需使用檔案的詳細資訊,請參閱 在驅動程式中使用檔案。
NtWriteFile 的呼叫端必須在 IRQL = PASSIVE_LEVEL且啟用特殊核心 APC 時執行。
如果呼叫此函式發生在使用者模式中,您應該使用名稱 「NtWriteFile」,而不是 「ZwWriteFile」。
對於核心模式驅動程式的呼叫,Windows 原生系統服務例程的 NtXxx 和 ZwXxx 版本在處理和解譯輸入參數的方式可能會有不同的行為。 如需例程 NtXxx 和 ZwXxx 版本之間的關聯性詳細資訊,請參閱 使用 Nt 和 Zw 版本的原生系統服務例程。
規格需求
需求 | 值 |
---|---|
最低支援的用戶端 | Windows 2000 |
目標平台 | Universal |
標頭 | ntifs.h (包括 Wdm.h、Ntddk.h、Ntifs.h) |
程式庫 | NtosKrnl.lib |
Dll | NtosKrnl.exe |
IRQL | PASSIVE_LEVEL (请参阅一节) |
DDI 合規性規則 | HwStorPortProhibitedDIS、 PowerIrpDDis |