首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

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

2013-02-19 
USB移动存储设备的检测、写入及弹出本帖最后由 zqckzqck 于 2013-01-10 13:16:22 编辑USB设备的基本操作涉

USB移动存储设备的检测、写入及弹出
本帖最后由 zqckzqck 于 2013-01-10 13:16:22 编辑
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);
 
定义响应函数:
 
[code=css]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;
 }
[/code] 
(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
 
这个宏定义的位置必须正确,在
 


[解决办法]
是好东西~虽然我自己也实现了...
[解决办法]
感谢分享~~
[解决办法]
这个必须要支持啊 谢谢
[解决办法]
这个很喜欢USB移动存储设备的检测、写下及弹出
[解决办法]
USB移动存储设备的检测、写下及弹出
[解决办法]
USB移动存储设备的检测、写下及弹出
[解决办法]

[解决办法]
这个地支持!!!!
[解决办法]
ON_WM_DEVICECHANGE消息根本没定义啊????

热点排行