ATL可执行文件(.exe)监控USB插拔状态

本文介绍了如何在ATL可执行文件中利用OnDeviceChange(ON_WM_DEVICECHANGE)消息监控USB设备的插拔状态。通过添加消息映射、声明及实现消息响应函数,以及注册设备,使得非服务型的ATL程序也能检测USB设备的变化。同时,文章提到了在Com接口类中创建MsgWnd类以及实现相关功能的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

OnDeviceChange(ON_WM_DEVICECHANGE)

1.添加消息

1.消息映射
BEGIN_MESSAGE_MAP(CAFT_1394Dlg, CDialog)
//{{AFX_MSG_MAP(CAFT_1394Dlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
...
ON_WM_DEVICECHANGE()
//}}AFX_MSG_MAP

2.声明消息响应函数
afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD dwData);

3.定义函数内容:
BOOL XXXXXXX::OnDeviceChange(UINT nEventType,DWORD dwData)
{
   DEV_BROADCAST_DEVICEINTERFACE* dbd = (DEV_BROADCAST_DEVICEINTERFACE*) dwData;

   //这里进行信息匹配,比如guid等

//针对各个事件进行处理.
switch (nEventType)
{
case DBT_DEVICEREMOVECOMPLETE:
   ...
   break;
case DBT_DEVICEARRIVAL:
   ...
   break;
...
...
...

default:
   break;
}

return TRUE;

}


2.注册设备

if (Handle == NULL)
   return FALSE;

DEV_BROADCAST_DEVICEINTERFACE DevInt;
memset(&DevInt,0,sizeof(DEV_BROADCAST_DEVICEINTERFACE));
DevInt.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
DevInt.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;

DevInt.dbcc_classguid = GetCurrentUSBGUID();//m_usb->GetDriverGUID();
if (!RegisterDeviceNotification(m_hWnd, &DevInt,DEVICE_NOTIFY_WINDOW_HANDLE) )
   return FALSE;

只有注册了该设备,OnDeviceChange才能获得详细的信息,否则收到的参数都是0007.

ATL可执行文件(.exe)监控USB

麻烦的地方在于,只能在窗口程序或者是服务程序中才能这么做,但是ATL程序中,如果程序类型不是服务的话,比如是一个可执行文件(.exe),又如何实现呢?

1,在Com接口类中创建MsgWnd类
class MsgWnd : public CDialog
{
public:
	MsgWnd() {}
	MsgWnd( CComExecute* p );
	~MsgWnd() {}
protected:
	afx_msg LRESULT OnRecvMsg(WPARAM wParam, LPARAM lParam);
//消息函数
	afx_msg BOOL OnDeviceChange(UINT nEventType,DWORD_PTR dwData );
	DECLARE_MESSAGE_MAP()
private:
	MsgWnd(const MsgWnd&);
	MsgWnd& operator=(const MsgWnd&);
	CComExecute* m_pParent;

public:
	//注册
	void RegisterUSBGUID();
};  

 

需要包含头文件

#ifdef _WINDOWS_
#undef _WINDOWS_
#include <afxwin.h>
#endif
2,实现MsgWnd类
HDEVNOTIFY      gNotifyDevHandle = NULL;
DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);  

BEGIN_MESSAGE_MAP(MsgWnd, CWnd)    
	//ON_MESSAGE(WM_COMM, OnRecvMsg)
	ON_WM_DEVICECHANGE()
END_MESSAGE_MAP()

LRESULT MsgWnd::OnRecvMsg(WPARAM wPar, LPARAM lPar)
{
	if ( NULL != m_pParent )
	{
		
	}
	return 1;
}

MsgWnd::MsgWnd( CComExecute* p )
{
	if ( NULL != p )
	{
		m_pParent = p;
	}
}

void MsgWnd::RegisterUSBGUID()
{
	DEV_BROADCAST_DEVICEINTERFACE broadcastInterface = {0};

	// Register to receive notification when a USB device is plugged in.
	broadcastInterface.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
	broadcastInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
	memcpy( &(broadcastInterface.dbcc_classguid),
		&(GUID_DEVINTERFACE_USB_DEVICE), sizeof(struct _GUID));
	gNotifyDevHandle = RegisterDeviceNotification(m_hWnd,
		&broadcastInterface, DEVICE_NOTIFY_WINDOW_HANDLE);
}

//check device event,WM_DEVICECHANGE
BOOL MsgWnd::OnDeviceChange(UINT nEventType,DWORD_PTR dwData )
{
	//analysing the event
	CString strDisk,strError;
	//PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam;
	DEV_BROADCAST_DEVICEINTERFACE* dbd = (DEV_BROADCAST_DEVICEINTERFACE*) dwData;

	//check device event
	switch(nEventType)   
	{   
	case DBT_DEVICEARRIVAL://设备检测结束 并且可以使用   
		{   
			//CheckDeviceType(pHdr,wParam);	
			int a = 0;
			m_pParent->TestAAA();
			break;   
		}   
	case DBT_DEVICEREMOVECOMPLETE://DBT_DEVICEREMOVECOMPLETE,设备卸载或者拔   
		{   
			//CheckDeviceType(pHdr,wParam);		
			int b = 0;
			m_pParent->TestBBB();
			break;   
		}   
		break;  
	case DBT_DEVICEQUERYREMOVE:
		break;
	case DBT_DEVICEQUERYREMOVEFAILED:
		break;
	case DBT_DEVICEREMOVEPENDING:
		break;
	case DBT_DEVICETYPESPECIFIC:
		break;
	case DBT_CUSTOMEVENT:
		break;
	case DBT_QUERYCHANGECONFIG:
		break;
	case DBT_CONFIGCHANGED:
		break;
	case DBT_CONFIGCHANGECANCELED:
		break;
	case DBT_MONITORCHANGE:
		break;
	case DBT_SHELLLOGGEDON:
		break;
	case DBT_CONFIGMGAPI32:
		break;
	case DBT_VXDINITCOMPLETE:
		break;
	case DBT_VOLLOCKQUERYLOCK:
		break;
	case DBT_VOLLOCKLOCKTAKEN:
		break;
	case DBT_VOLLOCKLOCKFAILED:
		break;
	case DBT_VOLLOCKQUERYUNLOCK:
		break;
	case DBT_VOLLOCKLOCKRELEASED:
		break;
	case DBT_VOLLOCKUNLOCKFAILED:
		break;
	case DBT_NO_DISK_SPACE:
		break;
	case DBT_LOW_DISK_SPACE:
		break;
	case DBT_CONFIGMGPRIVATE:
		break;
	case DBT_USERDEFINED:
		break;
	default:
		break;
	}
	return true;
}

需要添加头文件
#include <Dbt.h>
#include <Initguid.h>

 

3,Com接口类创建Dialog

	if ( NULL == m_pMsgWnd )
	{
		m_pMsgWnd = new MsgWnd( this );
 		BOOL bRet = m_pMsgWnd->CreateEx(WS_EX_CLIENTEDGE,_T("Message"),
 			_T("Message"),WS_OVERLAPPED,0,0,0,0,HWND_DESKTOP,NULL);
		if ( bRet )
		{ 
			m_pMsgWnd->RegisterUSBGUID();
		}
	}

OK,在客户端调用后,这个exe就会运行,并且可以检测到USB的插拔动作



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值