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