EX_CALLBACK_FUNCTION コールバック関数 (wdm.h)
フィルター ドライバーの RegistryCallback ルーチンは、レジストリ操作を監視、ブロック、または変更できます。
構文
EX_CALLBACK_FUNCTION ExCallbackFunction;
NTSTATUS ExCallbackFunction(
[in] PVOID CallbackContext,
[in, optional] PVOID Argument1,
[in, optional] PVOID Argument2
)
{...}
パラメーター
[in] CallbackContext
この RegistryCallback ルーチンを登録したときに、ドライバーが Context パラメーターとして CmRegisterCallback または CmRegisterCallbackEx に渡した値。
[in, optional] Argument1
実行されているレジストリ操作の種類と、レジストリ操作の実行前または実行後に RegistryCallback ルーチンが呼び出されているかどうかを識別する、REG_NOTIFY_CLASS型指定された値。
[in, optional] Argument2
レジストリ操作の種類に固有の情報を含む構造体へのポインター。 構造体の型は、次の表に示すように、Argument1 のREG_NOTIFY_CLASS型指定された値によって異なります。 オペレーティング システムのバージョンに使用できるREG_NOTIFY_CLASS型指定された値については、「 REG_NOTIFY_CLASS」を参照してください。
Windows 7 以降では、notify クラスが RegNtPreCreateKeyEx または RegNtPreOpenKeyEx のときに渡される実際のデータ構造は、それぞれこの構造体の V1 バージョン REG_CREATE_KEY_INFORMATION_V1 または REG_OPEN_KEY_INFORMATION_V1です。 予約済みメンバーを調べて、構造体のバージョンを確認します。
バージョン番号 | [構造名] |
---|---|
0 | REG_CREATE_KEY_INFORMATIONとREG_OPEN_KEY_INFORMATION |
1 | REG_CREATE_KEY_INFORMATION_V1とREG_OPEN_KEY_INFORMATION_V1 |
戻り値
RegistryCallback ルーチンがこれらの各状態値を返すタイミングの詳細については、「レジストリ呼び出しのフィルター処理」を参照してください。
注釈
レジストリ操作の通知を受け取るために、カーネル モード コンポーネント (ウイルス対策ソフトウェア パッケージのドライバー コンポーネントなど) は 、CmRegisterCallback または CmRegisterCallbackEx を呼び出して RegistryCallback ルーチンを登録できます。
RegistryCallback ルーチンは、レジストリ操作用に提供される入力バッファーと出力バッファーの内容を検査できます。 レジストリ操作は、ユーザー モード レジストリ ルーチン ( RegCreateKeyEx や RegOpenKeyEx など) を呼び出すユーザー モード アプリケーション、またはカーネル モード レジストリ ルーチン ( ZwCreateKey や ZwOpenKey など) を呼び出すドライバーによって開始できます。 入力バッファーは、操作の入力データをレジストリが読み取るイニシエーターによって提供されるメモリ バッファーです。 出力バッファーは、イニシエーターが要求した出力データをレジストリが書き込むイニシエーターによって提供されるバッファーです。
RegistryCallback ルーチンを呼び出す前に、カーネルは、ユーザー モード メモリ内の出力バッファーを指すが、システム メモリ内のユーザー モード出力バッファーをキャプチャしない Argument2 構造体のすべてのメンバーをプローブします (アラインメントとアクセシビリティを確認するため)。 コールバック ルーチンは、出力バッファーのアクセスを try/except ブロックで囲む必要があります。 コールバック ルーチンがシステム ルーチン ( ZwOpenKey など) に出力バッファー ポインターを渡す必要があり、バッファーがユーザー モード メモリ内にある場合、コールバック ルーチンは最初にバッファーをキャプチャする必要があります。
入力バッファーの処理は、Windows のバージョンによって異なります。 Windows 8以降、カーネルは RegistryCallback ルーチンを呼び出す前に、システム メモリ内の Argument2 構造体のメンバーが指すすべての入力バッファーをキャプチャします。 Windows 8より前のバージョンの Windows では、カーネルは、ユーザー モード メモリ内の入力バッファーを指す Argument2 構造体のすべてのメンバーをプローブしますが、システム メモリ内のこれらのバッファーの一部のみをキャプチャします。 これらの以前のバージョンの Windows では、コールバック ルーチンは、入力バッファーへのアクセスをtry except ブロックで/囲む必要があります。 さらに、コールバック ルーチンがシステム ルーチン ( ZwOpenKey など) に入力バッファー ポインターを渡す必要があり、バッファーがユーザー モード メモリにある場合、コールバック ルーチンは最初にバッファーをキャプチャする必要があります。
次の表は、 RegistryCallback ルーチンによるバッファー アクセスの要件をまとめたものです。
バッファーの種類 | Windows のバージョン | コールバック ルーチンに渡されるバッファー ポインター | コールバック ルーチンが直接アクセスしても安全ですか? | システム ルーチン ( ZwOpenKey など) に安全に渡すことができますか? |
---|---|---|---|---|
ユーザー モード入力 | Windows 8 以降 | キャプチャされたデータをポイントします。 | Yes | Yes |
ユーザー モード入力 | Windows 7 以前 | キャプチャされたデータまたは元のユーザー モード バッファーを指します。 | いいえ。 try/except の下で読む必要があります。 | いいえ。 カーネル メモリを割り当て、try/except の元のバッファーからデータをコピーし、コピーしたデータをシステム ルーチンに渡す必要があります。 |
ユーザー モードの出力 | すべて | 元のユーザー モード バッファーをポイントします。 | いいえ。 try/except の下に を記述する必要があります。 | いいえ。 カーネル メモリを割り当て、カーネル メモリをシステム ルーチンに渡し、try/except の元のバッファーに結果をコピーし直す必要があります。 |
カーネル モードの入出力 | すべて | 元のカーネル モード バッファーをポイントします。 | Yes | Yes |
RegistryCallback ルーチンとレジストリ フィルター ドライバーの詳細については、「レジストリ呼び出しのフィルター処理」を参照してください。
RegistryCallback は IRQL = PASSIVE_LEVELで実行され、レジストリ操作を実行しているスレッドのコンテキストで実行されます。
例
RegistryCallback コールバック ルーチンを定義するには、まず、定義するコールバック ルーチンの種類を識別する関数宣言を指定する必要があります。 Windows には、ドライバーのコールバック関数型のセットが用意されています。 コールバック関数の種類を使用して関数を宣言すると、 ドライバーのコード分析、 静的ドライバー検証ツール (SDV)、およびその他の検証ツールでエラーが検出され、Windows オペレーティング システムのドライバーを記述するための要件になります。
たとえば、 という名前MyRegistryCallback
の RegistryCallback コールバック ルーチンを定義するには、次のコード例に示すように、EX_CALLBACK_FUNCTION型を使用します。
EX_CALLBACK_FUNCTION MyRegistryCallback;
次に、コールバック ルーチンを次のように実装します。
_Use_decl_annotations_
NTSTATUS
MyRegistryCallback(
PVOID CallbackContext,
PVOID Argument1,
PVOID Argument2
)
{
// Function body
}
EX_CALLBACK_FUNCTION関数の種類は、Wdm.h ヘッダー ファイルで定義されています。 コード分析ツールの実行時にエラーをより正確に識別するには、 Use_decl_annotations 注釈を関数定義に追加してください。 Use_decl_annotations注釈を使用すると、ヘッダー ファイル内のEX_CALLBACK_FUNCTION関数型に適用される注釈が確実に使用されます。 関数宣言の要件の詳細については、「 WDM ドライバーの関数ロール型を使用して関数を宣言する」を参照してください。 Use_decl_annotationsの詳細については、「関数の動作に注釈を付ける」を参照してください。
要件
要件 | 値 |
---|---|
サポートされている最小のクライアント | Windows XP 以降でサポートされています (「戻り値」セクションを参照)。 |
対象プラットフォーム | デスクトップ |
Header | wdm.h (Wdm.h、Ntddk.h、Ntifs.h を含む) |
IRQL | PASSIVE_LEVELで呼び出されます (「解説」セクションを参照)。 |