听说现在网络上流传着一些能实时检测到U盘插拔消息并能在其插入后伺机拷贝其中文档资料的恶意程序,而日前在CSDN论坛也看到有网友询问这类程序的实现原理,为此我想通过一个简单的VB程序演示一下核心操作过程并借机把实现原理作一个简洁的说明。
    
事实上当U盘(实际上不局限于U盘,所有能在系统中获得逻辑卷标的设备都适用)插入视窗系统的机器后操作系统将发送一个WM_DEVICECHANGE的广播消息,因此只要在相应的消息处理过程中拦截该信息并加以处理就能实时检测到U盘的插拔,之后即可进行预设的有关处理动作了。
    
熟悉WINDOWS消息处理过程的人都知道,操作系统发送有关消息时还会附带上两个重要的参数:wParam、lParam,因此WM_DEVICECHANGE也不例外,当该消息发生时,wParam里的内容是指示设备变化的具体事件类别,在我们的演示程序里只需要关心DBT_DEVICEARRIVAL和DBT_DEVICEREMOVECOMPLETE这两个事件,前者表示新设备已经插入机器并能正常使用了,后者表示设备已经被物理移除了;lParam的内容实际上是一个地址,指向一个结构体,该结构的具体细节由插入系统的设备类型决定,这里有个需要注意的地方,即不论设备类型是什么,该结构的前面三个LONG型成员是固定的,因此我们可以先取得这三个成员的内容,再根据第二个成员的数值来确定新设备类型,然后再获取全部成员的内容。
     以下是这个VB演示程序的代码,效果就是检测到设备插入后即把该设备根目录下的全部文件名显示在LISTBOX里面。
模块代码:

AOption Explicit
‘子类化窗体消息处理函数时需要使用的API,很常见,不作过多说明。
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd 
As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal 
lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As 
Long, ByVal lParam As Long) As Long
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc 
As Any, ByVal ByteLen As Long)
Const GWL_WNDPROC = -4
Const WM_DEVICECHANGE As Long = &H219
Const DBT_DEVICEARRIVAL As Long = &H8000&
Const DBT_DEVICEREMOVECOMPLETE As Long = &H8004&
'设备类型:逻辑卷标
Const DBT_DEVTYP_VOLUME As Long = &H2
'与WM_DEVICECHANGE消息相关联的结构体头部信息
Private Type DEV_BROADCAST_HDR
lSize As Long
lDevicetype As Long    '设备类型
lReserved As Long
End Type
'设备为逻辑卷时对应的结构体信息
Private Type DEV_BROADCAST_VOLUME
lSize As Long
lDevicetype As Long
lReserved As Long
lUnitMask As Long    '和逻辑卷标对应的掩码
iFlag As Integer    
End Type
Public info As DEV_BROADCAST_HDR
Public info_volume As DEV_BROADCAST_VOLUME
Public PrevProc As Long   ‘原来的窗体消息处理函数地址
Public Sub HookForm(F As Form)
     PrevProc = SetWindowLong(F.hwnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub
Public Sub UnHookForm(F As Form)
     SetWindowLong F.hwnd, GWL_WNDPROC, PrevProc
End Sub
Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam 
As Long, ByVal lParam As Long) As Long
     Select Case uMsg
            '插入USB DISK 则接收到此消息
           Case WM_DEVICECHANGE
            If wParam = DBT_DEVICEARRIVAL Then
           
            '若插入USBDISK或者映射网络盘等则
            'info.lDevicetype =2
            '即DBT_DEVTYP_VOLUME
           
            ‘利用参数lParam获取结构体头部信息
            CopyMemory info, ByVal lParam, Len(info)
           
            If info.lDevicetype = DBT_DEVTYP_VOLUME Then
             
              CopyMemory info_volume, ByVal lParam, Len(info_volume)
             
              '检测到有逻辑卷添加到系统中,则显示该设备根目录下全部文件名
              ListFiles Chr(GetDriveName(info_volume.lUnitMask)) & ":\", 
Form1.List1
            End If
            End If
           
            If wParam = DBT_DEVICEREMOVECOMPLETE Then
           
            '若移走USBDISK或者映射网络盘等则
            'info.lDevicetype =2
            '即DBT_DEVTYP_VOLUME
           
            ‘利用参数lParam获取结构体头部信息
            CopyMemory info, ByVal lParam, Len(info)
                      
            If info.lDevicetype = DBT_DEVTYP_VOLUME Then
              CopyMemory info_volume, ByVal lParam, Len(info_volume)
             
              '清除LIST中的内容
              Form1.List1.Clear
            End If
            End If          
        
      End Select
     ' 调用原来的窗体消息处理函数
     WindowProc = CallWindowProc(PrevProc, hwnd, uMsg, wParam, lParam)
    
