系统检测USB 设备往往分为两个过程:
1. USB 设备已经插入, 打开软件。 此时需要枚举当前设备列表中所有的设备,并过滤指定的USB 设备。
2. 打开软件后, USB 热插拔 。 此时用WM_DEVICECHANGE 消息去获取设备信息。 当设备插入或者移除时,系统给当前主窗口发送WM_DEVICECHANGE 消息 。 注意: 默认状态, 任何设备都会通知。 所以需要注册指定的通知消息。
第一种:枚举系统中所有的USB 设备, 可根据 PID,VID 进一步做判断。
void CDataSyncAccessDlg::CollectUSBInfo()
{
// 获取当前系统所有使用的设备
DWORD dwFlag = (DIGCF_ALLCLASSES | DIGCF_PRESENT);
HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL, NULL, NULL, dwFlag);
if (INVALID_HANDLE_VALUE == hDevInfo)
{
AfxMessageBox(_T("获取系统设备列表失败"));
return;
}
// 准备遍历所有设备查找USB
SP_DEVINFO_DATA sDevInfoData;
sDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
TCHAR szDIS[MAX_PATH]; // Device Identification Strings,
DWORD nSize = 0;
for (int i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &sDevInfoData); i++)
{
nSize = 0;
if (!SetupDiGetDeviceInstanceId(hDevInfo, &sDevInfoData, szDIS, sizeof(szDIS), &nSize))
{
AfxMessageBox(_T("获取设备识别字符串失败"));
break;
}
// 设备识别串的前三个字符是否是"USB", 模板: USB\VID_XXXX&PID_XXXX\00000xxxxxxx
CString strDIS(szDIS);
strDIS.MakeUpper();
if (strDIS.Left(3) == _T("USB"))
{
int pos = strDIS.ReverseFind('\\');
CString DeviceSer = strDIS.Right(strDIS.GetLength() - pos-1);
//匹配序列号
if (ValidDevcie(DeviceSer))
{
SetUSBState(TRUE);
}
}
}
// 释放设备
SetupDiDestroyDeviceInfoList(hDevInfo);
}
第二种: windows操作系统在检测到硬件变化时,会发送一个WM_DEVICECHANGE硬件change消息。因此,我们要做的就是在我们的程序中添加WM_DEVICECHANGE的消息响应。
BEGIN_MESSAGE_MAP(CHWDetectDlg, CDialog)zai
// ... other handlers
ON_MESSAGE(WM_DEVICECHANGE, OnMyDeviceChange)
END_MESSAGE_MAP()
LRESULT CHWDetectDlg::OnMyDeviceChange(WPARAM wParam, LPARAM lParam)
{
// for more information, see MSDN help of WM_DEVICECHANGE
// this part should not be very difficult to understand
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 =