EVT_WDF_OBJECT_CONTEXT_CLEANUP コールバック関数 (wdfobject.h)
[KMDF と UMDF に適用]
ドライバーの EvtCleanupCallback イベント コールバック関数は、オブジェクトを削除できるように、オブジェクトに対するドライバーの参照を削除します。
構文
EVT_WDF_OBJECT_CONTEXT_CLEANUP EvtWdfObjectContextCleanup;
void EvtWdfObjectContextCleanup(
[in] WDFOBJECT Object
)
{...}
パラメーター
[in] Object
フレームワーク オブジェクトへのハンドル。
戻り値
なし
解説
ドライバーは、WDF_OBJECT_ATTRIBUTES構造体で EvtCleanupCallback コールバック関数を指定できます。 この構造体は、 WdfDeviceCreate などのフレームワーク オブジェクトを作成するすべてのフレームワーク メソッドへの入力として使用されます。
フレームワークまたはドライバーがオブジェクトの削除を試みると、フレームワークはコールバック関数を呼び出します。
ドライバーが WdfObjectReference を呼び出してオブジェクトの参照数を増やす場合、ドライバーは WdfObjectDereference を呼び出す EvtCleanupCallback コールバック関数を提供する必要があります。 この呼び出しにより、オブジェクトの参照カウントが 0 に減り、その結果、フレームワークはドライバーの EvtDestroyCallback コールバック関数を呼び出し、オブジェクトを削除できます。
ドライバーがオブジェクトの EvtCleanupCallback コールバック関数と EvtDestroyCallback コールバック関数の両方を提供する場合、フレームワークは最初 に EvtCleanupCallback コールバック関数を呼び出します。
フレームワークがオブジェクトの EvtCleanupCallback コールバック関数を呼び出した後、ドライバーは EvtDestroyCallback コールバック関数からのみオブジェクトにアクセスできます。 ただし、ドライバーは EvtDestroyCallback からオブジェクトのメソッドを呼び出そうとしないでください。
ドライバーは、オブジェクトを作成するときに、オブジェクト固有のメモリ バッファーを割り当て、オブジェクトの コンテキスト空間にバッファー ポインターを格納することがあります。 ドライバーの EvtCleanupCallback または EvtDestroyCallback コールバック関数は、これらのメモリ バッファーの割り当てを解除できます。
通常、ドライバーがオブジェクトに対して WdfObjectReference を呼び出さない場合、オブジェクトの EvtCleanupCallback コールバック関数はオブジェクト コンテキスト割り当てを解除できます。 この場合、ドライバーには、オブジェクトの EvtDestroyCallback コールバック関数は必要ありません。
オブジェクトが削除されると、フレームワークはオブジェクトの子も削除します。 1 つの例外では、フレームワークは子オブジェクトの EvtCleanupCallback ルーチンを呼び出してから親オブジェクトを呼び出すので、ドライバーは、子の EvtCleanupCallback ルーチンの実行時に親オブジェクトがまだ存在することが保証されます。
この保証順序付けの例外は、ドライバーがDISPATCH_LEVELで完了する I/O 要求に適用されます。 このような I/O 要求オブジェクトに、 PASSIVE_LEVELで EvtCleanupCallback ルーチンを呼び出す必要がある 1 つ以上の子がある場合は、その子の 1 つ以上の前に親要求が削除される可能性があります。 オブジェクトが完了するまで待機する必要がある場合、またはページ メモリにアクセスする場合は、PASSIVE_LEVELでクリーンアップが必要です。
ドライバーがDISPATCH_LEVELで実行中にこのようなオブジェクト (またはそのようなオブジェクトの親) を削除しようとすると、フレームワークは、後で処理するために作業項目に EvtCleanupCallback をキューに入れ、PASSIVE_LEVELで親オブジェクトのクリーンアップ コールバックを呼び出します。その後、子のコールバックが実行されたかどうかを判断せずに、親オブジェクトのクリーンアップ コールバックを呼び出します。
この動作によって発生する可能性のある問題を回避するために、ドライバーは、PASSIVE_LEVELでクリーンアップを必要とするオブジェクトの親として要求オブジェクトを設定しないでください。 既定では、ほとんどのオブジェクトの親は WDFDEVICE であるため、ドライバーは既定値をそのまま使用する必要があります。 一般に、WDFDEVICE オブジェクトが、オブジェクトを作成するメソッドにパラメーター (直接または構造体の一部として) として渡される場合、WDFDEVICE が既定の親になります。 既定の親の完全な一覧については、「 Framework オブジェクトの概要」を参照してください。
上記の例外が適用されない場合、フレームワークは親オブジェクトの EvtCleanupCallback コールバック関数を呼び出す前に、子オブジェクトの EvtCleanupCallback コールバック関数を呼び出します。 次に、子の参照カウントが 0 の場合、フレームワークは子オブジェクトの EvtDestroyCallback コールバック関数を呼び出します。 最後に、親の参照カウントが 0 の場合、フレームワークは親オブジェクトの EvtDestroyCallback コールバック関数を呼び出します。
フレームワーク オブジェクトの削除の詳細については、「 Framework オブジェクトのライフ サイクル」を参照してください。
通常、フレームワークは IRQL <= DISPATCH_LEVEL で EvtCleanupCallback コールバック関数を呼び出します。 ただし、フレームワークは、次の状況で IRQL = PASSIVE_LEVELでコールバック関数を呼び出します。
- オブジェクトのハンドルの種類は、WDFDEVICE、WDFDRIVER、WDFDPC、WDFINTERRUPT、WDFIOTARGET、WDFQUEUE、WDFSTRING、WDFTIMER、または WDFWORKITEM です。
- オブジェクトのハンドルの種類は WDFMEMORY または WDFLOOKASIDE であり、ドライバーは PoolType パラメーターに PagedPool を WdfMemoryCreate または WdfLookasideListCreate に指定しています。
同様に、タイマー オブジェクトが明示的に削除された場合、またはタイマーの親オブジェクトが削除されている場合、タイマーの EvtCleanupCallback コールバック関数を呼び出す前に、フレームワークはタイマーの EvtTimerFunc イベント コールバック関数のすべてのインスタンスが返されるまで待機します。
フレームワークのバージョン 1.9 以降、 wdfroletypes.h ヘッダー ファイルには、 EvtCleanupCallback コールバック関数の代替のオブジェクト型固有の関数型が含まれています。 これらの代替型は、ドライバーがコールバック関数を正しく使用しているかどうかを確認するための検証ツールに役立ちます。 使用する関数の種類を確認するには、次の表を使用します。
オブジェクトの型 | [関数の種類] |
---|---|
デバイス オブジェクト | EVT_WDF_DEVICE_CONTEXT_CLEANUP |
I/O キュー オブジェクト | EVT_WDF_IO_QUEUE_CONTEXT_CLEANUP_CALLBACK |
File オブジェクト | EVT_WDF_FILE_CONTEXT_CLEANUP_CALLBACK |
他のすべてのオブジェクト | EVT_WDF_OBJECT_CONTEXT_CLEANUP |
要件
要件 | 値 |
---|---|
対象プラットフォーム | ユニバーサル |
最小 KMDF バージョン | 1.0 |
最小 UMDF バージョン | 2.0 |
Header | wdfobject.h (Wdf.h を含む) |
IRQL | 「解説」を参照してください。 |