您的位置:首页 > 其它

USB移动存储设备的检测、写入及弹出

2013-01-10 13:00 246 查看

USB设备的基本操作涉及USB存储设备的插入检测及写入文件,同时可以在写入结束后自动弹出,下面介绍自己的实现方法。

(1)注册设备。

在检测之前需要对检测的设备进行注册。具体的代码如下:

//首先注册设备

void CUSBTestDlg::OnBtnRegister()

{

// TODO: Add your control notification handler code here

static const GUID GUID_DEVINTERFACE_LSIT[] =

{

//GUID_DEVINTERFACE_USB_DEVICE

{0xA5DCBF10,0x6530,0x11D2,{0x90,0x1F,0x00,0xC0,0x4F,0xB9,0x51,0xED}},

//GUID_DEVINTERFACE_DISK

{0X53F56307,0XB6BF,0X11D0,{0X94,0XF2,0X00,0XA0,0XC9,0X1E,0XFB,0X8B}},

//GUID_DEVINTERFACE_HID

{0X4D1E55B2,0XF16F,0X11CF,{0X88,0XCB,0X00,0X11,0X11,0X00,0X00,0X30}},

//GUID_NDIS_LAN_CLASS

{0XAD498944,0X762F,0X11D0,{0X8D,0XCB,0X00,0X00,0X4F,0XC3,0X35,0X8C}}

};

//注册插拔事件

HDEVNOTIFY hDevNotify;

DEV_BROADCAST_DEVICEINTERFACE NotifacationFiler;

ZeroMemory(&NotifacationFiler,sizeof(DEV_BROADCAST_DEVICEINTERFACE));

NotifacationFiler.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);

NotifacationFiler.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;

for(int i=0;i<sizeof(GUID_DEVINTERFACE_LSIT)/sizeof(GUID);i++)

{

NotifacationFiler.dbcc_classguid = GUID_DEVINTERFACE_LSIT[i];//GetCurrentUSBGUID();//m_usb->GetDriverGUID();

hDevNotify = RegisterDeviceNotification(m_hWnd,&NotifacationFiler,DEVICE_NOTIFY_WINDOW_HANDLE);

if(!hDevNotify)

{

int Err = GetLastError();

MessageBox("RegisterDeviceNotificationFailed");

}

else

MessageBox("RegisterDeviceNotificationSuccess");

}

}

(2)利用ON_WM_DEVICECHANGE实现检测。

这里需要手动添加ON_WM_DEVICECHANGE消息。首先头文件中声明响应函数:

afx_msg BOOL OnDeviceChange(UINT nEventType, DWORD dwData);

定义响应函数:

BOOL CUSBTestDlg::OnDeviceChange(UINT nEventType, DWORD dwData)

{

PDEV_BROADCAST_HDR pdb;

PDEV_BROADCAST_VOLUME pdbv;

CString strVolume="";

pdb = (PDEV_BROADCAST_HDR)dwData;

switch(nEventType)

{

case DBT_DEVICEARRIVAL:

// Check whether a CD or DVD was inserted into a drive.

if(pdb->dbch_devicetype==DBT_DEVTYP_VOLUME)

{

pdbv = (PDEV_BROADCAST_VOLUME)pdb;

JudgeDeviceChangePath(pdbv->dbcv_unitmask,strVolume);//获取卷标

g_strVolume = strVolume;

IOFileToMobileDevice(strVolume);//写入数据

}

if(pdb->dbch_devicetype==DBT_DEVTYP_DEVICEINTERFACE)

{

}

break;

case DBT_DEVICEREMOVECOMPLETE:

break;

default:

break;

}

return TRUE;

}

(3)弹出USB设备。

BOOL CUSBTestDlg::UnInstallUsb(char szDriveName)

{

DWORD accessMode = 0, shareMode = 0;

HANDLE hDevice;

ULONG returned = 0,bResult = 0;

DWORD dwError;

shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; // default

accessMode = GENERIC_WRITE | GENERIC_READ; // default

if(szDriveName == 0)

{

return FALSE;

}

CString vol_string = "\\\\.\\A:";

vol_string.SetAt(4, szDriveName);

TRACE("%s",vol_string);

hDevice = CreateFile(vol_string,accessMode,shareMode,NULL,OPEN_EXISTING,0,NULL);

if(hDevice == INVALID_HANDLE_VALUE)

{

CString debugInfo;

dwError = GetLastError();

debugInfo.Format("error = %d ", dwError);

TRACE("IOCTL_STORAGE_EJECT_MEDIA errorcode = %d \n", dwError);

return FALSE;

}

bResult = DeviceIoControl(hDevice,IOCTL_STORAGE_EJECT_MEDIA,NULL,0, NULL,0,&returned, NULL);

if(!bResult) // IOCTL failed //经实验,有时虽然失败了,U盘还是能弹出

{

CString debugInfo;

dwError = GetLastError();

debugInfo.Format("error = %d ", dwError);

TRACE("IOCTL_STORAGE_EJECT_MEDIA errorcode = %d \n", dwError);

}

bResult = CloseHandle(hDevice);

if(!bResult)

{

CString debugInfo;

dwError = GetLastError();

debugInfo.Format("error = %d ", dwError);

TRACE("IOCTL_STORAGE_EJECT_MEDIA errorcode = %d \n", dwError);

return FALSE;

}

return TRUE;

}

这个函数在按钮的实现中,即把卷标传入即可:

void CUSBTestDlg::OnButton1()

{

// TODO: Add your control notification handler code here

UnInstallUsb((char)g_strVolume.GetAt(0));

}

(4)需要的读取卷标和写入的函数。

void CUSBTestDlg::JudgeDeviceChangePath(DWORD dwData, CString &strPath)

{

for(int i=0;i<32;i++)

{

if(dwData&0x01)

{

//获取盘符

CString str=char('A'+i);

strPath+=str;

break;

}

dwData = dwData>>1;

if(dwData==0x0000)

break;

}

}

void CUSBTestDlg::IOFileToMobileDevice(CString str)

{

FILE* stream = NULL;

char paramfilepath[200];

strcpy(paramfilepath,str);

strcat(paramfilepath,":\\param.txt");

if((stream = fopen(paramfilepath,"w"))!=NULL)

{

fprintf(stream,"%d\n",11);

}

CTime m_SysTime = CTime::GetCurrentTime();

CString TimeStr;

TimeStr = m_SysTime.Format("%Y%m%d%H%M%S");

fprintf(stream,"%s\n",TimeStr);

fclose(stream);

stream = NULL;

MessageBox("Write Success");

}

(5)注意事项。

头文件中需要包含:

#include <dbt.h>//

#include <winioctl.h>//IOCTL_STORAGE_EJECT_MEDIA未定义的问题

在StdAfx.h中定义如下:

#define WINVER 0X0500

这个宏定义的位置必须正确,在

#if !defined(AFX_STDAFX_H__30C2945E_D8FC_4DCD_B67A_099B447FE1AD__INCLUDED_)

#define AFX_STDAFX_H__30C2945E_D8FC_4DCD_B67A_099B447FE1AD__INCLUDED_

//solved 'DEV_BROADCAST_DEVICEINTERFACE' : undeclared identifier

#define WINVER 0X0500

#if _MSC_VER > 1000

#pragma once

#endif // _MSC_VER > 1000

下载地址:http://download.csdn.net/detail/zqckzqck/4980910

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: