目前碰到这样一个需求,每插入一个新的移动设备就弹个框,即使是多个分区也只弹一个。我目前通过接收WM_DEVICECHANGE消息来判断新增设备,但是有的移动硬盘有三四个盘符, 这样我就会接收到三四个这个消息,然后弹出多个框,这个问题怎么能解决?

解决方案 »

  1.   

     http://group.gimoo.net/review/8965
      

  2.   

    BOOL   CCopyHook::IsIDE(CString   DriveName)   
      {   
      ////本段程序的前提是DriveName是已经过GetDriveType的判断是本地磁盘,否则报错,作用是判断是否是真正的本地磁盘////////   
      //////////////////111111111111111111111111111111111111111/////////////////////////////////////////////   
      ///////////////////////获得某分区(目的地址)的信息/////////////////////////   
      HANDLE   hDeviceDest   =   NULL;   
      DWORD   nBytesRead   =   0;//预设为0,当缓冲区的长度不够时,该值为所需的缓冲区的长度   
      DWORD   nBufferSize   =   sizeof(PARTITION_INFORMATION);   
      PPARTITION_INFORMATION   lpPartInfo   =   (PPARTITION_INFORMATION)malloc(nBufferSize);   
      if(lpPartInfo   ==   NULL)   
      {   
      //MessageBox("缓冲区分配出错!","失败!",MB_OK);   
      return   FALSE;   
      }   
      memset(lpPartInfo,   0,   nBufferSize);//将缓冲区lpPartInfo的内容设为nDiskBufferSize个NULL   
      //CString   DriveName="J:";//为判断提供接口   
      DriveName="\\\\.\\"+DriveName;   
        
      hDeviceDest   =   CreateFile(LPCTSTR(DriveName),//注意一定要是\\\\.\\的形式,CreateFile的要求   ""\\??\\Volume{e9233817-90be-11d6-88b7-00e04c3de005}   
      GENERIC_READ,   
      FILE_SHARE_READ   |   FILE_SHARE_WRITE,   
      NULL,   OPEN_EXISTING,   
      0,   NULL);   
        
      if(hDeviceDest   ==   NULL)   
      {   
      //MessageBox("CreateFile出错!","失败!",MB_OK);   
      return   FALSE;   
      }   
      /////////////获得该分区信息/////////////////////////   
      BOOL   ret1=DeviceIoControl(   
      hDeviceDest,   
      IOCTL_DISK_GET_PARTITION_INFO,   
      NULL,   
      0,   
      (LPVOID)   lpPartInfo,   
      (DWORD)   nBufferSize,   
      (LPDWORD)   &nBytesRead,   
      NULL//指向一个异步的结构体   
      );   
        
      if   (!ret1)   
      {   
      LPVOID   lpMsgBuf;   
      FormatMessage(     
      FORMAT_MESSAGE_ALLOCATE_BUFFER   |     
      FORMAT_MESSAGE_FROM_SYSTEM   |     
      FORMAT_MESSAGE_IGNORE_INSERTS,   
      NULL,   
      GetLastError(),   
      MAKELANGID(LANG_NEUTRAL,   SUBLANG_DEFAULT),   //   Default   language   
      (LPTSTR)   &lpMsgBuf,   
      0,   
      NULL     
      );   
      //MessageBox(   (LPCTSTR)lpMsgBuf,   "Error",   MB_OK   |   MB_ICONINFORMATION   );   
      LocalFree(   lpMsgBuf   );   
      //MessageBox("DeviceIoControl出错!","失败!",MB_OK);   
      return     FALSE;   
      }   
      ///////////////////导出该分区信息///////////////////////////////////   
      LARGE_INTEGER   StartingOffset=lpPartInfo->StartingOffset;   
      LONGLONG   QuadPart=StartingOffset.QuadPart;//取上面的值之一情形,支持64位整型   
      LARGE_INTEGER   PartitionLength=lpPartInfo->PartitionLength;   
      LONGLONG   QuadPart1=PartitionLength.QuadPart;//取上面的值之一情形,支持64位整型   
      DWORD   HiddenSectors=lpPartInfo->HiddenSectors;   
      DWORD   PartitionNumber=lpPartInfo->PartitionNumber;   
      BYTE     PartitionType=lpPartInfo->PartitionType;   
      BOOLEAN   BootIndicator=lpPartInfo->BootIndicator;   
      BOOLEAN   RecognizedPartition=lpPartInfo->RecognizedPartition;   
      BOOLEAN   RewritePartition=lpPartInfo->RewritePartition;   
        
      free(lpPartInfo);   
      CloseHandle(hDeviceDest);   
        
      /////////////////////查询注册表中COUNT(Disk)的值//////////////////////////////////////   
      UINT   IDESeqNum;//IDE的序号   
      BOOL   FindIDE=FALSE;   
        
      HKEY   hKEY;   
      RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum",   0,   KEY_READ,   &hKEY);     
      ///////////接收DWORD型/////////////   
        
      DWORD   Type;//仅仅用于接收数据类型   
      DWORD   dwValue;   
      DWORD   dwBufLen   =   sizeof(DWORD);   
      long   ret2=::RegQueryValueEx(hKEY,   _T("Count"),   NULL,   &Type,   (BYTE*)&dwValue,   &dwBufLen);   
      if(ret2!=ERROR_SUCCESS)   
      {   
      //MessageBox("找不到磁盘的个数","提示",MB_OK);   
      return   FALSE;//失败   
      }   
      for   (UINT   k=0;   k<dwValue;   k++)   
      {       
      ///////////接收字符型/////////////   
      char   str[256];   
      DWORD     sl   =   256;       
      CString   nDisk;   
      nDisk.Format("%u",k);   
      RegQueryValueEx(hKEY,     nDisk,     NULL,     NULL,     (LPBYTE)str,     &sl);   //注意第三项必须设为NULL,否则接收到的字符数据出错     
      CString   temp=str;   
      if   (temp.Left(3)=="IDE")   
      {   
      IDESeqNum=k;//IDE的序号   
      FindIDE=TRUE;   
      }   
        
      }   
      if   (!FindIDE)       
      return   FALSE;       //     IDESeqNum=0;   
      RegCloseKey(hKEY);       
        
      CString   temp;   
      temp.Format("%u",IDESeqNum);   
      temp="\\\\.\\PHYSICALDRIVE"+temp;//为下一步检测作准备   
      //////////////////22222222222222222222222222222222222222222   /////////////////////////////////////////   
        
        
      HANDLE   hDevice   =   NULL;   
      DWORD   nDiskBytesRead   =   0;//预设为0,当缓冲区的长度不够时,该值为所需的缓冲区的长度   
      DWORD   nDiskBufferSize   =   sizeof(DRIVE_LAYOUT_INFORMATION)   +   sizeof(PARTITION_INFORMATION)*104;//26*4   
      PDRIVE_LAYOUT_INFORMATION   lpDiskPartInfo   =   (PDRIVE_LAYOUT_INFORMATION)malloc(nDiskBufferSize);   
        
      if(lpDiskPartInfo   ==   NULL)   
      {   
      //MessageBox("缓冲区分配出错!","失败!",MB_OK);   
      return   FALSE;   
      }   
      memset(lpDiskPartInfo,   0,   nDiskBufferSize);//将缓冲区lpDiskPartInfo的内容设为nDiskBufferSize个NULL   
        
      //////////////////////获得所有分区的信息///////////////////////////////////////   
      hDevice   =   CreateFile(LPCTSTR(temp),//注意一定要是\\\\.\\的形式,CreateFile的要求   ""\\??\\Volume{e9233817-90be-11d6-88b7-00e04c3de005}   
      GENERIC_READ,   
      FILE_SHARE_READ   |   FILE_SHARE_WRITE,   
      NULL,   OPEN_EXISTING,   
      0,   NULL);   
        
      if(hDevice   ==   NULL)   
      {   
      //MessageBox("CreateFile出错!","失败!",MB_OK);   
      return   FALSE;   
      }   
        
      /////////////获得某磁盘上的所有分区信息/////////////////////////   
      BOOL   ret=DeviceIoControl(   
      hDevice,   
      IOCTL_DISK_GET_DRIVE_LAYOUT,   
      NULL,   
      0,   
      (LPVOID)   lpDiskPartInfo,   
      (DWORD)   nDiskBufferSize,   
      (LPDWORD)   &nDiskBytesRead,   
      NULL   
      );   
        
      if   (!ret)   
      {   
      LPVOID   lpMsgBuf;   
      FormatMessage(     
      FORMAT_MESSAGE_ALLOCATE_BUFFER   |     
      FORMAT_MESSAGE_FROM_SYSTEM   |     
      FORMAT_MESSAGE_IGNORE_INSERTS,   
      NULL,   
      GetLastError(),   
      MAKELANGID(LANG_NEUTRAL,   SUBLANG_DEFAULT),   //   Default   language   
      (LPTSTR)   &lpMsgBuf,   
      0,   
      NULL     
      );   
      //MessageBox(   (LPCTSTR)lpMsgBuf,   "Error",   MB_OK   |   MB_ICONINFORMATION   );   
      LocalFree(   lpMsgBuf   );   
      //MessageBox("DeviceIoControl出错!","失败!",MB_OK);   
      return   FALSE;   
      }   
        
      //////////////////////////////导出分区信息///////////////////////////////////////   
      DWORD   PartitionCount=lpDiskPartInfo->PartitionCount;     //永远是实际的分区数的4倍,不能用的分区将会显示类型PARTITION_ENTRY_UNUSED,即分区类型为0   
      ///////////////////依次获取导出某分区信息,并与目的驱动器进行比较///////////////////////////////////   
      for   (UINT   i=0;   i<PartitionCount;   i=i+4)//+4是因为只有下标为4的整数倍的值才是正确的引用   
      {   
      PARTITION_INFORMATION   DiskPartInfo=lpDiskPartInfo->PartitionEntry[i];//0为C:,4为D:,8为e:,12为F   
        
      LARGE_INTEGER   DiskStartingOffset   =   DiskPartInfo.StartingOffset;   
      LONGLONG   DiskQuadPart   =   DiskStartingOffset.QuadPart; //取上面的值之一情形,支持64位整型   
      LARGE_INTEGER   DiskPartitionLength   =   DiskPartInfo.PartitionLength;   
      LONGLONG   DiskQuadPart1   =   DiskPartitionLength.QuadPart; //取上面的值之一情形,支持64位整型   
      DWORD   DiskHiddenSectors   =   DiskPartInfo.HiddenSectors;   
      DWORD   DiskPartitionNumber   =   DiskPartInfo.PartitionNumber;   
      BYTE     DiskPartitionType   =   DiskPartInfo.PartitionType;   
      BOOLEAN   DiskBootIndicator   =   DiskPartInfo.BootIndicator;   
      BOOLEAN   DiskRecognizedPartition   =   DiskPartInfo.RecognizedPartition;   
      BOOLEAN   DiskRewritePartition   =   DiskPartInfo.RewritePartition;   
      if     ((DiskQuadPart==QuadPart)   &&   (DiskQuadPart1==QuadPart1)   
      &&   (DiskHiddenSectors==HiddenSectors)   &&   (DiskPartitionNumber==PartitionNumber)   
      &&   (DiskPartitionType==PartitionType   )   &&   (DiskBootIndicator==BootIndicator)   
      &&   (DiskRecognizedPartition==RecognizedPartition)   &&   (DiskRewritePartition==RewritePartition))   
      {   
      free(lpDiskPartInfo);   
      CloseHandle(hDevice);   
      ::MessageBox(NULL,"属于本地驱动器!","提示",MB_OK);   
      return   TRUE;   
      }   
      }   
      free(lpDiskPartInfo);   
      CloseHandle(hDevice);   
      ::MessageBox(NULL,"非本地驱动器!","提示",MB_OK);//改为return   IDCANCEL;   
      return   FALSE;   
      }