USB 设备热插拔的检测

来源:互联网 发布:淘宝店铺名可以修改吗 编辑:程序博客网 时间:2024/05/01 02:26

关于USB设备的热插拔,网上已有不少相关的文档,这里总结下,基本上分为两大类:
1.通过WM_DEVICECHANGE消息检测USB设备(包括手机、USB网卡等)由RegisterDeviceNotification来注册消息,如果需要检测多个设备,
这里就注册多个GUID。
2.通过SHChangeNotifyRegister注册消息来检测设备(U盘、移动硬盘等);
具体方法如下:


(1) 添加消息映射
#define WM_SHNOTIFY WM_USER + 100  //监控计算机目录消息ID
BEGIN_MESSAGE_MAP(CDYDirTreeCtrl, CDYTreeCtrl)
ON_WM_DEVICECHANGE()
ON_MESSAGE(WM_SHNOTIFY, OnComputerMonitor) 
END_MESSAGE_MAP()
(2)注册消息
//监控计算机目录实现部分
void CDYDirTreeCtrl::SetComputerMonitor()
{
PIDLIST_ABSOLUTE pidlWatch;
SHGetFolderLocation(NULL,CSIDL_DRIVES,NULL,NULL,&pidlWatch);


int const nSources = SHCNRF_ShellLevel | SHCNRF_InterruptLevel | SHCNRF_NewDelivery; 


SHChangeNotifyEntry shcne;
shcne.fRecursive = TRUE;
shcne.pidl = pidlWatch; 




m_hNotify = SHChangeNotifyRegister(this->GetSafeHwnd(), nSources, SHCNE_MEDIAINSERTED|SHCNE_MEDIAREMOVED|SHCNE_DRIVEADD|SHCNE_DRIVEREMOVED, WM_SHNOTIFY, 1, &shcne);  // SHCNE_ALLEVENTS
CoTaskMemFree(pidlWatch);


DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
// assume we want to be notified with USBSTOR
// to get notified with all interface on XP or above
// ORed 3rd param with DEVICE_NOTIFY_ALL_INTERFACE_CLASSES and dbcc_classguid will be ignored
DY_GUID guidUSBdy = DYGuidFromString(_T("A5DCBF10-6530-11D2-901F-00C04FB951ED"));
GUID guidUSB;guidUSBdy.GetGuid(guidUSB);
NotificationFilter.dbcc_classguid = guidUSB;//GUID_DEVINTERFACE_USBSTOR;GUID_DEVINTERFACE_USB_DEVICE  见 "usbiodef.h"中定义;
m_hDevNotify = RegisterDeviceNotification(this->GetSafeHwnd(),&NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE); 
if( !hDevNotify ) {
// error handling...
int err = GetLastError();
}


m_bComputerMonitor = TRUE;
}


(3)响应消息


//检测硬盘 存储设备
LRESULT CDYDirTreeCtrl::OnComputerMonitor(WPARAM wParam, LPARAM lParam)
{
CString strPath;
GetPath(strPath);
ShowTree();
}
//检测USB手机
BOOL CDYDirTreeCtrl::OnDeviceChange(UINT wParam, DWORD_PTR lParam)
{
CDYTreeCtrl::OnDeviceChange(wParam, lParam);




  if ( DBT_DEVICEARRIVAL == wParam || DBT_DEVICEREMOVECOMPLETE == wParam ) {
  PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam;
  switch( pHdr->dbch_devicetype ) {
  case DBT_DEVTYP_DEVICEINTERFACE:
  {
  PDEV_BROADCAST_DEVICEINTERFACE pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr;
  if (wParam == DBT_DEVICEARRIVAL)//插入USBdev
  {
 
  }else if (wParam == DBT_DEVICEREMOVECOMPLETE)//拔出USBDEV
  {
 
  }
 
  OnComputerMonitor(0,0);
 
  }
  break;
  
  case DBT_DEVTYP_VOLUME:
  //PDEV_BROADCAST_VOLUME pDevVolume = (PDEV_BROADCAST_VOLUME)pHdr;
  // do something...
  break;
  }
  }




return FALSE;
}
(4)取消注册
SHChangeNotifyDeregister(m_hNotify);
UnregisterDeviceNotification(m_hDevNotify );



参考链接:http://blog.csdn.net/wzy198852/article/details/52343819
https://www.codeproject.com/Articles/14500/Detecting-Hardware-Insertion-and-or-Removal