Winapi 如何检测硬盘驱动器是否通过USB连接?

Winapi 如何检测硬盘驱动器是否通过USB连接?,winapi,usb,hard-drive,Winapi,Usb,Hard Drive,我正在尝试为朋友和家人编写一个小的备份程序,并希望它尽可能简单易用。我不想问用户将数据备份到哪里,我只想搜索并使用连接到计算机的第一个USB硬盘。获取硬盘驱动器的唯一ID可能也是一个好主意,就像下次备份运行时再次检查一样。可以轻松收集一些信息: 使用GetDriveType查找第一个可移动驱动器,测试是否存在可写介质(这将在很大程度上排除CD驱动器)。可能还想查看通过win32查询驱动器信息时可用的其他字符串 使用libusb查看第一个存储类USB设备的位置(可能是闪存或硬盘驱动器) 这指向您

我正在尝试为朋友和家人编写一个小的备份程序,并希望它尽可能简单易用。我不想问用户将数据备份到哪里,我只想搜索并使用连接到计算机的第一个USB硬盘。获取硬盘驱动器的唯一ID可能也是一个好主意,就像下次备份运行时再次检查一样。

可以轻松收集一些信息:

  • 使用GetDriveType查找第一个可移动驱动器,测试是否存在可写介质(这将在很大程度上排除CD驱动器)。可能还想查看通过win32查询驱动器信息时可用的其他字符串
  • 使用libusb查看第一个存储类USB设备的位置(可能是闪存或硬盘驱动器)
  • 这指向您可能能够进入的win32磁盘驱动器类
当你找到答案时,把它贴在这里


-Adam

我知道你的问题被标记为Win32,但这在.NET中非常简单:

foreach (IO.DriveInfo drive in IO.DriveInfo.GetDrives()) {
  if ((drive.DriveType == IO.DriveType.Removable)) {
    // this is a removable drive
  }
}
请参阅drive.Name和drive.VolumeLabel以获取标签。你也可以得到它的尺寸,并根据需要猜测它是一个U盘(而且足够大)——可移动可以指软盘或USB

作为旁注,从UI的角度来看,我建议您在第一次找到新驱动器时,将其呈现给用户,并询问“这是您要用于备份的驱动器吗?”。否则,很可能会意外地擦除碰巧插入的usb密钥上的数据。没有什么比备份程序破坏您的数据更能破坏备份程序的可信度了。:)

您需要使用函数。是关于如何做的一些建议。还有一个

您可以使用示例枚举所有大容量存储设备。一般来说,寻找SetupDiXXX api


请注意,考虑到usb设备的动态特性,IMHO必须使用通知机制。您可能会发现您的自我分析设备已经分离或丢失了刚刚到达的新设备

我花了一点时间四处寻找,发现了一个名为SetupDiEnumDeviceInfo的函数,它确实提供了一个了解硬盘是否可移动的解决方案,但有了这些信息,我仍然无法(目前)将我找到的信息映射回驱动器号

以下是我到目前为止所做的(以下代码创建了一个dll):

#包括“stdafx.h”
#包括
#包括
#包括
外部“C”declspec(dllexport)int usb_硬盘驱动器(){
HDEVINFO HDEVINFO=SetupDiGetClassDevs(&GUID\u DEVCLASS\u DISKDRIVE,NULL,NULL,DIGCF\u PRESENT);
if(hdevinfo==无效的句柄值)返回-1;
DWORD MemberIndex=0;
SP_DEVINFO_数据SP_DEVINFO_数据;
零内存(&sp_devinfo_数据,sizeof(sp_devinfo_数据));
sp_devinfo_data.cbSize=sizeof(sp_devinfo_data);
int c=0;
while(SetupDiEnumDeviceInfo(hdevinfo、MemberIndex和sp_devinfo_数据)){
DWORD PropertyRegDataType;
德沃德要求的尺寸;
德沃德物业公司;
if(SetupDiGetDeviceRegistryProperty(HDeInfo和sp_设备信息数据、SPDRP_功能和PropertyRegDataType(PBYTE)和PropertyBuffer、sizeof(PropertyBuffer)和RequiredSize)){
if(PropertyBuffer&&CM\u DEVCAP\u REMOVABLE==CM\u DEVCAP\u REMOVABLE){
//在此处执行一些操作以识别驱动器号。
C++;
}
}       
MemberIndex++;
}
SetupDiDestroyDeviceInfo列表(hdevinfo);
返回c;
}

我发现Win32 API中有一个很好的函数,可以测试驱动器的类型

if( 2 == ::getDriveType( <driveletter> )){
  // its removable 
}
if(2==::getDriveType()){
//它是可拆卸的
}
函数的返回值:

驱动程序未知 0:无法确定驱动器类型

驱动器号根目录 1:根路径无效;例如,指定路径上没有装入卷

可拆卸驱动器 2:驱动器具有可移动介质;例如,软盘驱动器、拇指驱动器或闪存卡读卡器

固定驱动器 3:驱动器有固定介质;例如,硬盘驱动器或闪存驱动器

远程驾驶 4:驱动器是远程(网络)驱动器

光驱 5:驱动器是CD-ROM驱动器

磁盘驱动器 6:驱动器是一个RAM磁盘


感谢您的快速回复。GetDriveInfo为固定硬盘驱动器(驱动器C)返回与UDB硬盘驱动器相同的值;驾驶室修好了。我用一个USB笔驱动器尝试了它,它报告它是可移动的。我假设IO.DriveInfo与win32 api中的GetDriveInfo相同。如果是这样,它为USB硬盘驱动器返回的值与为固定硬盘驱动器(drive_fixed)返回的值相同。感谢指针,但我不想检测驱动器何时连接或断开,我想知道连接的驱动器是否为USB驱动器(可以在程序启动前插入)。如果已知文件位于可移动驱动器(根驱动器)的已知位置,则可以循环查找所有驱动器号以查找该文件。当你找到它时,你就知道驱动器号了。
if( 2 == ::getDriveType( <driveletter> )){
  // its removable 
}