USB 设备热插拔的检测

本文介绍了在Windows系统中如何检测USB设备的热插拔,包括通过WM_DEVICECHANGE消息监听设备变动,使用SetupDiXxx() API枚举设备,以及注册DeviceNotification()以获取详细设备信息。此外,还探讨了设备类GUID和设备接口GUID的区别,并提供了禁用设备的方法及程序测试情况。
摘要由CSDN通过智能技术生成

系统检测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 = 
  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值