次の方法で共有


フレームワーク オブジェクト コンテキスト空間

オブジェクト コンテキスト領域 は、ドライバーが割り当ててオブジェクトに割り当てることができる追加の、ページ不可能なメモリ領域です。 各フレームワーク ベースのドライバーは、ドライバーが受信または作成するすべてのフレームワーク オブジェクトに対して 1 つ以上のオブジェクト固有のコンテキスト空間を作成できます。

フレームワーク ベースのドライバーは、値またはポインターによって、データが属するオブジェクトのコンテキスト空間内のすべてのオブジェクト固有のデータを格納する必要があります。

たとえば、USB デバイス用のドライバーは、そのフレームワーク デバイス オブジェクトのコンテキスト領域を作成する場合があります。 コンテキスト空間では、ドライバーは、デバイスの USB_DEVICE_DESCRIPTORUSB_CONFIGURATION_DESCRIPTOR 構造体などのデバイス固有の情報に加えて、デバイス インターフェイスのパイプを表す コレクション オブジェクト へのハンドルを格納する場合があります。

フレームワークは、あるドライバーから別のドライバーにフレームワーク オブジェクトを渡さないため、オブジェクトのコンテキスト空間を使用して 2 つのドライバー間でデータを渡すことはできません。

オブジェクトのコンテキスト空間を定義するには、1 つ以上の構造体を作成する必要があります。 各構造体は、個別のコンテキスト空間を表します。 ドライバーは、各構造体メンバーを使用して、オブジェクト固有の情報の一部を格納します。 さらに、ドライバーは、構造体ごとに アクセサー メソッド を生成するフレームワークを要求する必要があります。 このアクセサー メソッドは、オブジェクト ハンドルを入力として受け取り、オブジェクトのコンテキスト空間のアドレスを返します。

ドライバーが WdfDeviceCreate などのオブジェクト作成メソッドを呼び出すたびに、メソッドは必要に応じてコンテキスト領域を割り当てます。 すべてのオブジェクト作成メソッドは、省略可能な WDF_OBJECT_ATTRIBUTES 構造体を入力として受け入れます。 この構造体は、フレームワークがオブジェクトに割り当てるコンテキスト空間を表します。

ドライバーがオブジェクトの作成メソッドを呼び出した後にオブジェクトにコンテキスト領域を追加するには、ドライバーは WdfObjectAllocateContext メソッドを呼び出すことができます。このメソッドは、オブジェクト作成メソッドと同様に、 WDF_OBJECT_ATTRIBUTES 構造体を入力として受け入れます。

フレームワークがオブジェクトにコンテキスト領域を割り当てると、コンテキスト空間もゼロ初期化されます。

フレームワークまたはドライバーがフレームワーク オブジェクトを削除すると、フレームワークはオブジェクトのすべてのコンテキスト空間を削除します。

ドライバーがオブジェクトの作成時にドライバーが割り当てるバッファーへのポインターを格納するコンテキスト領域を使用する場合、ドライバーは、オブジェクトが削除されたときにバッファーの割り当てを解除 する EvtCleanupCallback 関数を提供する必要があります。

ドライバーが作成するオブジェクトのオブジェクトのコンテキスト空間構造とアクセサー メソッドを定義するには、ドライバーは次の手順を使用する必要があります。

  1. 格納するデータを記述する構造を定義します。 たとえば、ドライバーのデバイス オブジェクトのコンテキスト データを作成する場合、ドライバーは、MY_DEVICE_CONTEXTという名前の構造体を定義できます。

  2. WDF_DECLARE_CONTEXT_TYPE マクロまたは WDF_DECLARE_CONTEXT_TYPE_WITH_NAME マクロを使用します。 これらのマクロはどちらも次の操作を行います。

    • WDF_OBJECT_CONTEXT_TYPE_INFO構造体を作成して初期化します。
    • 後でドライバーがオブジェクトのコンテキスト空間にアクセスするために使用するアクセサー メソッドを定義します。 アクセサー メソッドの戻り値は、オブジェクトのコンテキスト空間へのポインターです。

    WDF_DECLARE_CONTEXT_TYPE マクロは、構造体の名前からアクセサー メソッドの名前を作成します。 たとえば、コンテキスト構造の名前がMY_DEVICE_CONTEXT場合、マクロは WdfObjectGet_MY_DEVICE_CONTEXT という名前のアクセサー メソッドを作成します。

    WDF_DECLARE_CONTEXT_TYPE_WITH_NAME マクロを使用すると、アクセサー メソッドの名前を指定できます。 たとえば、デバイス オブジェクトのコンテキスト アクセサー メソッドの名前として GetMyDeviceContext を指定できます。

  3. WDF_OBJECT_ATTRIBUTES_INITを呼び出して、オブジェクトのWDF_OBJECT_ATTRIBUTES構造体を初期化します。

  4. WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE マクロを使用して、 WDF_OBJECT_ATTRIBUTES 構造体の ContextTypeInfo メンバーをWDF_OBJECT_CONTEXT_TYPE_INFO構造体のアドレスに設定します。

  5. WdfDeviceCreate などのオブジェクト作成メソッドを呼び出します。

ドライバーがオブジェクトを作成した後、ドライバーはいつでも WdfObjectAllocateContext を呼び出して、オブジェクトにコンテキスト領域を追加できます。

手順 1 と 2 ではグローバル データ構造を定義し、ドライバー呼び出し可能なルーチンを作成するため、ドライバーは、グローバル データを宣言するドライバーの領域 (通常はヘッダー ファイル) でこれらの手順を完了する必要があります。 これらの手順は、ドライバーのルーチン内から完了することはできません。

ドライバーは、WdfDeviceCreate を呼び出す EvtDriverDeviceAdd コールバック関数など、オブジェクトを作成するドライバー ルーチン内から手順 3、4、5 を完了する必要があります。

フレームワークでは、ドライバーの代わりに、フレームワーク要求オブジェクトとフレームワーク ファイル オブジェクトという 2 種類のオブジェクトを作成できます。 ドライバーは、 それぞれ WdfDeviceInitSetRequestAttributesWdfDeviceInitSetFileObjectConfig を呼び出すことによって、これらのオブジェクトのコンテキスト領域を登録できます。 ドライバーは 、WdfObjectAllocateContext を呼び出して、これらのオブジェクトのコンテキスト領域を割り当てることもできます。

オブジェクトが作成された後、ドライバーは、次のいずれかの手法を使用して、オブジェクトのコンテキスト空間へのポインターを取得できます。

ドライバーにコンテキスト空間ポインターがある場合は、 WdfObjectContextGetObject を呼び出すことによって、コンテキスト空間が属するオブジェクトを見つけることができます。