次の方法で共有


前のモード

ユーザー モード アプリケーションがネイティブ システム サービス ルーチンの Nt または Zw バージョンを呼び出すと、システム呼び出しメカニズムは呼び出し元のスレッドをカーネル モードにトラップします。 パラメーター値がユーザー モードで発生したことを示すために、システム呼び出しのトラップ ハンドラーは、呼び出し元のスレッド オブジェクトPreviousMode フィールドを UserMode に設定します。 ネイティブ・システム・サービス・ルーチンは、呼び出し元スレッドの PreviousMode フィールドを検査して、パラメーターがユーザー・モード・ソースからのものかどうかを判別します。

カーネル モード ドライバーは、ネイティブ システム サービス ルーチンを呼び出し、カーネル モード ソースからルーチンにパラメーター値を渡す場合、ドライバーは、現在のスレッド オブジェクトの PreviousMode フィールドが KernelMode に設定されていることを確認する必要があります。

カーネル モード ドライバーは任意のスレッドのコンテキストで実行でき、このスレッドの PreviousMode フィールドが UserMode に設定されている可能性があります。 この状況では、カーネル モード ドライバーは、パラメーターの値が信頼されたカーネル モード ソースからであることをルーチンに通知するネイティブ システム サービス ルーチンの Zw バージョンを呼び出すことができます。 Zw 呼び出しは、現在のスレッド オブジェクトの PreviousMode 値をオーバーライドするシン ラッパー関数に移動します。 ラッパー関数は PreviousModeKernelMode に設定し、 Nt バージョンのルーチンを呼び出します。 Nt バージョンのルーチンから返された場合、ラッパー関数はスレッド オブジェクトの元の PreviousMode 値を復元して返します。

カーネル モード ドライバーは、ネイティブ システム サービス ルーチンの Nt バージョンを直接呼び出すことができます。 カーネル モード ドライバーは、ユーザー モードまたはカーネル モードで発生する I/O 要求を処理する場合、ドライバーは、呼び出し中に現在のスレッドの PreviousMode 値が変更されないように、ルーチンの Nt バージョンを呼び出すことができます。 NtXxx ルーチンは、呼び出し元のスレッドの PreviousMode 値をチェックして、パラメーター値がユーザー モード アプリケーションまたはカーネル モード コンポーネントの値かどうかを判断し、それに応じて処理します。

カーネル モード ドライバーが NtXxx ルーチンを呼び出し、現在のスレッド オブジェクトの PreviousMode 値は、パラメーター値がユーザー モードまたはカーネル モードソースからのかどうかを正確に示していない場合に発生する可能性があります。

たとえば、カーネル モード ドライバーが任意のスレッドのコンテキストで実行され、このスレッドの PreviousMode 値が UserMode に設定されているとします。 ドライバーが NtClose ルーチンにカーネル モード ファイル ハンドルを渡す場合、このルーチンは 、PreviousMode 値を確認し、ハンドルがユーザー モード ハンドルである必要があることを決定します。 NtClose は、ユーザー モード のハンドル テーブルでハンドルを見つけられない場合、STATUS_INVALID_HANDLEエラー コードを返します。 一方、ドライバーは、閉じられなかったカーネル モード ハンドルをリークします。

別の例として、 NtXxx ルーチンのパラメーターに入力バッファーまたは出力バッファーが含まれている場合、 PreviousMode = UserMode の場合、このルーチンは ProbeForRead ルーチンまたは ProbeForWrite ルーチンを呼び出してバッファーを検証します。 バッファーがユーザー モード メモリではなくシステム メモリに割り当てられた場合、 ProbeForXxx ルーチンは例外を発生させ、 NtXxx ルーチンはSTATUS_ACCESS_VIOLATIONエラー コードを返します。

必要に応じて、ドライバーは ExGetPreviousMode ルーチンを呼び出して、現在のスレッド オブジェクトから PreviousMode 値を取得できます。 または、ドライバーは、要求された I/O 操作を記述する IRP 構造体から RequestorMode フィールドを読み取ることができます。 RequestorMode フィールドには、操作を要求したスレッドからの PreviousMode 値のコピーが含まれています。