ドライバーによって定義されたコールバック オブジェクトの使用

別のドライバーによって定義されたコールバック オブジェクトを使用するには、ドライバーがオブジェクトを開き、次の図に示すように、コールバックがトリガーされたときに呼び出されるルーチンを登録します。 通知を要求するドライバーは、コールバック オブジェクトの名前を認識し、コールバック ルーチンに渡される引数のセマンティクスを理解する必要があります。

diagram illustrating registration for callback notification.

オブジェクトを開く前に、ドライバーは InitializeObjectAttributes を呼び出して、オブジェクトの名前を指定して属性ブロックを作成する必要があります。 属性ブロックへのポインターがある場合は、ExCreateCallback を呼び出し、属性ポインター、コールバックへのハンドルを受け取る場所、および作成パラメーターの FALSE を渡して、既存のコールバック オブジェクトが必要であることを示します。

その後、ドライバーは、返されたハンドルを使用して ExRegisterCallback を呼び出して、コールバック ルーチンを登録できます。

コールバック ルーチンには、次のプロトタイプがあります。

typedef VOID (*PCALLBACK_FUNCTION ) (
    IN PVOID CallbackContext,
    IN PVOID Argument1,
    IN PVOID Argument2
    );

CallbackContext パラメーターは、コールバック ルーチンが呼び出されるたびに渡されるコンテキスト ポインターです。 通常、このパラメーターはコンテキスト データのブロックへのポインターであり、ルーチンを DISPATCH_LEVEL で呼び出すことができる場合、呼び出し元は非ページ プールから割り当てる必要があります。 2 つの引数は、コールバックを作成したコンポーネントによって定義されます。 通常、引数はコールバックをトリガーした条件に関する情報を提供します。

コールバックの作成者が通知をトリガーすると、システムは登録されたルーチンを呼び出し、コンテキストと 2 つの引数へのポインターを渡します。 引数の値は、コールバックを作成したコンポーネントによって提供されます。 コールバック ルーチンは、作成ドライバーが通知をトリガーしたのと同じ IRQL (常に IRQL <= DISPATCH_LEVEL) で呼び出されます。

そのコールバック ルーチンでは、ドライバーは、現在の条件に必要なタスクを実行できます。

ドライバーが通知を必要としなくなった場合は、ExUnregisterCallback を呼び出して、登録されているコールバックの一覧からルーチンを削除し、コールバック オブジェクトへの参照を削除する必要があります。