原创地址:http://blog.youkuaiyun.com/jingzhongrong/archive/2007/01/02/1472440.aspx
今天看到一篇文章里面说到的检测U盘插入的方法
文章中使用的是用循环不停检测系统盘符的变化,然后根据盘符对应的类型来判 断。
下面是大概的方法
int CheckDisk(char *disk)
{
if(GetDriveType(disk)==DRIVE_REMOVABLE)return 0;
return -1;
}
int dectect()
{ char buf[10];
DWORD lod=GetLogicalDrives();
if (lod!=0)
{
for (int i=0;i<26;i++)
{
if ((lod & 1)==1)
{
sprintf(buf,"%c",'A'+i);
strcat(buf,":/");
if(!CheckDisk(buf))
{
if(GetVolumeInformation(buf,0,0,0,0,0,0,0))
{
//检测到U盘并且驱动器已准备就绪
}
}
}
lod=lod>>1;
}
}
return 0;
}
//然后使用
while(1)
{
dected();
//此处可以添加Sleep函数停止一段时间,以免过高占用CPU
}
下面是我的实现,不使用循环,使用C++Builder完成, 原理是当U盘插入或移除的时候 Windows会生成一条信息WM_DEVICECHANGE 处理此消息便可 使用VC的可以定义一个WindowProc的回调函数,其中的实现与下面的WndProc类似 上面代码其实并没有对是否为USB设备进行判断,在MSDN中提到此消息在添加网络驱动器时也会产生 要判断USB设备,可以这样 if (dbvDev->dbcv_flags & DBTF_MEDIA) 下面是MSDN中PDEV_BROADCAST_VOLUME的参数dbcv_flags 描述: 原理已经说完,发挥一下想象,可以写出一个简单的判断U盘中是否有病毒的小程序, 现在很多使用U盘传播的病毒,都会在U盘下生成带有“autorun”的文件,通过判断是否有autorun文件进行判断,提示用户注意。 程序在Windows2003+Borland Developer C++Builder 2006中调试通过 //$$---- Form CPP ---- //$$---- Form HDR ----
{
if(started)
{
if(Message.Msg == WM_DEVICECHANGE)
{
switch(Message.WParam)
{
case 0x8000: //DBT_DEVICEARRIVAL
{
ShowMessage("U盘插入");
PDEV_BROADCAST_VOLUME dbvDev = (PDEV_BROADCAST_VOLUME)Message.LParam;
DWORD vn = dbvDev->dbcv_unitmask;
//this->HasAutoRunInFileName(vn);
break;
}
case DBT_DEVICEREMOVECOMPLETE: //0x8004
ShowMessage("U盘拔出");
break;
}
}
}
TForm::WndProc(Message); //处理其他消息
}Value Meaning DBTF_MEDIA Change affects media in drive. If not set, change affects physical device or drive. DBTF_NET Indicated logical volume is a network volume.
#pragma hdrstop
#include "Unit1.h"
#include <windows.h>
#include <dir.h>
#include <io.h>
#include <fcntl.h>
#include <Dbt.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
started = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::WndProc(TMessage &Message)
{
if(started)
{
if(Message.Msg == WM_DEVICECHANGE)
{
switch(Message.WParam)
{
case 0x8000: //DBT_DEVICEARRIVAL
{
ShowMessage("U盘插入");
//PDEV_BROADCAST_HDR dbhDev = (PDEV_BROADCAST_HDR)Message.LParam;
PDEV_BROADCAST_VOLUME dbvDev = (PDEV_BROADCAST_VOLUME)Message.LParam;
//if(dbhDev.dbch_devicetype == DBT_DEVTYP_VOLUME)
//{
DWORD vn = dbvDev->dbcv_unitmask;
this->HasAutoRunInFileName(vn);
//}
break;
}
case DBT_DEVICEREMOVECOMPLETE: //0x8004
ShowMessage("U盘拔出");
break;
}
}
}
TForm::WndProc(Message);
}
//---------------------------------------------------------------------------
bool __fastcall TForm1::HasAutoRunInFileName(unsigned long area)
{
char s = FirstDriveFromMask(area);
struct ffblk ffblk;
int done;
AnsiString path = AnsiString(s);
path += ":/";
path += "*autorun*";
done = findfirst(path.c_str(),&ffblk,0);
Memo1->Clear();
while (!done)
{
Memo1->Lines->Add(AnsiString(ffblk.ff_name));
done = findnext(&ffblk);
}
if(Memo1->Lines->Count != 0)
{
MessageBox(Handle,"注意,U盘中含有包含"autorun"字样的文件,可能是病毒请不要直接双击打开该U盘","USBAutoRunScan",MB_OK | MB_ICONHAND);
return true;
}
return false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
started = true; //开始监视
Button2->Enabled = true;
Button1->Enabled = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
started = false; //停止监视
Button2->Enabled = false;
Button1->Enabled = true;
}
//---------------------------------------------------------------------------
char __fastcall TForm1::FirstDriveFromMask(ULONG unitmask)
{
char i;
for (i = 0; i < 26; ++i)
{
if (unitmask & 0x1)
break;
unitmask = unitmask >> 1;
}
return (i + 'A');
}
//---------------------------------------------------------------------------
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <windows.h>
#include <ExtCtrls.hpp>
#include <XPMan.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TMemo *Memo1;
TButton *Button1;
TButton *Button2;
TXPManifest *XPManifest1;
TTrayIcon *TrayIcon1;
void __fastcall Button1Click(TObject *Sender);
void __fastcall Button2Click(TObject *Sender);
private: // User declarations
bool __fastcall HasAutoRunInFileName(unsigned long area);
char __fastcall FirstDriveFromMask(ULONG unitmask);
bool started;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
void __fastcall WndProc(TMessage &Message);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif