在程序中,有时候需要区分移动硬盘和本地硬盘,U盘的检测比较简单,首先用GetLogicalDriveStrings获取盘符,然后用GetDriveType获取类型,返回结果为DRIVE_REMOVABLE,则为U盘。这里有个问题,就是如果电脑中存在可移动磁盘的盘符,却没有插入移动磁盘,这时候如果试图打开这个磁盘,系统会提示你插入磁盘。所以,应该在检测到类型为DRIVE_REMOVABLE之后,再使用GetVolumeInformation获取卷信息,如果获取成功,则说明该盘符已插入磁盘。

对于移动硬盘,使用GetDriveType返回的结果永远为DRIVE_FIXED,就是说系统将其与本地硬盘归为一类。那么,如何区分指定盘符是移动硬盘还是本地硬盘呢?

首先用CreateFile通过指定的盘符打开设备,返回设备句柄,然后用DeviceIoControl获取设备信息,通过总线类型判断是否USB接入,如果总线类型为USB则是移动硬盘。

代码如下:

bool CopyFileThread::checkRemoveDisk(vector<LPTSTR>* drivePath)   //参数存储所有移动盘的盘符
{
 bool flag=false;
 DWORD dw=GetLogicalDriveStrings(0,NULL);
 LPTSTR lpDriveStrings=(LPTSTR)HeapAlloc(GetProcessHeap(),0,dw*sizeof(TCHAR));
 GetLogicalDriveStrings(dw,lpDriveStrings);      //获取盘符,字符串形式。
 do
 {
  UINT drivetype=GetDriveType(lpDriveStrings);   //获取驱动器类型
  if(drivetype==DRIVE_REMOVABLE)

//驱动器类型为DRIVE_REMOVABLE,进一步获取卷信息,如果获取成功,则将盘符保存。
  {
   TCHAR szFileSNBuffer[512];
   DWORD dwFSystemFlags;
   //获取卷信息,如果获取成功,则说明已插入U盘。
   if(GetVolumeInformation(lpDriveStrings,NULL,0,NULL,NULL,&dwFSystemFlags,szFileSNBuffer,512))
   {
    drivePath->push_back(lpDriveStrings);
    flag=true;
   }
  }
  else if(drivetype==DRIVE_FIXED)   //驱动器类型为DRIVE_FIXED,需要进一步判断是移动硬盘还是本地硬盘。
  {
   if(GetDisksProperty( lpDriveStrings)==TRUE)   //GetDisksProperty区分移动硬盘和本地硬盘,返回TRUE为移动硬盘.
   {
    drivePath->push_back(lpDriveStrings);
    flag=true;
   }
  }
  lpDriveStrings+=(lstrlen(lpDriveStrings)+1);
 }
 while(*lpDriveStrings!='\x00');
 return flag;
}

GetDisksProperty定义如下:

BOOL CopyFileThread::GetDisksProperty(TCHAR *drive)
{
 STORAGE_PROPERTY_QUERY Query;
 DWORD dwOutBytes;
 BOOL bResult;
 Query.PropertyId = StorageDeviceProperty;
 Query.QueryType = PropertyStandardQuery;
 CString cstr(drive);
 cstr="\\\\.\\"+cstr;
 cstr.Delete(cstr.GetLength()-1,1);
 HANDLE hDevice=CreateFile(
  cstr, // 要打开的驱动器设备;格式必须为“\\.\C:”,否则打开失败,返回错误码2:系统找不到指定的文件。
  GENERIC_READ | GENERIC_WRITE,     // 访问权限
  FILE_SHARE_READ | FILE_SHARE_WRITE, //共享模式
  NULL,             // 使用默认的安全属性
  OPEN_EXISTING,    // 打开存在的设备
  NULL,            
  NULL           
  );
 if (hDevice == INVALID_HANDLE_VALUE)
 {
  return FALSE;
 }

STORAGE_DESCRIPTOR_HEADER *pDevDescHeader;
 pDevDescHeader = (STORAGE_DESCRIPTOR_HEADER *)malloc(sizeof(STORAGE_DESCRIPTOR_HEADER));
 if (NULL == pDevDescHeader)
 {
  return FALSE;
 }
 bResult = DeviceIoControl(
  hDevice,     // 设备句柄
  IOCTL_STORAGE_QUERY_PROPERTY,     // 操作控制码
  &Query,sizeof Query,   //输入参数及缓冲区大小
  pDevDescHeader,     //输出参数
  sizeof(STORAGE_DESCRIPTOR_HEADER),  //输出参数的缓冲区大小
  &dwOutBytes,     //实际输出的大小
  NULL);    
 if (!bResult)      
 {
  free(pDevDescHeader);
  (void)CloseHandle(hDevice);
  return FALSE;
 }
 PSTORAGE_DEVICE_DESCRIPTOR pDevDesc;
 pDevDesc=(STORAGE_DEVICE_DESCRIPTOR *)malloc(pDevDescHeader->Size);
 bResult = DeviceIoControl(hDevice,
  IOCTL_STORAGE_QUERY_PROPERTY,
  &Query, sizeof Query,
  pDevDesc, pDevDescHeader->Size, 
  &dwOutBytes,
  NULL);
 free(pDevDescHeader);
 (void)CloseHandle(hDevice);
 if(pDevDesc->BusType==BusTypeUsb)//总线类型为USB,返回TRUE
 {
  free(pDevDesc);
  return TRUE;
 }
 free(pDevDesc);
 return FALSE;
}

使用windows API区分移动硬盘和本地硬盘相关推荐

  1. U盘移动硬盘变本地硬盘怎么办 ,移动硬盘变本地硬盘的恢复方法

    这是分区逻辑损坏后最常见的表现.U盘移动硬盘变本地硬盘怎么办 ,移动硬盘变本地硬盘的恢复方法有些用人到这种情况后首先会尝试使用Windows系统自带的硬盘修复工具chk命令进行修复,不过,这样操作并不 ...

  2. 移动硬盘变本地硬盘,小编教你移动硬盘变本地硬盘怎么办

    移动硬盘提示:移动硬盘变本地磁盘如何解决?相信大家对移动硬盘都很熟悉,几乎每个人都有,因为移动硬盘内存空间大,便于储存文件,很方便.接下来,针对这一问题,下面来分享系统移动硬盘移动硬盘变本地磁盘的解决 ...

  3. windows 挂载百度网盘/阿里云盘等(网盘变本地硬盘) alist + raidrive

    windows 挂载百度网盘/阿里云盘等 alist + raidrive Alist安装 使用步骤: Raidrive安装 Alist安装 AList: 一个支持多种存储的文件列表程序,使用 Gin ...

  4. 用C#和本地Windows API操纵系统菜单

    一.前言 .net框架是Windows应用领域中一个非常新的技术,可以肯定在未来的一段时间内,.NET应用必须与现存的Windows技术交互作用.这种交互作用主要体现在两个领域:COM和应用编程接口( ...

  5. 移动硬盘识别为本地硬盘_如果仅在硬盘已经旋转时才能识别硬盘,该怎么办?

    移动硬盘识别为本地硬盘 What do you do when your computer only recognizes your hard-drive part of the time? Is i ...

  6. Windows平台下使用 Rclone 挂载 OneDrive Google Drive 为本地硬盘

    本文首发于 热夏的博客 https://upwon.github.io/ Rclone (rsync for cloud storage) 是一个命令行程序,用于同步文件和目录,支持常见的 Amazo ...

  7. Windows API详情

    Windows API详情 原文链接:https://docs.microsoft.com/zh-cn/windows/desktop/apiindex/windows-api-list 桌面和服务器 ...

  8. VBS调用Windows API函数

    Demon's Blog 忘记了,喜欢一个人的感觉 Demon's Blog  »  程序设计  »  VBS调用Windows API函数 « 用VBS修改Windows用户密码 在VB中创建和使用 ...

  9. Windows API一日一练(一)第一个应用程序 使用应用程序句柄 使用命令行参数 MessageBox函数 RegisterClass和RegisterClassEx函数

    要跟计算机进行交互,就需要计算机显示信息给人看到,或者发出声音给人听到,然后人看到或听到相应的信息后,再输入其它信息给计算机,这样就可以让计算机进行数据处理,把结果显示给我们.现在就来编写一个最简单的 ...

  10. Windows API的时间结构体、时间转换及时间获取

    Windows API的时间结构体.时间转换及时间获取   时间格式:DosDateTime <====>FileTime <====> SystemTime |        ...

最新文章

  1. Java泛型 通配符? extends与super
  2. VC++结束程序进程
  3. lda主题词评论python_Python之酒店评论主题提取LDA主题模型
  4. Blazor University (2)布局 — 创建 Blazor 布局
  5. Java虚拟机详解----常用JVM配置参数
  6. java map hashtable_Java的HashMap和HashTable
  7. 设计模式16-访问者模式
  8. python中的列表推导与生成器
  9. 平安科技一轮等多久_科技正等着我们成长
  10. gpasswd 附属组管理,添加用户到附属组中
  11. IEEE 2021年新增Fellow出炉,70余位华人入选
  12. CPU、内存、I/O设备速度差异
  13. 灰色预测的MATLAB代码
  14. 为什么感知机不能表示异或?
  15. 项目经验怎么写HTML,简历中的项目经验怎么写
  16. Alpha版本冲刺(三)
  17. 《Armv8/armv9架构入门指南》-【第四章】- ARMv8 寄存器
  18. matlab 电化学程序,基于MATLAB的电化学滴定曲线导数变换的实现
  19. 【C素数】素数(质数)和分解质因数
  20. 安卓逆向从入门到嗝屁之另一道CTF题目

热门文章

  1. 李宏毅2021机器学习笔记——Transformer
  2. EXCEL科学计数法转为文本格式
  3. 【图像处理】图像锐化
  4. 论文参考文献格式及意义
  5. PHP实现支付宝手机WAP支付接入说明
  6. win7计算机桌面文件位置更改,Win7系统怎么更改桌面文件路径_win7修改桌面文件保存路径的方法...
  7. 端口已经被占用 (Port 8081 already in use)解决方法
  8. JS时间增加2个小时
  9. lisp全部文本改宋体字型_如何将CAD里面的文字一下全改成宋体 CAD2014中如何将图...
  10. word上怎么把图片拼接到一起_word怎么将图片合并