Nt および Zw バージョンのネイティブ システム サービス ルーチンの使用

Windows ネイティブ オペレーティング システム サービス API は、カーネル モードで実行されるルーチンのセットとして実装されます。 これらのルーチン名は、プレフィックス Nt または Zw で始まります。 カーネル モード ドライバーは、これらのルーチンを直接呼び出すことができます。 ユーザー モード アプリケーションは、システム呼び出しを使用してこれらのルーチンにアクセスできます。

いくつかの例外を除き、ネイティブ システム サービス ルーチンにはそれぞれ、名前が似ているがプレフィックスが異なる、わずかに異なる 2 つのバージョンがあります。 たとえば、NtCreateFile の呼び出しと ZwCreateFile の呼び出しでは、どちらでも同じ操作が実行され、同じカーネル モードのルーチンによって実際にサービスが提供されます。 ユーザー モードからのシステム呼び出しの場合、ルーチンの Nt バージョンと Zw バージョンは同じように動作します。 カーネル モード ドライバーからの呼び出しの場合、ルーチンの Nt バージョンと Zw バージョンは、呼び出し元がルーチンに渡すパラメーター値の処理方法が異なります。

カーネル モード ドライバーは、ネイティブ システム サービス ルーチンの Zw バージョンを呼び出して、パラメーターが信頼されたカーネル モード ソースから取得されたことをルーチンに通知します。 この場合、ルーチンは、パラメーターを最初に検証しなくても安全にパラメーターを使用できることを前提としています。 ただし、パラメーターがユーザー モード ソースまたはカーネル モード ソースのいずれかである可能性がある場合、ドライバーは代わりにルーチンの Nt バージョンを呼び出します。このルーチンは、呼び出し元のスレッドの履歴に基づいて、パラメーターがユーザー モードまたはカーネル モードで発生したかどうかを判断します。 ルーチンがユーザー モード パラメーターとカーネル モード パラメーターを区別する方法の詳細については、PreviousMode を参照してください。

ユーザー モード アプリケーションがネイティブ システム サービス ルーチンの Nt または Zw バージョンを呼び出すと、ルーチンは常に、信頼されていないユーザー モード ソースから取得された値として受け取るパラメーターを扱います。 ルーチンは、パラメーターを使用する前に、パラメーター値を徹底的に検証します。 特に、このルーチンは、呼び出し元が指定したバッファーをプローブして、バッファーが有効なユーザー モード メモリ内にあり、適切にアラインされていることを確認します。

ネイティブ システム サービス ルーチンは、受け取るパラメーターに関する追加の前提条件を作成します。 ルーチンがカーネル モード ドライバーによって割り当てられたバッファーへのポインターを受け取った場合、ルーチンは、バッファーがユーザー モード メモリではなくシステム メモリに割り当てられたと見なします。 ルーチンがユーザー モード アプリケーションによって開かれたハンドルを受け取った場合、ルーチンはカーネル モード ハンドル テーブルではなく、ユーザー モード のハンドル テーブルでハンドルを検索します。

いくつかのインスタンスでは、パラメーター値の意味は、ユーザー モードからの呼び出しとカーネル モードからの呼び出しによって大きく異なります。 たとえば、ZwNotifyChangeKey ルーチン (またはその NtNotifyChangeKey に対応するルーチン) には、入力パラメーター ApcRoutineApcContext のペアがあります。これは、パラメーターがユーザー モードソースとカーネル モード ソースのどちらからのものであるかによって異なります。 ユーザー モードからの呼び出しの場合、 ApcRoutine は APC ルーチンを指し、 ApcContext は オペレーティング システムが APC ルーチンを呼び出すときに提供するコンテキスト値を指します。 カーネル モードからの呼び出しの場合、ApcRoutineWORK_QUEUE_ITEM 構造体を指し、ApcContext は、WORK_QUEUE_ITEM 構造体によって記述される作業キュー項目の種類を指定します。

ここでは、次のトピックについて説明します。

PreviousMode

ライブラリとヘッダー

Zw プレフィックスの意味

アクセス権の指定

NtXxx ルーチン