いつもお世話になります。
早速ですが、、、、、
USB-RS232C変換をにてシリアル通信を実現したいと考えています。
その際に、不用意にUSBが外れた時に切断処理をしたいと思い、
【WM_DEVICECHANGE】メッセージでUSBデバイスの状態変化で判別したいと思うのですが、、、、
その際、そのデバイスだけを検出して処理がしたいと思っています。
いろいろと調べた感じでは、RegisterDeviceNotification これで設定することで出来るような感じで書かれていたのですが、、、、、
//GUID指定
//{A5DCBF10-6530-11D2-901F-00C04FB951ED}
DEFINE_GUID(GUID_TEST3,
0xA5DCBF10, 0x6530, 0x11d2, 0x90, 0x1F, 0x00, 0xc0, 0x4F, 0xb9, 0x51, 0xed);
#define GUID_DRIVER GUID_TEST3
//認識するデバイス情報の登録
DEV_BROADCAST_DEVICEINTERFACE devif;
ZeroMemory( &devif, sizeof(DEV_BROADCAST_DEVICEINTERFACE) );
devif.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
devif.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
devif.dbcc_classguid = GUID_DRIVER;
hDevNotify = RegisterDeviceNotification( hWnd, &devif, DEVICE_NOTIFY_WINDOW_HANDLE );
そもそもGUIDはどう調べればよいのでしょうか?
infに書かれているClassGUIDではHitせず、どのGUIDを指定すればよいのかわかりませんでした。
試しに
devif.dbcc_classguid = GUID_CLASS_USB_DEVICE;
にすると、抜き差しで反応はするのですが、wParamの情報がすべて
{A5DCBF10-6530-11D2-901F-00C04FB951ED}
になってしまいます。(dbcc_nameは正しいものが格納されている)
PID/VIDは変更する可能性がありますので、出来ればデバイスのGUIDで判断できたら良いのですが、、、、、
良い方法はないでしょうか???
申し訳ありませんが、ご教授宜しくお願いします。
P.S.
PID/VIDは変更する可能性があるというのは、市販ケーブルではなく、
自社製の評価ボードへの組み込みでUSB-シリアル変換をしているため。
Driverは共通のものを使うが、評価ボード毎にPIDを変える可能性が
あるためです。。。。
わかりにくくて申し訳ないです。。。。
デバイス名からデバイスクラスGUIDを探し出す方法もあり
ますが、当該デバイスのGUIDがどうなっているかは、デバ
イスマネージャの該当デバイスのプロパティを開き、詳細
タブのデバイスクラスGUIDから解るはずです。
※ デバイス情報をWMIで検索するという方法もあります
が、レジストリから探し出す方法もあります。
以上。参考まで
補足・・・
1.デバイスチェンジ(アライバル)が発生した場合
PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam;
PDEV_BROADCAST_DEVICEINTERFACE pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr;
と、wParamの値で、該当デバイスを探すことになります。
2.デバイスの検索では
先のwParam = DBT_DEVICEARRIVAL の場合、デバイスが接続されたことになりますので
(そうで無い場合は、切断された場)
ようやくGUIDを探す手順に入ります。
3.デバイス名は、 pDevInfo->dbcc_name の、'\\'が出現するまでの文字列ですので、そ
れを切り出して変数に保存(szClassとかの変数名に)(通常は、'USB'になります)
例
pDevInf->dbcc_name:
\\?\USB#Vid_04e8&Pid_503b#0002F9A9828E0F06#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
szDevId: USB\Vid_04e8&Pid_503b\0002F9A9828E0F06
szClass: USB
※ 『#』を、『\』に置き換える処理が必要です。
SetupDiGetClassDevs で、切り出したデバイスのクラス名で、デバイスハンドルを取得
ハンドルが取得できていれば、SetupDiEnumDeviceInfo で、全デバイス情報から合致す
るデバイスを検索します。
検索は、SetupDiGetDeviceInstanceId で、先のデバイスハンドルと、
pDevInf->dbcc_name からの、szClassとszDevId になります。
合致するものが見つかったら、そのデバイスから、SetupDigetDeviceRegistryProperty
で、デバイス情報を取得します。
得られたspDevInfoData.ClassGuid が、お探しものものになるはずです。
※ COMポート側のGUIDではなく、親デバイスとしてのUSB側のGUIDになることを
お忘れなく。
● 無茶苦茶ハショッてますが、流れとAPIを参考にして下さい。
尚、英語圏サイトには、それらサンプルがゴロゴロしてます。
お探しになっては如何でしょうか。
以上。
回答遅くなりました。
上記でテストアプリ作って取得したGUIDで
RegisterDeviceNotification設定することで指定の
デバイスを捕まえることが出来ました。
協力ありがとうございます!
ツイート | ![]() |