ACX WDF ドライバーの有効期間管理
このトピックでは、ACX WDF ドライバーの有効期間管理と適切なメモリ クリーンアップの概要について説明します。 ACX の一般的な概要については、「 ACX オーディオ クラス拡張機能の概要」を参照してください。
Note
ACX ヘッダーとライブラリは、WDK 10.0.22621.2428 (2023 年 10 月 24 日リリース) には含まれていませんが、以前のバージョンと WDK の最新 (25000 シリーズ ビルド) Insider Preview で使用できます。 WDK のプレビュー バージョンの詳細については、「 Windows Driver Kit (WDK) のプレビュー バージョンのインストール」を参照してください。
ACX WDF の初期化と起動
ACX、WDF、およびメモリ リソースの適切なクリーンアップを可能にするには、ACX の初期化を適切に行う必要があります。 ここで要約したデバイス列挙体の主要なフェーズの詳細については、「ACX デバイス列挙体」を参照してください。
- WDM ドライバー エントリ
- WDF デバイスの追加
- WDF ハードウェアの準備
- WDF デバイスの D0 エントリ
- ACX 回線作成プロセス (ACX ピンおよびジャック オブジェクトは回線に関連付けられます)
- ACX ストリーム作成プロセス
ACX WDF オブジェクト クリーンアップ
このトピックでは、この順序で行う ACX WDF オブジェクトのクリーンアップについて説明します。
- ACX ストリームを閉じるプロセス
- ACX 回路の取り外しプロセス
- WDF デバイス リリース ハードウェア
- WDF ドライバーのアンロード
WDF オブジェクトと ACX オブジェクトを作成してクリーンアップする有効な方法は複数あります。このトピックでは、ACX/WDF オブジェクトの有効期間を管理するための重要な要素のいくつかについて説明します。
PnP 電源イベントとオブジェクトの破棄
PnP 電源イベントによって、オブジェクトの作成と破棄が生じる可能性があります。 PnP 電源イベントの詳細については、「ACX 電源管理」と WDF の「PnP および電源管理コールバック シーケンス」を参照してください。
WDF オブジェクト参照の有効期間の管理
WDF は参照カウントを使用して、オブジェクトの有効期間を追跡します。 オブジェクト参照を逆参照するには、クリーンアップ コールバック関数で行うことが適切な場合があります。 フレームワークはこのクリーンアップ コールバック関数を呼び出します。これによりドバイラーは、削除中のオブジェクトに対して以前 WdfObjectReference を呼び出したことがある場合、WdfObjectDereference を呼び出すことができます。 詳しくは、「WdfObjectReference」 と 「WdfObjectDereference」 を参照してください。
Surface チームのドライバー開発に関するベスト プラクティス
メモリとオブジェクトの有効期間管理を使用してドライバー コードで行われる一般的な間違いの説明については、Surface チームのドライバー開発に関するベスト プラクティスの該当セクションを参照してください。
ACX ストリームを閉じるプロセス
クライアントがストリームを閉じると、ドライバーは、ストリームに関連付けられていたリソースを閉じてクリーンアップするために動作する必要があります。 詳細については、「ACX ストリーミング - ストリームを閉じるプロセス」を参照してください。 ドライバーではストリームをサポートするリソースがクリーンアップされないこと、およびクリーンアップ プロセスがクライアントへの影響を認識することが重要です。
ACX 回路の取り外しプロセス
ACX は、必要に応じて動的回線を作成できます。 このため、ドライバーは、WdfPdoInitAllocate を呼び出して WDFDEVICE_INIT 構造体を割り当てます。 その後、ドライバーは、受信する PnP/電源コールバックを指定し、デバイスを作成します。 ドライバーは、デバイスの一覧からオーディオ デバイスを削除するために、AcxDeviceRemoveCircuitDevice を呼び出します。
詳細については、「ACX 回線」の「ACX 回線の動的な取り外し」を参照してください。
WDF デバイス リリース ハードウェア
EVT_WDF_DEVICE_RELEASE_HARDWARE コールバック関数は、デバイスがアクセスできなくなったときに必要な操作を実行するために、ドライバーの EvtDeviceReleaseHardware イベント コールバック関数で使用されます。
WDF デバイス コンテキスト クリーンアップ
AudioCodec サンプルのこのコードが示すのは、WDF_OBJECT_ATTRIBUTES 構造体を使用して EvtCleanupCallback を設定する方法です。
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, CODEC_DEVICE_CONTEXT);
attributes.EvtCleanupCallback = Codec_EvtDeviceContextCleanup;
次に示すのは、WdfDevice でデバイス コンテキストがクリーンアップされたと仮定した場合のコールバック例です。
VOID
Codec_EvtDeviceContextCleanup(
_In_ WDFOBJECT WdfDevice
)
{
WDFDEVICE device;
PCODEC_DEVICE_CONTEXT devCtx;
device = (WDFDEVICE)WdfDevice;
devCtx = GetCodecDeviceContext(device);
ASSERT(devCtx != nullptr);
if (devCtx->Capture)
{
CodecC_CircuitCleanup(devCtx->Capture);
}
}
WDF ドライバーのアンロード
ドライバーがアンロードされると、残りのリソースはすべて解放されます。 詳細については、「ドライバー割り当てリソースの解放」を参照してください。
ドライバーは、WdfDriverCreate を呼び出すときに EvtDriverUnload コールバック関数を登録します。 EvtDriverUnload コールバック関数は、ドライバーの DriverEntry ルーチンが割り当てたデバイス固有のシステム リソース以外の割り当てを解除する必要があります。 詳細については、「EVT_WDF_DRIVER_UNLOAD コールバック関数」を参照してください。
AudioCodec サンプルのこのコードが示すのは、ドライバー アンロード コールバックの構造体です。
EVT_WDF_DRIVER_UNLOAD AudioCodecDriverUnload;
void AudioCodecDriverUnload(
_In_ WDFDRIVER Driver
)
{
PAGED_CODE();
if (!Driver)
{
ASSERT(FALSE);
return;
}
WPP_CLEANUP(WdfDriverWdmGetDriverObject(Driver));
// Here is where you would cleanup any allocated resources associated with the driver.
return;
}