设备监控功能一般用于设备使用安全场景,主要是监控设备的加载和卸载,实际上通过监控系统设备的加载过程,组织可以在用户使用设备前对设备进行保护或则限制(这种功能需要设备提供相应的控制接口)。
设备监控功能控制
在SystemPanel的菜单资源编辑器中添加新的菜单项
修改菜单变量名,添加菜单事件处理函数
在设备监控控制菜单处理函数中添加如下代码:
//设备监控控制
#include <dbt.h>
HDEVNOTIFY hDevNotify;
//注册监听消息(只监听USB设备变化)
//参考https://learn.microsoft.com/zh-cn/windows/win32/api/dbt/ns-dbt-dev_broadcast_deviceinterface_a?redirectedfrom=MSDN
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
//注册设备监听消息
static const GUID GUID_DEVINTERFACE = { 0xA5DCBF10, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED }}; // usb设备guid
void SystemPanel::Onm_DeviceMonitorSelected(wxCommandEvent& event)
{
if(event.IsChecked())
{
//对于部分USB设备的变化无法通知广播到指定窗口,需要注册相应设备的通知消息
ZeroMemory( &NotificationFilter, sizeof(NotificationFilter) );
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE;//指定要检测的设备的guid,这里是usb设备的
hDevNotify =RegisterDeviceNotification(wxTheApp->GetTopWindow()->GetHandle(), &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);//注册设备通知窗口
}
else
{
UnregisterDeviceNotification(hDevNotify);
}
}
监控设备消息
由于设备变化消息WM_DEVICECHANGE属于系统级消息,目前只能在主窗口中获取,所以我们只能通过重载主窗口系统消息处理函数然后转发给SystemPanel中的处理函数来实现。
首先,我们在主窗口MSWWindowProc添加WM_DEVICECHANGE处理,代码如下:
//处理系统消息和自定义消息
WXLRESULT SDKLearnFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
{
switch (message)
{
//处理设备改变的消息
case WM_DEVICECHANGE:
{
m_SystemPanel->DoDeviceChange(message, wParam, lParam);
}
break;
default:
break;
}
return wxFrame::MSWWindowProc(message, wParam, lParam);
}
设备变化具体的处理过程将会放到SystemPanel的DoDeviceChange函数中进行。
处理设备消息
在SystemPanel的DoDeviceChange函数中添加如下代码:
//设备监控消息处理
void SystemPanel::DoDeviceChange(WXUINT message,WXWPARAM wParam, WXLPARAM lParam)
{
PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam;
switch(wParam )
{
case DBT_DEVICEARRIVAL:
cout<<_("message: 设备添加了!")<<message<<endl;
//USBBridge设备添加处理
if(pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{
PDEV_BROADCAST_DEVICEINTERFACE pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr;
wxString dbcc_name = pDevInf->dbcc_name;
if(dbcc_name.Find(_T("VID_067B&PID_2701")) != -1)
{
cout<<_("PL-2701 USB Bridge Cable Arrival!")<<endl;
}
}
break;
case DBT_DEVICEREMOVECOMPLETE:
cout<<_("message: 设备删除了!")<<message<<endl;
//USBBridge设备卸载处理
if(pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
{
PDEV_BROADCAST_DEVICEINTERFACE pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr;
wxString dbcc_name = pDevInf->dbcc_name;
if(dbcc_name.Find(_("VID_067B&PID_2701")) != -1)
{
cout<<_("PL-2701 USB Bridge Cable Removed!")<<endl;
}
}
break;
case DBT_DEVNODES_CHANGED://设备改变的处理函数
// cout<<_("设备改变了!")<<endl;
break;
default:
break;
}
}
可能用到的设备变化消息如下:
DBT_DEVICEARRIVAL 是设备加载到系统产生的消息
DBT_DEVICEREMOVECOMPLETE 是设备从系统卸载产生的消息
DBT_DEVNODES_CHANGED 是设备在系统中发生任何变化都会产生的消息
代码中用到的 PL-2701 USB Bridge Cable是一种用于电脑间通过USB接口直接传输文件的线缆设备,SDK参考如下:
ProlificCom/PL2701_Libusb_SDK: SDK for PL2701 USB 3.0 Host-to-Host Bridge Controller (github.com)
至此,设备监控功能已经简单实现完成。