天天看点

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

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