第 9 章 実行に当たっての問題
11.5 WinDriver Kernel PlugIn の構造
11.5.1 構造の概要
ユーザーモードで記述したドライバは、デバイスにアクセスする際に WinDriver の関数 (WDC_xxx および/
または WD_xxx) を使用します。ユーザーモードで実装され、カーネルレベルのパフォーマンスの達成が
必要な関数 (割り込み処理など) の場合、WinDriver Kernel PlugIn に移します。通常、ユーザーモードと
Kernel PlugIn の両方で同じ WinDriver API をサポートしているので、コードの修正をせずに、ユーザー
モードからカーネルへ WDC_xxx / WD_xxx 関数呼び出しを使用するようにコードを移行できます。
アプリケーション ( YourApp.EXE )
ドライバ コード
WinDriver ユーザーモード ライブラリ
(WinDrvr.h)
WinDriver カーネル
(WinDrvr.VXD、
WinDrvr.SYS) WinDriver
Kernel PlugIn 関数
KP_Init() KP_Open() KP_IntAtIrq() KP_IntAtDpc()
KP_Call() KP_Close()
Kernel PlugIn
I/O 割り込み 割り込み処理
メッセージ 受け渡し
WinDriver コンポーネント
記述するコンポーネント
ユーザー モード カーネル モード
ハードウェア アプリケーション
( YourApp.EXE )
ドライバ コード
WinDriver ユーザーモード ライブラリ
(WinDrvr.h)
WinDriver カーネル
(WinDrvr.VXD、
WinDrvr.SYS) 記述するコンポーネント
WinDriver コンポーネント
WinDriver Kernel PlugIn 関数
KP_Init() KP_Open() KP_IntAtIrq() KP_IntAtDpc()
KP_Call() KP_Close()
Kernel PlugIn
I/O 割り込み 割り込み処理
メッセージ 受け渡し
ユーザー モード カーネル モード
ハードウェア
図 11.1: KernelPlugIn の構造
11.5.2 WinDriver Kernel と Kernel Plugin のインターフェイス
WinDriver カーネルと WinDriver Kernel PlugIn は次の 2 種類のインターフェイスがあります。
1. 割り込み処理: WinDriver が割り込みを受け取ると、ユーザーモードの割り込み処理をデフォルト で有効にします。しかし、割り込みを Kernel PlugIn ドライバが処理するように設定し、WinDriver が 割り込みを受信すると、Kernel PlugIn ドライバのカーネルモードで割り込み処理が始動します。
Kernel PlugIn 割り込み処理は、基本的に Kernel PlugIn へ移動する前にユーザーモードで割り込
み処理を記述およびデバッグしていたコードと同様ですが、ユーザーモードのコードの一部を編 集する必要があります。KernelPlugIn で割り込みの検知および処理を行うコードを再記述し、
KernelPlugIn の柔軟性を有効にします (セクション 11.6.5 を参照してください)。
2. メッセージ受け渡し: カーネル モードで関数を実行する場合 (I/O 処理関数など)、ユーザー モー ドのドライバは WinDriver Kernel PlugIn に「メッセージ」を渡します。このメッセージは特定の関数 にマップされ、カーネル内で実行されます。この関数はユーザー モードで開発されたものと同じ コードが含まれます。
ユーザー モード アプリケーションから Kernel PlugIn ドライバへメッセージを使用してデータを渡す こともできます。
11.5.3 Kernel Plugin コンポーネント
Kernel PlugIn の開発サイクルを終了すると、作成したドライバは以下のエレメントを持つことになります。
z WDC_xxx / WD_xxx API 関数で記述されたユーザー モード ドライバ アプリケーション(<アプリ ケーション名>/.exe)。
z WinDriver カーネルモジュール (windrvr6/.sys/.o)。
z カーネル レベルへ移動したドライバ機能を含む WDC_xxx / WD_xxx API 関数で記述された Kernel PlugIn ドライバ (<Kernel PlugIn ドライバ名>/.sys/.o)
11.5.4 Kernel PlugIn イベント シーケンス
次に Kernel PlugIn で実装できるすべての関数の一般的なイベント シーケンスを示します。
11.5.4.1 ユーザー モードから Kernel PlugIn へのハンドルを開く イベント / コールバック 備考
イベント:
Windows は Kernel PlugIn ドライバをロードしま す。
このイベントはブート時にダイナミックロードにより行 われるか、またはレジストリからの指示として行われ ます。
コールバック:
KP_Init() Kernel PlugIn ルーチンを呼び出し ます。
KP_Init() が WinDriver に KP_Open() ルーチンの 名前を知らせます。アプリケーションがドライバを開 く場合 (Kernel PlugIn ドライバを開く名前で WDC_xxxDeviceOpen() を呼び出す場合か、ま たは (ラッパー WDC_xxxDeviceOpen() 関数に 呼び出される) 低水準の
WD_KernelPlugInOpen() 関数を呼び出す場
合)、WinDriver はこのルーチンを呼び出します。
イベント:
ユーザーモードドライバアプリケーションは
Kernel PlugIn ドライバを開く名前で
WDC_xxxDeviceOpen() を呼び出すか、また は (ラッパー WDC_xxxDeviceOpen() 関数に 呼び出される) 低水準の
WD_KernelPlugInOpen() 関数を呼び出しま す。
コールバック:
KP_Open() Kernel PlugIn ルーチンを呼び出し ます。
KP_Open() 関数は WinDriver への Kernel PlugIn ドライバで実装した全コールバック関数名の通知に 使用されます。また、必要に応じて Kernel Plugin ド ライバの開始に使用されます。
11.5.4.2 Kernel PlugIn からのユーザー モード要求処理 イベント / コールバック 備考
イベント:
アプリケーションは WDC_callKerPlug()、ま
たは低水準の WD_KernelPlugInCall() 関
数を呼び出します。
アプリケーションは WDC_CallKerPlug() / WD_KernelPlugInCall() を呼び出し、(Kernel
PlugIn ドライバの) カーネルモードでコードを実行し
ます。アプリケーションは Kernel PlugIn ドライバへ メッセージを渡します。 Kernel PlugIn ドライバは送ら れたメッセージに従って実行するコードを選択しま す。
コールバック:
KP_Call() Kernel PlugIn ルーチンを呼び出し ます。
KP_Call() はユーザー モードより渡されたメッ セージに従ってコードを実行します。
11.5.4.3 割り込み処理の有効化/無効化および高い割り込み要求処理 イベント / コールバック 備考
イベント:
アプリケーションは fUseKP 引数に TRUE を設定 して WDC_IntEnable() を呼ぶか (Kernel PlugIn でデバイスを開いた後)、または、
KernelPlugIn ドライバへのハンドルでより低レベ
ルな InterruptEnable() または
WD_IntEnable()関数を呼びます (関数へ渡さ
れた WD_INTERRUPT 構造体の
hKernelPlugIn フィールドに設定)。 コールバック:
KP_IntEnable() Kernel PlugIn ルーチンを呼 び出します。
この関数には Kernel PlugIn の割り込み処理に必要 な初期化設定を含めてください。
イベント:
ハードウェアが割り込みを発生します。
コールバック:
KP_IntAtIrql() Kernel PlugIn ルーチンを呼 び出します。
KP_IntAtIrql() は高い優先度で実行されるた め、基本的な割り込み処理 (割り込みを識別するた めに、レベル センシティブ割り込みの HW 割り込み シグナルの低くするなど) だけを実行します。
より多くの割り込み処理が必要な場合、
KP_IntAtDpc() 関数で追加処理を引き継ぐため に KP_IntAtIrql() は TRUE を返します。
イベント:
割り込みが Kernel PlugIn で有効になっている場 合 (割り込みを有効にするイベントの詳細を参 照) 、アプリケーションは WDC_IntDisable() を呼び出すか、または、低水準の
InterruptDisable() または
WD_IntDisable() 関数を呼び出します。
コールバック:
KP_IntDisable() Kernel PlugIn ルーチンが 呼び出されます。
この関数は KP_IntEnable() コールバックにより 割り当てられたメモリを解放します。
11.5.4.4 割り込み処理 – 異なる処理の呼び出し イベント / コールバック 備考
イベント:
Kernel PlugIn KP_IntAtIrql() 関数が TRUE を戻します。
カーネルで引き継いだ手順として追加の割り込み 処理を WinDriver へ伝えます。
コールバック:
KP_IntAtDpc() Kernel PlugIn ルーチンを呼 び出します。
残りの割り込みコードを処理しますが
KP_IntAtIrql() よりは優先度が低いです。
イベント:
KP_IntAtDpc() は 0 よりも大きい値を戻します
ユーザーモードで処理するための割り込みコード が必要です。
コールバック:
WD_IntWait() を戻します。
ユーザーモード割り込みハンドラから実行が再開さ れます。
11.5.4.5 Plug-and-Play およびパワー マネージメント イベント / コールバック 備考
イベント:
アプリケーションは fUseKP 引数に TRUE を設定
して WDC_EventRegister() を呼んで、
Kernel PlugIn ドライバを使用して、Plug-and-Play およびパワーマネージメントの通知を受け取るよ うに登録します (Kernel PlugIn でデバイスを開い た後)。または、Kernel PlugIn ドライバへのハンド ルでより低レベルな EventRegister() または WD_EventRegister() 関数を呼び出します (関数に渡された WD_EVENT 構造体の hKernelPlugIn フィールドに設定)。 イベント:
Plug-and-Play またはパワーマネージメントイベン
トが発生します。
コールバック:
KP_Event() が呼び出されます。
KP_Event() は、発生したイベントについての情 報を受け取ります。
イベント:
KP_Event() は TRUE を返します。
イベントは、ユーザー モード アプリケーションで処 理される必要があります。
コールバック:
WD_Intwait() を返します。
ユーザーモード割り込みハンドラアプリケーション イベントハンドラで処理を再開します。