DevCon と SetupDi API ~ DevCon の使い方編 ~
久方ぶりです。まさかたです。
前回の「USBView の中身を見てみる」の記事の中で USBView のお話を書かせていただいた時に、SetupDi という API について、少しだけ触れさせていただきました。
この API は、ドライバに縁の深いものであるという風に、簡単にしかご紹介しませんでしたので、この SetupDi API について、もう少し詳しくお話したいなと思っています。
と、その前に、みなさんは、WDK に含まれている DevCon というツールについて、ご存知でしょうか?
このツールは、システム上のデバイスドライバの情報を取得・表示したり、さらには、新規にデバイスをインストールしたり、既にインストールされているデバイスドライバの設定を変更したり、削除することもできるという、Device Manager 並に豊富な機能を持つコマンドライン ツールです。
- DevCon
https://msdn.microsoft.com/en-us/library/ms792824.aspx
このツール、WDK の中の以下のパスに、バイナリとして含まれているものの他に、そのサンプルコードも公開されています。
- バイナリ : WINDDK\6001.18002\Tools\devcon
- サンプルコード : WINDDK\6001.18002\src\setup\devcon
そして、その中身を覗いていただければお分かりになるかと思いますが、DevCon はさまざまな SetupDi API を駆使して、その豊富な機能を実現しています。
ですので、SetupDi API のことを知ろうとするなら、このサンプルはとても参考になると思います。
前回の記事で、SetupDi API は、システム上の USB ホスト コントローラ デバイスを列挙するために使われていると書きましたが、この API の主な用途は、その名前の通り、そういったデバイスの列挙や情報の取得するための他に、デバイスやドライバのインストールを行うために使われるものです。
具体的にどんな API があるかについては、以下の技術情報を見ていただければと思いますが、たくさんの種類があります。
- Using Device Installation Functions
https://msdn.microsoft.com/en-us/library/ms791137.aspx
これを一つ一つ見て、覚えて使いこなすというのも手ですが、まずは DevCon を入り口として、どんなことができるのかを具体的に見ながら、その使い方を知っていくのもいいのではないかと思います。
というわけで、少々前置きが長くなりましたが、今回は DevCon そのものについて簡単にご紹介したいと思います。
■DevCon の使い方
それでは、DevCon のサンプルの中身に入って行く前に、どんなツールなのか、その使い方を見ていきたいと思います。
(今回は、Windows Vista x86 の環境を前提としています。)
まずは、コマンドプロンプトを開いて、DevCon の help オプションを打ち込んでみましょう。
c:\WINDDK\6001.18002\Tools\Devcon\i386>devcon help Device Console Help: devcon [-r] [-m:\\<machine>] <command> [<arg>...] -r Reboots the system only when a restart or reboot is required. <machine> Specifies a remote computer. <command> Specifies a Devcon command (see command list below). <arg>... One or more arguments that modify a command. For help with a specific command, type: devcon help <command> classfilter Add, delete, and reorder class filters.
classes List all device setup classes.
disable Disable devices.
driverfiles List installed driver files for devices.
drivernodes List driver nodes of devices.
enable Enable devices.
find Find devices.
findall Find devices, including those that are not currently attached.
help Display Devcon help.
hwids List hardware IDs of devices.
install Install a device manually.
listclass List all devices in a setup class.
reboot Reboot the local computer.
remove Remove devices.
rescan Scan for new hardware.
resources List hardware resources for devices.
restart Restart devices.
sethwid Modify Hardware ID's of listed root-enumerated devices.
stack List expected driver stack for devices.
status List running status of devices.
update Update a device manually.
updateni Manually update a device (non interactive).
dp_add Adds (installs) a third-party (OEM) driver package.
dp_delete Deletes a third-party (OEM) driver package.
dp_enum Lists the third-party (OEM) driver packages installed on this machine. |
たくさんのオプションがありますね!
とは言え、これら DevCon が持っている各オプションの機能は、大別すると主に以下の 3つになります。
1. デバイスおよびドライバの情報の取得と表示
2. デバイスおよびドライバの検索
3. デバイスおよびドライバの設定を変更
それぞれのコマンドでは、ターゲットとなるデバイスの指定方法や、検索条件を指定する必要がありますが、その指定の仕方は、主に以下の 2つ の方法があります。
① デバイスの Hardware ID, Compatible ID, Device Instance ID そのもの、もしくはそのパターンで指定
② デバイスが属する Setup Class 名で指定
以下のヘルプ等をご覧いただければ、それぞれのコマンドがどんなことをするのかも分かりますが、せっかくなので、以下で、簡単な一覧にまとめてみました。
- Commands for DevCon Operations
https://msdn.microsoft.com/en-us/library/ms792835.aspx
Ø デバイスおよびドライバの情報の取得と表示
オプション |
説明 |
ターゲットの指定方法 |
HwIDs |
指定したデバイスの Hardware ID を列挙 |
① or ② |
Classes |
システムに存在する Setup Class を列挙 |
N/A |
ListClass |
指定した Setup Class に属するデバイスを列挙 |
② |
DriverFiles |
指定したデバイスのドライバファイルを列挙 |
① or ② |
DriverNodes |
指定したドライバパッケージの情報を列挙 |
① or ② |
Resources |
指定したデバイスが使用しているリソースを列挙 |
① or ② |
Stack |
指定したデバイスのスタック(Upper Filter、Lower Filter)を表示 |
① or ② |
Status |
指定したデバイスの状態(動作中、停止中、無効)を表示 |
① or ② |
Dp_enum |
システムにインストールされている OEM*.inf のドライバパッケージを列挙 |
N/A |
Ø デバイスおよびドライバの検索
オプション |
説明 |
ターゲットの指定方法 |
Find |
指定した条件に合致するデバイスの情報を表示 現在接続されているデバイスだけを表示 |
① or ② |
FindAll |
一度インストールされたが、現在は接続されていないデバイスも表示する |
① or ② |
Ø デバイスおよびドライバの設定を変更
オプション |
説明 |
ターゲットの指定方法 |
Enable |
指定したデバイスを有効にする |
① or ② |
Disable |
指定したデバイスを無効にする |
① or ② |
Update |
指定した HardwareID のデバイスのドライバを、指定した INF のドライバに更新 |
Hardware ID |
UpdateNI |
Update オプションを、ユーザーインターフェースを表示しないで実行 |
Hardware ID |
Install |
指定した非プラグアンドプレイデバイスをインストール |
- INF の(フル)パス - Hardware ID |
Remove |
指定したデバイスをデバイスツリーから削除 ただし、ドライバは削除されない。 |
① or ② |
Rescan |
デバイスリストの情報を再スキャンし、最新の情報に更新し、新しいデバイスを検出(管理者権限が必要) |
N/A |
Restart |
指定したデバイスをリスタート |
① or ② |
Reboot |
OS を再起動 |
N/A |
SetHwID |
指定したデバイスのHardware ID のリストを変更 |
① or ② |
ClassFilter |
指定した Setup Class のフィルタドライバの設定を変更 |
② |
Dp_add |
指定した Driver Package を Driver Store にコピー |
INF の(フル)パス |
Dp_delete |
指定した Driver Package を Driver Store から削除 |
INF の(フル)パス |
■Toaster で実験
百聞は一見に如かずということで、例として WDK のサンプルの Toaster ドライバをインストールした環境で、DevCon をいろいろ動かしてみることにします。
- Toaster
https://msdn.microsoft.com/en-us/library/dd163450.aspx
Toaster を動かすためには、Toaster のバスドライバ(BusEnum.sys)をインストールしなければなりません。
これは、当然 Device Manager からインストールすることもできますが、実は以下のように DevCon の Install オプションを使って行うこともできます。
c:\WINDDK\6001.18002\Tools\Devcon\i386>devcon install C:\WINDDK\6001.18002\src\general\toaster\ inf\i386\bus.inf "root\busenum" Device node created. Install is complete when drivers are installed... Updating drivers for root\busenum from C:\WINDDK\6001.18002\src\general\toaster\inf\i386\bus.inf. Drivers installed successfully. |
その後、Toaster のインスタンスをプラグインしてインストールしておきますが、今回は、Toaster のインスタンスを 3つ 入れてみました。
それでは、手始めにシステムに Toaster の Setup Classs が組み込まれているかを、Classes オプションでチェックします。
c:\WINDDK\6001.18002\Tools\Devcon\i386>devcon classes Listing 55 setup classes. WCEUSBS : USB : Media Center Extender: Media Center Extender PnpPrinters : IEEE 1394 SCSI Dot4 : IEEE 1284.4 Dot4Print : IEEE 1284.4 CDROM : DVD/CD-ROM Computer : DiskDrive : Display : fdc : hdc : IDE ATA/ATAPI Keyboard : MEDIA : Modem : Monitor : Mouse : MTD : MultiFunction : Net : NetClient : NetService : NetTrans : PCMCIA : PCMCIA Ports : (COM LPT) Printer : SCSIAdapter : System : Unknown : FloppyDisk : Processor : MultiPortSerial : Memory : SmartCardReader : VolumeSnapshot : 1394 : 1394 Infrared : Image : TapeDrive : Volume : Battery : HIDClass : 61883 : 61883 LegacyDriver : SideShow : Windows SideShow SDHost : SD TOASTER : Toaster Transfer Cable : AVC : AVC MediumChanger : SBP2 : SBP2 IEEE 1394 XnaComposite : Windows Microsoft SecurityDevices : Bluetooth : Bluetooth WPD : |
確かに Toaster クラスが存在します。
では、この Toaster クラスに属するデバイスを、ListClass オプションで列挙してみます。
c:\WINDDK\6001.18002\Tools\Devcon\i386>devcon listclass toaster Listing 3 devices in setup class "TOASTER" (Toaster). {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&1AAFB3D5&0&01: ToasterDevice01 {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&1AAFB3D5&0&02: ToasterDevice02 {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&1AAFB3D5&0&03: ToasterDevice03 |
確かに、該当するデバイスとして、ToasterDevice01 ~ 03 が見つかりました。
続いて、検索機能として、Find オプションと Findall オプションという 2つ のオプションがありますので、この違いを見てみたいと思います。
ここで、結果に差をつけるために、ToasterDevice03 だけを Unplug しておきました。
c:\WINDDK\6001.18002\Tools\Devcon\i386>devcon find *toaster* {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&1AAFB3D5&0&01: ToasterDevice01 {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&1AAFB3D5&0&02: ToasterDevice02 2 matching device(s) found.
c:\WINDDK\6001.18002\Tools\Devcon\i386>devcon findall *toaster* {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&1AAFB3D5&0&01: ToasterDevice01 {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&1AAFB3D5&0&02: ToasterDevice02 {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&1AAFB3D5&0&03: ToasterDevice03 3 matching device(s) found. |
すると、Find オプションでは出てこない ToasterDevice03 が、Findall オプションだとちゃんと出てきました。
では、次に、Update オプションを使ってドライバを更新して、クラスドライバ、ファンクションドライバにそれぞれ Upper と Lower のフィルタドライバ4つも入れてみます。
- Class upper filter : Clsupper.sys
- Class lower filter : Clslower.sys
- Device upper filter : Devupper.sys
- Device lower filter : Devlower.sys
と、その前に、Update コマンドで必要となる Toaster のHardware ID をHwIds オプションで調べておきます。
c:\WINDDK\6001.18002\Tools\Devcon\i386>devcon hwids =toaster {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&79F5D87&0&01 Name: ToasterDevice01 Hardware IDs: {B85B7C50-6A01-11d2-B841-00C04FAD5171}\MsToaster Compatible IDs: {B85B7C50-6A01-11d2-B841-00C04FAD5171}\MsCompatibleToaster {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&79F5D87&0&02 Name: ToasterDevice02 Hardware IDs: {B85B7C50-6A01-11d2-B841-00C04FAD5171}\MsToaster Compatible IDs: {B85B7C50-6A01-11d2-B841-00C04FAD5171}\MsCompatibleToaster {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&79F5D87&0&03 Name: ToasterDevice03 Hardware IDs: {B85B7C50-6A01-11d2-B841-00C04FAD5171}\MsToaster Compatible IDs: {B85B7C50-6A01-11d2-B841-00C04FAD5171}\MsCompatibleToaster 3 matching device(s) found. |
INF を見ても分かることではありますが、Hardwere ID は、” {B85B7C50-6A01-11d2-B841-00C04FAD5171}\MsToaster” になります。
それでは、Update コマンドで、toasterf.inf を使ってドライバをアップデートして、フィルタドライバをインストールします。
c:\WINDDK\6001.18002\Tools\Devcon\i386>devcon update c:\Workspace\toaster_pkg\toasterf.inf {b85b7c50-6a01-11d2-b841- 00c04fad5171}\MsToaster Updating drivers for {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster from c:\Workspace\toaster_pkg\toasterf.inf. Drivers installed successfully. |
ここで Stack オプションを使えば、ファンクションドライバの Upper と Lower のフィルタドライバとして、何がインストールされているかが分かります。
c:\WINDDK\6001.18002\Tools\Devcon\i386>devcon stack *toaster* {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&79F5D87&0&01 Name: ToasterDevice01 Setup Class: {b85b7c50-6a01-11d2-b841-00c04fad5171} TOASTER Upper filters: devupper Controlling service: toaster Lower filters: devlower {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&79F5D87&0&02 Name: ToasterDevice02 Setup Class: {b85b7c50-6a01-11d2-b841-00c04fad5171} TOASTER Upper filters: devupper Controlling service: toaster Lower filters: devlower {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&79F5D87&0&03 Name: ToasterDevice03 Setup Class: {b85b7c50-6a01-11d2-b841-00c04fad5171} TOASTER Upper filters: devupper Controlling service: toaster Lower filters: devlower 3 matching device(s) found. |
さて、次は、DriverFiles と、DriverNodes オプションで、ドライバが使っているファイルの情報を取得してみましょう。
まずは、DriverFiles オプションの場合です。
c:\WINDDK\6001.18002\Tools\Devcon\i386>devcon driverfiles =toaster {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&1AAFB3D5&0&01 Name: ToasterDevice01 Driver installed from C:\Windows\INF\oem6.inf [Toaster_Device]. 5 file(s) used by driver: C:\Windows\system32\DRIVERS\toaster.sys C:\Windows\system32\DRIVERS\Devupper.sys C:\Windows\system32\DRIVERS\Devlower.sys C:\Windows\system32\DRIVERS\clsupper.sys C:\Windows\system32\DRIVERS\clslower.sys … (中略) … 3 matching device(s) found. |
長いので間の出力は省略しましたが、その間には、ToasterDevice02 と 03 について、同じ情報が列挙されます。
先ほどのドライバの更新により、Toaster のデバイスドライバと、クラスドライバの両方に、Upper と Lower のフィルタをインストールされているので、デバイスドライバである toaster.sys の他に、ファンクションドライバに対するフィルタドライバとして、Devupper.sys、Devlower.syが、クラスのフィルタドライバとして、clsupper.sys、clslower.sys が使われているのが分かります。
次に、DriverNodes オプションの場合です。今度は、デバイスを指定するのに、Hardware ID のパターンを使ってみました。
c:\WINDDK\6001.18002\Tools\Devcon\i386>devcon drivernodes *toaster* {B85B7C50-6A01-11D2-B841-00C04FAD5171}\MSTOASTER\1&1AAFB3D5&0&01 Name: ToasterDevice01 Driver node #0: Inf file is C:\Windows\INF\oem6.inf Inf section is Toaster_Device Driver description is Microsoft Toaster with class and device filters Manufacturer name is (Standard system devices) Provider name is Microsoft Driver date is 2006/09/21 Driver version is 6.0.5736.1 Driver node rank is 2164195328 Driver node flags are 00040040 Driver node #1: Inf file is C:\Windows\INF\oem7.inf Inf section is Toaster_Device Driver description is Microsoft Toaster With Coinstaller Manufacturer name is (Standard system devices) Provider name is Microsoft Driver date is 2006/09/21 Driver version is 6.0.5736.1 Driver node rank is 2164195328 Driver node flags are 00000040 … (中略) … 3 matching device(s) found. |
Manufacturer や、Provider、Driver Date や Version など、INF に記述されている情報も取得できます。
SetupDi API を使えば、このような情報も取得することができるわけです。
以上のように、DevCon を使えば、通常なら Device Manager を使って行うような操作も、コマンドラインから行うことができるわけです。
さらに、DevCon をコマンドとして使った Script を組んで、Device Manager のような UI を使わずに、デバイスの設定を操作することができます。
ちなみに、DevCon は、WDK をインストールしなくても、以下のサポート オンラインのページから、既にビルド済みのバイナリをダウンロードすることもできます。
すぐに試してみたい方は、こちらも一緒にご覧いただければと思います。
- デバイスマネージャとして機能する DevCon コマンド ライン ユーティリティ
https://support.microsoft.com/kb/311272/ja
というわけで、今回は、SetupDi API の説明をする前に、SetupDi API の使い方の参考となりそうな DevCon とその使い方をご紹介をさせていただきました。
また別の機会に、DevCon のサンプルコードを見ながら、DevCon では SetupDi API をどのように使って、上記のような機能を実現しているのかについてお話したいと思います。
それでは。