Windows Driver Frameworks (WDF) ドライバーが WdfDeviceStopIdle を呼び出すと、フレームワークはデバイスの電源参照数をインクリメントします。 WdfDeviceStopIdle への正常な呼び出しはすべて、電源参照数を減らすため、WdfDeviceResumeIdle の呼び出しと一致している必要があります。
カーネルモード ドライバー フレームワーク (KMDF) 1.15 およびユーザーモード ドライバー フレームワーク (UMDF) 2.15 以降では、!wdfkd.wdfdevice および !wdfkd.wdftagtracker デバッガー拡張機能を使用して電源参照の使用状況を監視できます。 この機能は、パフォーマンス上の理由から既定で無効になっているため、WdfVerifier アプリケーションで、またはドライバーのサービス キーを手動で編集して有効にする必要があります。
WdfVerifier
ドライバーの設定一覧を開き、[TrackPower] 設定を右クリックします。 シナリオに適したオプションを選択します。
ヒント: パフォーマンスが重要ななコード パスでスタック トレースをキャプチャしないようにします。
レジストリ編集
ドライバーのサービス キーを編集して、検証ツールのサポートと電源参照の追跡を有効にすることもできます。
KMDF ドライバーの場合:
HKLM\SYSTEM\ControlSet001\Services\<Driver Service Name>\Parameters\Wdf
UMDF ドライバーの場合:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WUDF\Services\<Driver Service Name>\Parameters\Wdf
(REG_DWORD) VerifierOn = 0x1
(REG_DWORD) TrackPower = 0x0 (disabled)
= 0x1 (capture tick count, file name, line number)
= 0x2 (capture tick count, file name, line number, and stack traces)
ドライバー コード
ドライバーは、WdfDeviceStopIdle と WdfDeviceResumeIdle を呼び出して、デバイスの動作電源状態を次のように管理します。
//
// Take power reference
//
status = WdfDeviceStopIdle(device, FALSE);
if (NT_SUCCESS(status)) {
//
// Release power reference
//
WdfDeviceResumeIdle(device);
}
WdfKd を使用したデバッグ
デバイスで取得された電源参照と、参照履歴を示すタグ トラッカーを表示するには、詳細フラグを指定して !wdfkd.wdfdevice を使用します。
kd> !wdfkd.wdfdevice 0x6d939790 ff
Power references: 0 !wdftagtracker 0x9ea030a8
!wdfkd.wdftagtracker を呼び出すと、デバイスの電源参照履歴が表示されます。
kd> !wdftagtracker 0x9ea030a8
Reference and Release History:
# (showing most recent first; refcount is approximate in multi-threaded scenarios)
## 3 entries, history depth is 25
(--) 0 ref: Tag '....' at Time 0x1331e ticks
## path\to\your\driver\code.c @ 374
(++) 1 refs: Tag '....' at Time 0x1331e ticks
## path\to\your\driver\code.c @ 372
(++) Initial Tag '....' at Time 0x12c9a ticks
タグの指定
必要に応じて、特定の電源参照の識別を容易にするタグ名を指定します。 これを行うには、WdfDeviceStopIdleWithTag と WdfDeviceResumeIdleWithTag を使用します。
status = WdfDeviceStopIdleWithTag(device, FALSE, (PVOID)'oyeH');
if (NT_SUCCESS(status)) {
WdfDeviceResumeIdleWithTag(device, (PVOID)'oyeH');
}
対応する !wdftagtracker サンプル出力:
(--) 0 ref: Tag 'Heyo' at Time 0x24e40 ticks
## path\to\your\driver\code.c @ 374
(++) 1 refs: Tag 'Heyo' at Time 0x24e40 ticks
## path\to\your\driver\code.c @ 372
(++) Initial Tag '....' at Time 0x12c9a ticks