次の方法で共有


ProbeForWrite 関数 (wdm.h)

警告

ProbeForWrite 関数は、現在のソフトウェアでの使用には推奨されず、履歴の互換性のみを目的として含まれています。 ユーザー バッファーを検証するときは、代わりに ProbeForRead を使用します。 詳細については、「解説」を参照してください。

ProbeForWrite ルーチンは、ユーザー モード バッファーが実際にはアドレス空間のユーザー モード部分に存在し、書き込み可能であり、正しくアラインされていることを確認します。

構文

void ProbeForWrite(
  [in, out] volatile VOID *Address,
  [in]      SIZE_T        Length,
  [in]      ULONG         Alignment
);

パラメーター

[in, out] Address

ユーザー モード バッファーの先頭を指定します。

[in] Length

ユーザー モード バッファーの長さをバイト単位で指定します。 詳細については、「解説」セクションを参照してください。

[in] Alignment

ユーザー モード バッファーの先頭に必要なアラインメントをバイト単位で指定します。

戻り値

なし

解説

ProbeForWrite 呼び出しの実行後にドライバーに渡されたバッファーへの書き込みアクセス許可を削除する保護の変更など、ユーザー モードの仮想アドレス空間での保護の変更を処理するために、堅牢なドライバーを常に準備する必要があるため、この関数は通常、ProbeForRead に対して大きなメリットを提供しません。 ProbeForWrite は指定されたバッファー内の各ページにアクセスするため、特に指定されたバッファーが仮想アドレス空間の大きな領域を記述している場合は、各ページにアクセスするオーバーヘッドが原因でパフォーマンスが低下する可能性があります。 また、 ProbeForWrite は各ページに書き込むため、複数の同時ドライバー要求で同じバッファーを安全に使用できない場合があります。 これらの理由から、新しいドライバー コードでは、代わりに ProbeForRead を常に使用する必要があります。

次の表は、各カーネル モード バッファー プローブ ルーチンのプロパティの概要を示しています。

動作 ProbeForRead ProbeForWrite
長さが 0 以外の場合、バッファーがユーザー モードのアドレス空間内の領域を記述することを確認します x x
バッファーのベース アドレスと長さが最大ポインター値を超えてラップされないことを確認します x x
長さが 0 以外の場合に、バッファーが要求された配置境界にアラインされていることを確認します x x
バッファーが最初に書き込み可能であることを確認します (ユーザー モード アプリケーションがアドレス空間を再保護すると、いつでも変更される可能性があります) x
バッファー内の各ページにアクセスします (追加のオーバーヘッド) x
バッファー内の各ページを変更します (複数のドライバー要求と並行して同じバッファーを使用すると、予期しない動作が発生する可能性があります) x

これまで、カーネル モード コードの読み取り専用アクセス許可を受け入れなかった特定のプロセッサでは、 ProbeForWriteProbeForRead の間に意味のある機能の違いがありました。 このような場合、オペレーティング システムは、明示的なページング書き込みチェックを実行する ProbeForWrite に以前依存していました。 この区別は、Windows NT 4.0 以降でサポートされているプロセッサでは意味がなくなりました。

従来の解説

カーネル モード ドライバーでは、 ProbeForWrite を使用して、ユーザー空間に割り当てられたバッファーへの書き込みアクセスを検証できます。 これは、Irp-UserBuffer> が指すユーザー バッファーを検証するために、METHOD_NEITHER I/O 中に最も一般的に使用されます。

指定したメモリ範囲が有効なユーザー モード アドレス範囲ではない場合、または書き込み可能でない場合 (アクセス、読み取り専用など)、 ProbeForWrite はSTATUS_ACCESS_VIOLATION例外を発生させます。 アドレス範囲の先頭が Alignment で指定されたバイト境界にア ラインされていない場合、 ProbeForWrite はSTATUS_DATATYPE_MISALIGNMENT例外を発生させます。

ドライバーは、try/except ブロック内で ProbeForWrite を呼び出す必要があります。 ルーチンで例外が発生した場合、ドライバーは適切なエラーで IRP を完了する必要があります。 ドライバーによるユーザー モード バッファーへの後続のアクセスは 、try/except ブロック内にもカプセル化する必要があることに注意してください。悪意のあるアプリケーションは、( ProbeForRead または ProbeForWrite の呼び出しの後または呼び出し中でも) いつでもユーザー アドレス範囲の保護を削除、置換、または変更する別のスレッドを持つ可能性があります。 詳細については、「 例外の処理」を参照してください。

カーネル モード アドレスでは、このルーチンを使用しないでください。例外が発生します。

Irp-RequestorMode> = KernelMode の場合、Irp-AssociatedIrp.SystemBuffer> フィールドと Irp-UserBuffer> フィールドにはユーザー モード アドレスが含まれていません。また、ProbeForWrite を呼び出して、いずれかのフィールドが指すバッファーをプローブすると、例外が発生します。

Length = 0 の場合、ProbeForWrite はアドレスのチェックを行いません。 この場合、ルーチンは、位置がずれているアドレスまたは有効なユーザー アドレスの範囲外のアドレスに対して例外を発生させません。

要件

要件
サポートされている最小のクライアント Windows 2000 以降で使用できます。
対象プラットフォーム ユニバーサル
Header wdm.h (Wdm.h、Ntddk.h、Ntifs.h を含む)
Library NtosKrnl.lib
[DLL] NtosKrnl.exe
IRQL <= APC_LEVEL
DDI コンプライアンス規則 HwStorPortProhibitedDDIs(storport), IrqlExApcLte2(wdm)

こちらもご覧ください

ProbeForRead