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

書き込み操作を開始するためのファイル内の開始バイト オフセットを指定する変数へのポインター。 LengthByteOffset で現在のファイルの末尾のマークを超える書き込み操作が指定されている場合、NtWriteFile は自動的にファイルを拡張し、ファイルの終了マークを更新します。このような古いファイルの終わりと新しいファイルの終わりのマークの間に明示的に書き込まれていないバイトは、ゼロとして定義されます。

NtCreateFile の呼び出しで DesiredAccess フラグのみが設定FILE_APPEND_DATA場合、ByteOffset は無視されます。 指定された Buffer 内のデータ ( Length バイト) は、ファイルの現在の末尾から書き込まれます。

NtCreateFile の呼び出しで CreateOptions フラグ (FILE_SYNCHRONOUS_IO_ALERTまたはFILE_SYNCHRONOUS_IO_NONALERT) のいずれかが設定されている場合、I/O マネージャーは現在のファイル位置を維持します。 その場合、 NtWriteFile の呼び出し元は、明示的な ByteOffset 値の代わりに現在のファイル位置オフセットを使用するように指定できます。 この仕様は、次のいずれかの方法を使用して行うことができます。

  • * HighPart メンバーが -1 に設定され、 LowPart メンバーがシステム定義値に設定されたLARGE_INTEGER値へのポインターを指定FILE_USE_FILE_POINTER_POSITION。
  • ByteOffset に NULL ポインターを渡します。

NtWriteFile は、書き込み操作の完了時に書き込まれたバイト数を追加することによって、現在のファイル位置を更新します (I/O マネージャーによって管理されている現在のファイル位置を使用している場合)。

I/O マネージャーが現在のファイル位置を維持している場合でも、呼び出し元は明示的な ByteOffset 値を NtWriteFile に渡すことで、この位置をリセットできます。 これにより、現在のファイルの位置がその ByteOffset値に自動的に変更され、書き込み操作が実行され、実際に書き込まれたバイト数に従って位置が更新されます。 この手法により、呼び出し元にアトミックなシークおよび書き込みサービスが提供されます。

また、HighPart が -1 に設定され、LowPart が FILE_WRITE_TO_END_OF_FILE に設定されたLARGE_INTEGER値へのポインターを ByteOffset に指定することで、書き込み操作をファイルの現在の末尾から開始することもできます。 これは、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 パラメーターは NtWriteFile にセクター サイズの整数である必要があります。 詳細については、「 NtCreateFile」を参照してください。

NtWriteFile は、 ByteOffset、現在のファイル位置、またはファイルの末尾にあるファイルへの書き込み操作を開始します。 Buffer から Length バイトを書き込むと、書き込み操作が終了 します。 必要に応じて、ファイルの長さを拡張し、ファイルの終了マークをリセットします。

呼び出し元が DesiredAccess SYNCHRONIZE フラグを設定してファイルを開いた場合、呼び出し元は、このルーチンが指定された FileHandle を シグナル状態に設定するまで待機できます。

ドライバーは、次の 3 つの場合に、システム プロセスのコンテキストで NtWriteFile を呼び出す必要があります。

  • ドライバーは、 NtWriteFile に渡すファイル ハンドルを作成します。
  • NtWriteFile は、ドライバーによって作成されたイベントによって I/O 完了をドライバーに通知します。
  • NtWriteFile は、ドライバーが NtWriteFile に渡す APC コールバック ルーチンを使用して、I/O 完了をドライバーに通知します。

ファイル ハンドルとイベント ハンドルは、ハンドルが作成されるプロセス コンテキストでのみ有効です。 そのため、セキュリティ ホールを回避するために、ドライバーは、ドライバーが存在するプロセス コンテキストではなく、システム プロセスのコンテキストで NtWriteFile に渡すファイルまたはイベント ハンドルを作成する必要があります。

同様に、APC を使用してドライバーに I/O 完了を通知する場合は、システム プロセスのコンテキストで NtWriteFile を呼び出す必要があります。これは、APC は常に I/O 要求を発行するスレッドのコンテキストで発生するためです。 ドライバーがシステム プロセス以外のプロセスのコンテキストで NtWriteFile を 呼び出した場合、APC が無期限に遅延する可能性があります。または、発生元のスレッドがアラート可能な待機状態に入らない可能性があるため、まったく起動しない可能性があります。

ファイルの操作の詳細については、「 ドライバーでのファイルの使用」を参照してください。

NtWriteFile の呼び出し元は、IRQL = PASSIVE_LEVELで実行され、特殊なカーネル APCs が有効になっている必要があります。

この関数の呼び出しがユーザー モードで行われる場合は、"ZwWriteFile" ではなく "NtWriteFile" という名前を使用する必要があります。

カーネル モード ドライバーからの呼び出しの場合、Windows ネイティブ システム サービス ルーチンの NtXxx および ZwXxx バージョンは、入力パラメーターを処理および解釈する方法で動作が異なる場合があります。 ルーチンの NtXxx バージョンと ZwXxx バージョンの間の関係の詳細については、「ネイティブ システム サービス ルーチンの Nt バージョンと Zw バージョンの使用」を参照してください。

要件

要件
サポートされている最小のクライアント Windows 2000
対象プラットフォーム ユニバーサル
Header ntifs.h (Wdm.h、Ntddk.h、Ntifs.h を含みます)
Library NtosKrnl.lib
[DLL] NtosKrnl.exe
IRQL PASSIVE_LEVEL (「解説」セクションを参照)
DDI コンプライアンス規則 HwStorPortProhibitedDDIs、PowerIrpDDis

こちらもご覧ください

KeInitializeEvent

NtCreateFile

NtQueryInformationFile

NtReadFile

NtSetInformationFile