End Function
'根据输入的32位LONG型数据(只有一位为1)返回对应的卷标的ASCII数值
'规则是1:A、2:B、4:C等等
Function GetDriveName(ByVal lUnitMask As Long) As Byte
Dim i As Long
i = 0
While lUnitMask Mod 2 <> 1
    lUnitMask = lUnitMask \ 2
    i = i + 1
Wend
GetDriveName = Asc("A") + i
End Function
'显示插入逻辑卷根目录的文件名列表,需要在工程里引用Microsoft Scripting Runtime库。
Function ListFiles(strPath As String, ByRef list As ListBox)
   Dim fso As New Scripting.FileSystemObject
   Dim objFolder As Folder
   Dim objFile As File
  
   Set objFolder = fso.GetFolder(strPath)
  
   For Each objFile In objFolder.Files
     list.AddItem objFile.Name
   Next
End Function

窗体Form1代码:

Option Explicit
Private Sub Form_Load()
    '子类化窗体的消息处理函数
    HookForm Me
End Sub
Private Sub Form_Unload(Cancel As Integer)
    '程序退出时恢复原窗体处理函数
    UnHookForm Me
End Sub

效果图:

备注:本示例程序不仅仅能检测U盘的插入,对CDROM、网络映射盘等设备也会作出同样的反应,如果需要只检测U盘,则需要在If info.lDevicetype = 
DBT_DEVTYP_VOLUME 
处再对iFlag结构成员作检测,其数值为0时表示设备为U盘。另外根据微软的解释,软盘的插拔是不会有引发该消息的,原因是只有支持软弹出技术的设备才会引发该消息。(原文:Messages 
for media arrival and removal are sent only for media in devices that support a 
soft-eject mechanism. )
本演示程序在WINDOWS98、XP系统下调试通过。


VB部分相关文章推荐:

※vb中line的用法[转]

※画图工具的VB实现

※VB 一个获得自己外网 IP 地址的程序代码

※VB程序中实现IP地址子网掩码网关DNS的更改  [转]

※在 VB 中应用 FSO 对象模型介绍(摘自网络)

※[转] Vb中FSO 对象的介绍

※VB 画坐标轴

※VB 二进制文件的操作

※[VB]BMP转JPGVB中KeyCode常数用法

※vb实时曲线的绘制和保存

※VB操作EXCEL

※vb初学回顾:最大公约数 最小公倍数 素数求取

※vb 关于窗口样式的API以及处理文本的API参考

※【引用】在VB6.0中实现弹出式菜单的几种方法

※【引用】URLDownloadToFile_VB下载文件!

※利用WinRar压缩和解压缩文件

※VB 剪切板

※VB实现指示窗口中拖动方框的程序

※VB绘制走动的表针

※如何用VB制作DLL文件

※【引用】VB修改IP地址

※VB多窗体退出代码

※[转]VB:如何检测到U盘的插拔(源代码)

※巧用SendMessage函数扩展Treeview功能

※vb中如何在任务管理器里面隐藏应用程序进程

※如何实现VB与EXCEL的无缝连接

※一个API方式存取日志文件的模块[VB]

※VB用记录集填充表格函数

※VB打开文本文件各种方法

※vb ClipBoard 剪切板应用(复制剪切粘贴)

※【引用】窗口处理技巧大全 vb(窗体控件)

※【转】 Md rd命令之VB

※vb:读写文本文件

※在vb中实现真正锁定的带自定义菜单的文本控件

※【引用】使用CommonDialog的ShowSave后如何判断是保存还是※取消?

※vb 关于commondialog的多选VB获取Windows操作系统所有版本

※vb UTF文本文件访问

※VB编程中的Unicode vs Ansi

※VB编PiView4注册机

※VB获取超过2G文件的大小

※比CopyMemory还要快的函数SuperCopyMemory

※VB:编程效率快步提高之:十七种可用一行代码完成的技巧

※VB画出来的五星红旗

※Qt第一印象——Qte与Qt


更多精彩>>>

[转]VB:如何检测到U盘的插拔(源代码)相关推荐

  1. Android开发-动态获取电视盒子U盘的插拔状态和路径

    最近公司的盒子端扩展一个新功能:插入U盘后自动幻灯片播放U盘指定文件夹下的所有图片,拔出U盘后恢复视频播放. 直接上代码: 一.注册广播监听U盘的插拔 1.1.注册 IntentFilter inte ...

  2. sim插拔识别时间_一种sim卡检测装置及其检测sim卡插拔的方法

    一种sim卡检测装置及其检测sim卡插拔的方法 [技术领域] [0001]本发明涉及移动通讯设备领域,尤其涉及一种S頂卡检测装置及其检测S頂卡插拔的方法. [背景技术] [0002]S頂卡是移动终端中 ...

  3. VB中简便的检测U盘插拔的方法(DriveListBox)

    我在网上找了很多资料,实现检测U盘插拔的方法基本上都是监测WM_DEVICECHANGE.这种方法不但臃肿,而且效率不高,很容易出错.于是我摸索出了一种新的方法,以下就是实现过程. 首先在窗体中添加一 ...

  4. MFC使用Windows API实现U盘插拔检测,获取U盘容量,U盘内容移动删除,开启和关闭U盘以及获取盘符

    文章目录 前言 一.利用OS API实现对U盘的管理 二.项目到底长啥样 三.实例代码 1.实时判断U盘插入与拔出 2.能够显示U盘的总容量.使用容量和剩余容量 3.能够将某个目录上的文件或整个目录复 ...

  5. C#随手笔记——自动检测外部设备(U盘)的插拔

    Windows系统下,每当外部设备有变动时都会向所有窗体发送一个消息,我们根据这点可以让程序检测出例如U盘插拔的信号,在C#代码中实现如下: [StructLayout(LayoutKind.Sequ ...

  6. linux U盘插拔检测

    因为最终要在tiny210上实现此功能,最终选择了hotplug. http://hi.baidu.com/hdy5200075/item/7751f48647f3d12a100ef3f6这里是hot ...

  7. u盘插在电脑上没有反应_电脑无法识别U盘或插上U盘提示格式化

    不识别U盘有很多种可能情况,原因及解决办法: 1.您的U盘已经损坏了,2.USB接口问题:3.您的电脑USB驱动有问题.你可以试着更新一下驱动:4.电脑问题换一台电脑试试 报错提示如下情况 1.先将要 ...

  8. 删除u盘插拔记录linux,电脑u盘插拔记录_电脑u盘插拔时间记录

    2016-06-07 18:50:08 按照如下步骤进行处理,尝试解决问题. 1.USB接口损坏.接触不良也会出现此情况,换一个USB接口,台式机插入主机后接口试试. 2.插入电脑,右下角有图标,不显 ...

  9. android u盘广播路径,android6.0 外部存储设备插拔广播以及获取路径(U盘)

    android4.1版本时U盘插拔时的广播 在android4.1时我们可以用以下的BroadcastReceiver接收U盘广播. 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 a ...

最新文章

  1. 使用Javascript获取图片坐标以及宽度高度的方法
  2. CAN总线在嵌入式Linux下驱动程序的实现
  3. 40个超酷的jQuery动画教程
  4. java语言执行模式,使用java.exe执行静默模式
  5. python自动化测试框架结构_基于Python的HTTP接口自动化测试框架实现
  6. 摘抄:微软 Dynamics AX 学习步骤
  7. mysql扩展文件_MySQL中的空间扩展
  8. 虚拟机+centOS挂载ISO步骤
  9. kali安装zmap
  10. centos7使用iso镜像离线安装依赖工具
  11. windows安装memcached
  12. vue element-ui实现input输入框金额数字添加千分位
  13. html自动定时弹窗,html网页弹窗代码 setinterval 定时任务啊
  14. 车载网络技术——CAN总线基础
  15. CSR867x一拖多加密工具8670 8675
  16. L3-007 天梯地图
  17. java培优学习笔记(一)多线程快速入门
  18. 图像处理中常用的彩色模型
  19. 十五天学会Autodesk Inventor,看完这一系列就够了(十),凸雕、贴图
  20. Automatic multiorgan segmentation in thorax CT images using U-net-GAN

热门文章

  1. ElasticSearch 7 正式发布!
  2. 走不远的共享滑板车!
  3. 未来 10 年的科技圈,将会因这 10 项技术而颠覆!
  4. 微软“作死”Windows
  5. 人工智能芯片的前世与今生
  6. 百度,你拿什么和谷歌争?| 畅言
  7. 等重构完这系统,我就辞职!
  8. 如何评价程序员相亲约在肯德基反被拉黑?
  9. 网络编程之 listen()函数的使用与三次握手的理解
  10. Java定时器每小时执行一次