Driver Coverage Tool Kit
おひさしぶりです。まさかたです。
以前、A寿さんの Blog の記事の中で、WDK for windows 7 で追加された新しいツールとして、OACR について紹介いたしましたが、この他にも様々なツールが追加されました。
New for Windows 7
https://msdn.microsoft.com/en-us/library/dd434869.aspx
そんな中から、今回は、WDK 7.0.0 に追加された Driver Coverage Took Kit という、ドライバーのテストを補助するツールについて、ご紹介したいと思います。
Driver Coverage Tool Kit とは?
Driver Coverage Tool Kit は、ターゲットとなるドライバーにどんな IRP が、どれだけ流れてきているかを調べることができるツールです。
原理的には、ターゲットとなる任意のドライバーに対し、フィルタードライバーをインストールし、流れる IRP を記録していくというものです。
このツールを使えば、例えば、ドライバーの IRP の Dispatch Routine をテストしているときに、テストでどの Dispatch Routine が網羅されているのか、いないのかなど、Coverage を測ることができます。
そのため、この Tool は、ドライバーのテストそのものを実行するというよりは、テストを補助するためのツールと考えていただいた方がいいと思います。
以下では、Toaster ドライバーを対象に、実際に Driver Coverage Tool Kit を動かした様子を、簡単にご紹介したいと思います。
■ツールの場所
まず、ツールの在り処ですが、WDK の以下のパスに格納されています。
WINDDK\7600.16385.0\tools\drvCov
上記のフォルダーの中で、さらに、CPU アーキテクチャーごとにフォルダーが分かれています。
フォルダーに含まれているファイルは、以下の 4点 ですが、これらのファイルをテスト用のマシンの任意の場所にコピーして使用します。
※今回の記事では、”C:\Workspace” というフォルダーにコピーして使っています。
Ø Drvcov.sys : フィルタードライバー(Driver Coverage Filter driver)
Ø Drvcov.inf : フィルタードライバーをインストールするための INF ファイル
Ø Drvcov.cat : フィルタードライバーをインストールする際に使用するカタログファイル
Ø Drvcov.exe : フィルタードライバーのインストールや、IRP のキャプチャを開始したりするコマンドラインツール
■使用手順
Driver Coverage Tool Kit を使う場合の大まかな手順は以下のようになります。
1. ターゲットとなるドライバーの ID を確認
2. ターゲットのドライバーにフィルタードライバーをインストール
3. IRP 計測用のバッファをクリア
4. 目的のドライバーで IRP のやり取りを発生させる
5. 結果を出力、分析
6. フィルタードライバーをアンインストール
今回は、ターゲットとするドライバーとして Toaster を使用して、実際に上記の手順を追っていきます。
なお、以下で実行するコマンドプロンプトは、管理者権限で起動しておく必要がありますので、ご注意ください。
1. ターゲットとなるドライバーの ID を確認
Driver Coverage Tool Kit の原理としては、調べる対象のドライバーの Upper または、Lower に フィルタードライバー(Driver Coverage Filter driver) をインストールして、流れてくる IRP を監視し、それぞれの数をカウントしています。
そのフィルタードライバーが、DrvCov.sys になります。
というわけで、ツールを使うためには、調べるドライバーを予め OS にインストールしておき、さらに、DrvCov.sys を目的のドライバーのフィルタードライバーとしてインストールしておかなくてはなりません。
そして、上記のインストールを行う時に、どのドライバーのフィルタードライバーとしてインストールするかを指定するのに、ID を使います。
ID には、Devnode # というのと、Device ID が指定可能です。
この ID を知るために、” /DA” オプションで、さらにパラメーターに “1” を指定することで、すべてのデバイスの Devnode # と Device ID を表示させます。
C:\WorkSpace> drvcov.exe /DA 1 Devnode #: 2080 Class: Net Desc: Microsoft 6to4 Adapter |Device ID : ROOT\*6TO4MP000 Devnode #: 2120 Class: Net Desc: Microsoft ISATAP Adapter |Device ID : ROOT\*ISATAP000 Devnode #: 2160 Class: Computer Desc: ACPI x86 PC |Device ID : ROOT\ACPI_HAL000 Devnode #: 2204 Class: System Desc: Microsoft ACPI-Compliant System |Device ID : ACPI_HAL\PNP0C08 … (中略) … Devnode #: 11572 Class: System Desc: Toaster Bus Enumerator |Device ID : ROOT\UNKNOWN001 Devnode #: 11612 FN: ToasterDevice01 Class: TOASTER Desc: Microsoft Toaster With Coinstaller |Device ID : {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&7F60330&0&01 |
Toaster のインスタンス 01 の Devnode # は、11612 ということなので、以後のコマンド実行でデバイスを指定する必要がある場合には、この ID を使用します。
ちなみに、この Devnode # は、OS が再起動する毎に変わる可能性があるので、注意が必要です。
2. Filter のインストール
Toaster の Upper にフィルタードライバーをインストールする際は、以下のとおり、” /A” オプションで可能です。
C:\WorkSpace>drvcov.exe /A 11612 Add our upper filter to: Devnode #: 11612 FN: ToasterDevice01 Class: TOASTER Desc: Microsoft Toaster With Coinstaller Process path Raw path : drvcov.exe Relative path : Absolute path : C:\WorkSpace\Blog_20090824\DrvCov_i386 Absolute Inf File : C:\WorkSpace\Blog_20090824\DrvCov_i386\Drvcov.INF Process INF File : C:\WorkSpace\Blog_20090824\DrvCov_i386\Drvcov.INF Add Service. ( Run INF section DRVCOV.Service) Copy files. ( Run INF section DRVCOV.Files): ............ Process Devnode 11612l Add filter driver
NOTE: You need to reboot to load the filter driver. |
メッセージにも書かれているように、フィルタードライバーをロードするには、再起動が必要です。
再起動後に、デバイスマネージャーで確認してみると、確かに、フィルタードライバー drvCov.sys がロードされているのがわかります。
ちなみに、Lower にインストールする場合は、” /AL” オプションでインストール可能です。
C:\WorkSpace>drvcov.exe /AL 11612 Add our lower filter to: Devnode #: 11612 FN: ToasterDevice01 Class: TOASTER Desc: Microsoft Toaster With Coinstaller Process path Raw path : drvcov.exe Relative path : Absolute path : C:\WorkSpace\Blog_20090824\DrvCov_i386 Absolute Inf File : C:\WorkSpace\Blog_20090824\DrvCov_i386\Drvcov.INF Process INF File : C:\WorkSpace\Blog_20090824\DrvCov_i386\Drvcov.INF Add Service. ( Run INF section DRVCOV.Service) Copy files. ( Run INF section DRVCOV.Files): ............ Process Devnode 11612l Add filter driver
NOTE: You need to reboot to load the filter driver. |
また、drvcov.exe の ” /DF” オプションでも、フィルターがインストールされているドライバーを確認することができます。
ただし、フィルタードライバーはインストールされていても、実際にはロードされていないドライバーも表示されます。
C:\WorkSpace>drvcov.exe /DF |------------------------------------------------------------------ | List of devices that are filtered by the Driver Coverage driver. |------------------------------------------------------------------ | Devnode #: 10600 FN: ToasterDevice01 Class: TOASTER Desc: Microsoft Toaster With Coinstaller | - Drvcov Filter : Lower Upper | 1 device(s) found. |------------------------------------------------------------------ |
“ /D” オプションを使えば、現在、ドライバーが実際にロードされていて、データーの収集が可能なもののみが表示されます。
C:\WorkSpace>drvcov.exe /D |------------------------------------------------------------------ | List of devices we can get coverage data from. |------------------------------------------------------------------ | Device # : 1 | Devnode #: 10600 FN: ToasterDevice01 Class: TOASTER Desc: Microsoft Toaster With Coinstaller | Device ID: "{B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&1AAFB3D5&0&01" |------------------------------------------------------------------ | 1 device(s) found. |------------------------------------------------------------------ |
3. バッファのクリア
さて、IRP の測定に入る前に、前回測定したバッファがあれば、それをクリアしておく必要があります。
今回は初めて測定を行うので必要ありませんが、コマンドで実行すると以下のような出力となります。(“ /E” オプション)
C:\WorkSpace> drvcov /E 11612 Clear IRP coverage data for device: Friendly Name : Microsoft Toaster With Coinstaller DeviceInstId : {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&7F60330&0&01 |
4. IRP のやり取りを発生させる
今回は、以下の操作を実行してみました。
- Enum.exe で、Unplug/Plug-in を繰り返す
- Toast.exe で Read を繰り返す
- システムを Sleep -> 復帰
5. 結果の出力
それでは、実際に流れた IRP を見てみます。
結果の出力には、“ /C” オプションを使います。
C:\WorkSpace>drvcov.exe /C 11612 Getting coverage data Data source Source Type: Driver Source Name: \\.\DrvcovControl2 Device Friendly Name : Microsoft Toaster With Coinstaller Class Name : TOASTER Device ID : {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&1AAFB3D5&0&01 Device # : 1 Devnode # : 10600
|--------------------------------------------------------| | MJ & MN Device irp coverage | ß------ ① |--------------------------------------------------------| | IRPS covered 24 | # of times | |--------------------------------------------------------| | CREATE | 15 | | PNP\QUERY_INTERFACE | 9 | | READ | 61 | | CLEANUP | 5 | | CLOSE | 5 | | PNP\QUERY_DEVICE_RELATIONS\Target | 6 | | PNP\QUERY_DEVICE_RELATIONS\Removal | 2 | | PNP\QUERY_DEVICE_RELATIONS\Eject | 2 | | PNP\SURPRISE_REMOVAL | 2 | | PNP\REMOVE_DEVICE | 2 | | Unknown | 12 | | PNP\QUERY_RESOURCE_REQUIREMENTS | 2 | | PNP\FILTER_RESOURCE_REQUIREMENTS | 2 | | PNP\START_DEVICE | 6 | | PNP\QUERY_CAPABILITIES | 4 | | PNP\QUERY_PNP_DEVICE_STATE | 2 | | PNP\QUERY_DEVICE_TEXT | 2 | | PNP\QUERY_ID | 2 | | PNP\QUERY_DEVICE_RELATIONS\Bus | 2 | | WMI\REGINFO_EX | 2 | | POWER\QUERY_POWER\SYSTEM | 3 | | POWER\QUERY_POWER\DEVICE | 1 | | POWER\SET_POWER\SYSTEM | 5 | | POWER\SET_POWER\DEVICE | 3 | |--------------------------------------------------------| | IRPS NOT covered 28 | | |--------------------------------------------------------| | WRITE | | | FLUSH_BUFFERS | | | DEVICE_CONTROL | | | INTERNAL_DEVICE_CONTROL | | | SHUTDOWN | | | POWER\WAIT_WAKE | | | WMI\QUERY_ALL_DATA | | | WMI\QUERY_SINGLE_INSTANCE | | | WMI\CHANGE_SINGLE_INSTANCE | | | WMI\CHANGE_SINGLE_ITEM | | | WMI\ENABLE_EVENTS | | | WMI\DISABLE_EVENTS | | | WMI\ENABLE_COLLECTION | | | WMI\DISABLE_COLLECTION | | | WMI\REGINFO | | | WMI\EXECUTE_METHOD | | | PNP\QUERY_REMOVE_DEVICE | | | PNP\CANCEL_REMOVE_DEVICE | | | PNP\STOP_DEVICE | | | PNP\QUERY_STOP_DEVICE | | | PNP\CANCEL_STOP_DEVICE | | | PNP\QUERY_RESOURCES | | | PNP\READ_CONFIG | | | PNP\WRITE_CONFIG | | | PNP\EJECT | | | PNP\SET_LOCK | | | PNP\QUERY_BUS_INFORMATION | | | PNP\DEVICE_USAGE_NOTIFICATION | | |--------------------------------------------------------| | Stats | |--------------------------------------------------------| | Total IRP count : 52 | | Covered IRP count : 24 | | NOT Covered IRP count : 28 | | Covered IRP % : 46.15% | | NOT Covered IRP % : 53.85% | |--------------------------------------------------------|
|--------------------------------------------------------| | MJ Device irp coverage | ß------ ② |--------------------------------------------------------| | IRPS covered 8 | # of times | |--------------------------------------------------------| | IRP_MJ_CREATE | 15 | | IRP_MJ_PNP | 45 | | IRP_MJ_READ | 61 | | IRP_MJ_CLEANUP | 5 | | IRP_MJ_CLOSE | 5 | | IRP_MJ_UNKNOWN | 12 | | IRP_MJ_SYSTEM_CONTROL | 2 | | IRP_MJ_POWER | 12 | |--------------------------------------------------------| | IRPS NOT covered 5 | | |--------------------------------------------------------| | IRP_MJ_WRITE | | | IRP_MJ_FLUSH_BUFFERS | | | IRP_MJ_DEVICE_CONTROL | | | IRP_MJ_INTERNAL_DEVICE_CONTROL | | | IRP_MJ_SHUTDOWN | | |--------------------------------------------------------| | Stats | |--------------------------------------------------------| | Total IRP count : 13 | | Covered IRP count : 8 | | NOT Covered IRP count : 5 | | Covered IRP % : 61.54% | | NOT Covered IRP % : 38.46% | |--------------------------------------------------------|
|--------------------------------------------------------| | MJ & MN Device IRP Concurrency pairs. | ß------ ③ |--------------------------------------------------------| | IRP Pairs covered 4 | # of times | |--------------------------------------------------------| | CREATE | | | PNP\QUERY_INTERFACE | 5 | |--------------------------------------------------------| | POWER\SET_POWER\SYSTEM | | | POWER\SET_POWER\DEVICE | 2 | |--------------------------------------------------------| | POWER\QUERY_POWER\SYSTEM | | | POWER\QUERY_POWER\DEVICE | 1 | |--------------------------------------------------------| | PNP\START_DEVICE | | | PNP\QUERY_CAPABILITIES | 2 | |--------------------------------------------------------| |--------------------------------------------------------| | Stats | |--------------------------------------------------------| | Total IRP pairs : 1099 | | Covered IRP pairs : 4 | | NOT Covered IRP pairs : 1095 | | Covered IRP pairs % : 0.36% | | NOT Covered IRP pairs % : 99.64% | |--------------------------------------------------------|
|
この出力は、3つのセクションに分かれています。
① MJ & MN Device irp coverage (IRP Major (MJ) and Minor (MN) Coverage Data)
様々な Major Function IRP と、Minor Function IRP の中で、テスト中にドライバーによって処理された IRP と、処理されていない IRP の種類と数がそれぞれ表示されます。
これによって、実施したテストの IRP の Coverage がどれだけであるか、またどの IRP のテストが足りないかを知ることができます。
② MJ Device Irp coverage (IRP MJ Coverage Data)
IRP の Major Function Code に限って、どれだけの IRP Code が Cover されているかを測定した結果です。
これによって、ドライバーに実装されている MJ_IRP Dispatch Routine のテストの Coverage を知ることができます。
③ MJ & MN Device IRP Concurrency pairs. (IRP Pairs Coverage Data)
同時に処理された IRP の組について、結果を表示しています。
これは、複数の IRP の同時処理のテストを行う場合に、どれだけの IRP の組み合わせが網羅できているのかを知ることができます。
以上の内容を見ると、確かに、4 の手順に関連する IRP が流れているのが分かります。ただ、網羅できたのは半分くらいですね。まだまだです。
ちなみに、データーをコンマ区切りでマトリックスとして表した、csv 形式での出力もできます。(" /CT” オプション)
これは、通常はファイルに結果をリダイレクトして使えばいいかと思います。
C:\Workspace> drvcov /CT 11612 > result.csv |
このファイルを Excelで表示すれば、マトリックスで全体の状況を表示できるので、必要に応じて使い分けてはいかがでしょうか。
6. Filter のアンインストール
最後に、” /R” オプションでフィルタードライバーをアンインストールします。
C:\Workspace> drvcov /R 11612 Remove our filter ( both Upper & Lower ) from : Devnode #: 11364 FN: ToasterD evice01 Class: TOASTER Desc: Microsoft Toaster With Coinstaller Process Devnode 11364l Removing filter driver. Process Devnode 11364l Removing filter driver.
NOTE: You need to reboot to unload the filter driver. |
このツールの使い方については、MSDN にも詳しい説明が載っていますので、使ってみたいという方は、是非こちらもご覧いただいきたいと思います。
Driver Coverage Toolkit
https://msdn.microsoft.com/en-us/library/dd535798.aspx
それでは、また。