首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > windows >

windows用户方式下检测即插即用设备的变化

2013-10-30 
windows用户模式下检测即插即用设备的变化序:在21世纪,这个信息时代,热插拔设备是一个巨大的安全隐患。在这

windows用户模式下检测即插即用设备的变化

序:
    在21世纪,这个信息时代,热插拔设备是一个巨大的安全隐患。在这个篇文章中,我将介绍一种在用户模式下检测即插即用设备的方法。比如,在系统中插入一个usb设备,ipod,无线网卡等等,都可以在用户模式下检测到,并决定开启或关闭新插入的设备。并且,在文章结尾,我将介绍一下这种方法的优点,以及限制。
    怎样检测硬件改变呢?
    事实上,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 = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr;                // do something...                break;            case DBT_DEVTYP_HANDLE:                PDEV_BROADCAST_HANDLE pDevHnd = (PDEV_BROADCAST_HANDLE)pHdr;                // do something...                break;            case DBT_DEVTYP_OEM:                PDEV_BROADCAST_OEM pDevOem = (PDEV_BROADCAST_OEM)pHdr;                // do something...                break;            case DBT_DEVTYP_PORT:                PDEV_BROADCAST_PORT pDevPort = (PDEV_BROADCAST_PORT)pHdr;                // do something...                break;            case DBT_DEVTYP_VOLUME:                PDEV_BROADCAST_VOLUME pDevVolume = (PDEV_BROADCAST_VOLUME)pHdr;                // do something...                break;        }    }    return 0;}

    然而,在默认情况下,windows操作系统只是发送WM_DEVICECHANGE消息给同时具备以下条件的程序(以下是原文):
1.All applications with a top-level window, and
2.Only upon port and volume change.
    这样的设计其实并不坏,至少操作系统给了你提示,在你的应用程序中检测设备加载与卸载的提示。你可以在设备变更后通过DEV_BROADCAST_VOLUME.dbcv_unitmask捕捉设备消息。缺点是当你获得提示时,你的系统已经加载或卸载了设备。
RegisterDeviceNotification()
    想在其他类型的设备改变时获得通知,或者当你的程序不是top-level窗口时,你可以通过调用RegisterDeviceNotification() API来实现。
比如,当你想要获得upon interface改变的通知时,你可以这样做:

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 ignoredNotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USBSTOR;HDEVNOTIFY hDevNotify = RegisterDeviceNotification(this->GetSafeHwnd(),    amp;NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);if( !hDevNotify ) {    // error handling...    return FALSE;}

在看一下第8行NotificationFilter.dbcc_classguid = GUID_DEVINTERFACE_USBSTOR;
即插即用设备由两部分组成:设备接口GUID和设备类GUID。
设备类GUID是一个广泛的设备类概念,打开“设备管理器”,在“查看”菜单中选择“依类型排序设备”,你所看到的每一个子树节点,都是一个设备类。
一个设备类GUID定义了设备类的图标,默认安全设置,安装属性(如用户不能手动安装这个类的实例,它必须列举PNP型),和其他设置。
设备类GUID并没有定义一个I/O接口,来把它作为一个分组的依据。我认为一个好的例子就是端口类。
COM设备和并口设备都是端口类的一部分,然而它们各自都有自己的I/O接口,并且互不兼容。
一个设备只能属于一个设备类。在INF文件的顶部你看到GUID,就是设备类GUID。

一个设备接口GUID定义了一组特定的I/O接口规范。
规范要求每个设备接口GUID的实例都必须支持相同的I/O接口。
每个驱动程序都要注册和启用/禁用设备接口GUID基于PnP状态。
一个设备可以注册多个设备接口GUID,它不局限于一个设备接口GUID。
如果需要,一个设备可以注册多个拥有相同设备接口GUID的事例。一个简单的I/O接口规范是键盘设备接口,键盘接口GUID的每个实例都必须支持原子输入线程。

You can see the current list of device classes and device interface classes at the following registries:

\\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class \\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses

A list of common device interface class GUIDs is given below:

 

windows用户方式下检测即插即用设备的变化 Collapse |Copy Code
LRESULT CHWDetectDlg::OnMyDeviceChange(WPARAM wParam, LPARAM lParam){    ....    ....    windows用户方式下检测即插即用设备的变化 Collapse |Copy Code
windows用户方式下检测即插即用设备的变化 Collapse |Copy Code
windows用户方式下检测即插即用设备的变化 Collapse |Copy Code
SP_PROPCHANGE_PARAMS spPropChangeParams ;spPropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);spPropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE ;spPropChangeParams.Scope = DICS_FLAG_GLOBAL ;spPropChangeParams.HwProfile = 0; // current hardware profilespPropChangeParams.StateChange = DICS_DISABLEif( !SetupDiSetClassInstallParams(hDevInfo, &spDevInfoData,    // note we pass spPropChangeParams as SP_CLASSINSTALL_HEADER    // but set the size as sizeof(SP_PROPCHANGE_PARAMS)    (SP_CLASSINSTALL_HEADER*)&spPropChangeParams, sizeof(SP_PROPCHANGE_PARAMS)) ){    // handle error}else if(!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &spDevInfoData)){    // handle error}else{    // ok, show disable success dialog    // note, after that, the OS will post DBT_DEVICEREMOVECOMPLETE for the disabled device}
原文:

http://www.codeproject.com/Articles/14500/Detecting-Hardware-Insertion-and-or-Removal

 

热点排行