指定したデバイスの接続/切断時の処理をするには?

解決


junjun  2012-05-31 20:32:26  No: 73411  IP: 192.*.*.*

いつもお世話になります。

早速ですが、、、、、

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を変える可能性が
    あるためです。。。。
    わかりにくくて申し訳ないです。。。。

編集 削除
オショウ  2012-05-31 21:54:08  No: 73412  IP: 192.*.*.*

デバイス名からデバイスクラスGUIDを探し出す方法もあり
ますが、当該デバイスのGUIDがどうなっているかは、デバ
イスマネージャの該当デバイスのプロパティを開き、詳細
タブのデバイスクラスGUIDから解るはずです。

※  デバイス情報をWMIで検索するという方法もあります
    が、レジストリから探し出す方法もあります。

以上。参考まで

編集 削除
オショウ  2012-06-02 10:53:52  No: 73413  IP: 192.*.*.*

補足・・・

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を参考にして下さい。
    尚、英語圏サイトには、それらサンプルがゴロゴロしてます。
    お探しになっては如何でしょうか。

以上。

編集 削除
junjun  2012-06-15 16:24:36  No: 73414  IP: 192.*.*.*

回答遅くなりました。

上記でテストアプリ作って取得したGUIDで
RegisterDeviceNotification設定することで指定の
デバイスを捕まえることが出来ました。


協力ありがとうございます!

編集 削除