もくじ
https://tera1707.com/entry/2022/02/06/144447
やりたいこと
devconで、
devcon listclass <クラス名>
とパラメータを渡して実行したときの処理の中身を追いかけたい。
クラス名とは、devcon classesで取れるクラス名のこと。たとえはMouse
など。
出力例
PS C:\Users\masa\Desktop\Windows-driver-samples-main\Windows-driver-samples-main\setup\devcon\x64\Debug> ./devcon listclass Mouse Listing 3 devices in setup class "Mouse" (マウスとそのほかのポインティング デバイス). HID\CRAZYREMOTEHIDDEVICE&COL02\1&2D595CA7&0&0001 : HID 準拠マウス HID\VID_046D&PID_C52E&MI_01&COL01\8&39B8ABAE&0&0000 : HID 準拠マウス HID\VID_04F3&PID_0235\6&35218DED&2&0000 : HID 準拠マウス
該当コード
ここ。
やってることの流れ
SetupDiClassGuidsFromNameEx
SetupDiClassGuidsFromNameEx()
で、ユーザー指定のクラス名(今回は「Mouse」)から、クラスのGUIDを取得する
while(!SetupDiClassGuidsFromNameEx(argv[argIndex],guids,reqGuids,&numGuids,Machine,NULL)) {
SetupDiGetClassDevsEx
SetupDiGetClassDevsEx()
で、指定のクラスのGUIDに含まれるデバイスのためのハンドル(HDEVINFO
)を取得する。
devs = SetupDiGetClassDevsEx(&guids[index],NULL,NULL,DIGCF_PRESENT,NULL,Machine,NULL);
https://learn.microsoft.com/ja-jp/windows/win32/api/setupapi/nf-setupapi-setupdigetclassdevsexa
そのハンドルを使って、下でそのクラスに含まれるデバイスの情報を取る。
※今のところ、NULLにしている引数の意味は不明。いろいろいじってみたが、いじるとdevsの戻り値がINVALID_HANDLE_VALUEになってしまったので、上記以外の使い方は不明。
SetupDiEnumDeviceInfo
SetupDiEnumDeviceInfo()
の、
- 第一引数に、
SetupDiGetClassDevsEx()
で取ったハンドルを渡す - 第二引数に、最初0を渡す
- とやると、第三引数にデバイス情報(SP_DEVINFO_DATA)が載ってくる。
- 第二引数を++しながら、戻り値が0になるまで繰り返せば、全デバイスの情報が取れる。
但し、今回のdevconの"listclass"コマンドでは、第三引数で取れるデバイス情報は見てなくて、何回デバイスが取れたかのカウントだけをしていた。
第三引数のDWORD DevInst
は、CM_Get_DevNode_Status()
などの関数に渡すとまた別の情報が取れる。それを(なぜか)ちょっと後ろ↓でやる。(一緒にやったらあかんのか?)
SetupDiClassNameFromGuidEx
devconの中身を見る①(cmdClasses)でやったのと同じ。
SetupDiGetClassDescriptionEx
devconの中身を見る①(cmdClasses)でやったのと同じ。
改めてSetupDiEnumDeviceInfoでデバイス情報(SP_DEVINFO_DATA)をとって、その内容を表示
SetupDiGetDeviceRegistryProperty
上で取った
と
- 取りたいプロパティの種類を指定するDWORD値(例えばSPDRP_FRIENDLYNAME)
をSetupDiGetDeviceRegistryProperty()
に渡して、そのデバイスの欲しい情報を取る。
情報は、戻り値として文字列で帰る。
SetupDiGetDeviceInfoListDetail
上でとったデバイスハンドルを与えて、デバイスの詳細情報(SP_DEVINFO_LIST_DETAIL_DATA)を取る。
詳細情報というが、少なくともローカルPCの情報を取るだけだと、全然情報量多くないっぽい。
詳細情報を取るためというより、この後のCM_Get_Device_ID_Ex
の引数に渡すための情報(RemoteMachineHandle)を取るために呼んでる?
CM_Get_Device_ID_Ex
ここで、CM_Get_Device_ID_Ex()
の第一引数に、上で取ったSP_DEVINFO_DATA
のDevInstを渡して、このデバイスのデバイスインスタンスID
を取得する。
SetupDiDestroyDeviceInfoList
SetupDiGetClassDevsEx()
でとったハンドルを破棄する。
#以上
これで終わり。
昔から、どういう値なのかが謎だった「デバイスインスタンスID」を取ってる奴が出てきた。
下に書いたが、デバイスインスタンスIDがなんなのか?の説明ページを見つけた。そこを見て、どういう値なのか調べたい。
※デバマネ見たら、デバイスインスタンス「パス」って書いてるけど、listclassで取れる値とこの画面の値が同じだったので、どちらも同じ意味だと思われる...
メモ
クラスは「種類」みたいなもの
1つのクラスの中に、複数のデバイスがある
下記のページに、デバイスマネージャーに出てくる値の説明がありそう!
https://learn.microsoft.com/ja-jp/windows-hardware/drivers/install/device-instance-ids
デバイスの名前などは、下記で取れる。
desc = GetDeviceStringProperty(Devs,DevInfo,SPDRP_FRIENDLYNAME); desc = GetDeviceStringProperty(Devs,DevInfo,SPDRP_DEVICEDESC);
CM_Get_Device_ID_Ex(DevInfo->DevInst,devID,MAX_DEVICE_ID_LEN,0,devInfoListDetail.RemoteMachineHandle)
listclassは、これでとった値を表示してる。
次
★これのつぎ、「hwids」を調べたい。デバイスIDとはなにか?が気になる