By jingzhongrong
今天看到一篇文章里面说到的检测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类似
{
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); //处理其他消息
}
上面代码其实并没有对是否为USB设备进行判断,在MSDN中提到此消息在添加网络驱动器时也会产生
要判断USB设备,可以这样
if (dbvDev->dbcv_flags & DBTF_MEDIA)
下面是MSDN中PDEV_BROADCAST_VOLUME的参数dbcv_flags 描述:
dbcv_flagsValue | 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. |
原理已经说完,发挥一下想象,可以写出一个简单的判断U盘中是否有病毒的小程序,
现在很多使用U盘传播的病毒,都会在U盘下生成带有“autorun”的文件,通过判断是否有autorun文件进行判断,提示用户注意。
程序在Windows2003+Borland Developer C++Builder 2006中调试通过
//$$---- Form CPP ----
#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' );
}
//---------------------------------------------------------------------------
//$$---- Form HDR ----
#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
last edit by jingzhongrong on Jan 5th,2007 12:58