如何检测硬盘是否通过USB连接?

时间:2008-10-20 22:10:17

标签: winapi usb hard-drive

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

5 个答案:

答案 0 :(得分:1)

我知道你的问题被标记为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以获取标签。您也可以获得尺寸,并做出有根据的猜测它是一个USB棒(并且足够大) - 可移动可能意味着软盘或USB,according to the docs

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

答案 1 :(得分:1)

您需要使用RegisterDeviceNotification功能。 Here是关于如何做到这一点的一些指示。还有一个sample code

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

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

答案 2 :(得分:1)

我花了一点时间环顾四周,发现了一个名为SetupDiEnumDeviceInfo的函数,该函数提供了一个解决方案,可以知道硬盘驱动器是否可移动但是有了这些信息,我仍然无法(还)将我找到的内容映射回来驱动信!

这是我到目前为止(以下代码创建一个dll):

#include "stdafx.h"
#include <setupapi.h>
#include <devguid.h>
#include <cfgmgr32.h>
extern "C" __declspec(dllexport) int usb_hard_drives() {
  HDEVINFO hdevinfo = SetupDiGetClassDevs(&GUID_DEVCLASS_DISKDRIVE, NULL, NULL, DIGCF_PRESENT);
  if (hdevinfo == INVALID_HANDLE_VALUE) return -1;
  DWORD MemberIndex = 0;
  SP_DEVINFO_DATA sp_devinfo_data;
  ZeroMemory(&sp_devinfo_data, sizeof(sp_devinfo_data));
  sp_devinfo_data.cbSize = sizeof(sp_devinfo_data);
  int c = 0;
  while (SetupDiEnumDeviceInfo(hdevinfo, MemberIndex, &sp_devinfo_data)) {
    DWORD PropertyRegDataType;
    DWORD RequiredSize;
    DWORD PropertyBuffer;
    if (SetupDiGetDeviceRegistryProperty(hdevinfo, &sp_devinfo_data, SPDRP_CAPABILITIES, &PropertyRegDataType, (PBYTE)&PropertyBuffer, sizeof(PropertyBuffer), &RequiredSize)) {
      if (PropertyBuffer && CM_DEVCAP_REMOVABLE == CM_DEVCAP_REMOVABLE) {
        // do something here to identify the drive letter.
        c++;
      }
    }       
    MemberIndex++;
  }
  SetupDiDestroyDeviceInfoList(hdevinfo);
  return c;
}

答案 3 :(得分:0)

可以毫不费力地收集一些信息:

  • 使用GetDriveType查找第一个可移动驱动器,测试是否存在可写介质(这将主要排除CD驱动器)。您还可以查看通过win32查询驱动器信息时可用的其他字符串。
  • 使用libusb查看第一个存储类USB设备的位置(可能是闪存或硬盘)
  • C# article指向您可能可以使用的win32磁盘驱动器类。

找到答案后在这里发布答案!

- 亚当

答案 4 :(得分:0)

我在Win32 API中发现了一个用于测试驱动器类型的强大功能。

if( 2 == ::getDriveType( <driveletter> )){
  // its removable 
}

返回函数值:

DRIVE_UNKNOWN 0:无法确定驱动器类型。

DRIVE_NO_ROOT_DIR 1:根路径无效;例如,指定路径上没有安装卷。

DRIVE_REMOVABLE 2:驱动器有可移动介质;例如,软盘驱动器,拇指驱动器或闪存卡读卡器。

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

DRIVE_REMOTE 4:驱动器是远程(网络)驱动器。

DRIVE_CDROM 5:驱动器是CD-ROM驱动器。

DRIVE_RAMDISK 6:驱动器是RAM磁盘。

http://msdn.microsoft.com/en-us/library/windows/desktop/aa364939(v=vs.85).aspx