在 Windows 上区分 USB 闪存驱动器和 USB 硬盘驱动器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3390865/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Differentiating between USB flash drive and USB hard drive on Windows
提问by user408962
I'm trying to differentiate between a USB flash drive and a USB hard drive on Windows using the Win32 API.
我正在尝试使用 Win32 API 在 Windows 上区分 USB 闪存驱动器和 USB 硬盘驱动器。
The GetDriveType()function will return DRIVE_REMOVABLE if the drive is removable, and USB flash drives are of course removable. But I'm thinking that Windows probably considers USB hard drives removable as well (unfortunately I don't have access to a USB hard drive to test it out).
该GetDriveType()函数将返回DRIVE_REMOVABLE如果驱动器是可移动的,和USB闪存驱动器当然可移动的。但我认为 Windows 可能也认为 USB 硬盘驱动器是可移动的(不幸的是,我无法访问 USB 硬盘驱动器来测试它)。
Thanks in advance.
提前致谢。
回答by Andriy
If you want to determine that a device is USB device, you can open its handle and send IOCTL queries using DeviceIoControl() to get bus type a device is connected to.
如果你想确定一个设备是 USB 设备,你可以打开它的句柄并使用 DeviceIoControl() 发送 IOCTL 查询来获取设备连接到的总线类型。
EnumUsbDrivesLetters- the post is in Russian but it contains C++ source code, so the matter could be understood easily.
EnumUsbDrivesLetters-这篇文章是俄文的,但它包含 C++ 源代码,所以这件事很容易理解。
Cheers, Andriy
干杯,安德烈
回答by Marty
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Method OpenVolume
// Purpose: Open volume for removal. Change to ::CreateFile(volumeName, 0, 0, 0, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0);
// if you just want to inquire if it's removable.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
HANDLE OpenVolume(const char& driveLetter)
{
char volumeName[8] = "";
char* volumeFormat = "\\.\%c:";
sprintf(volumeName, volumeFormat, driveLetter);
HANDLE volume = ::CreateFile(volumeName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (volume == INVALID_HANDLE_VALUE) return INVALID_HANDLE_VALUE;
DWORD bytesReturned = 0;
STORAGE_HOTPLUG_INFO Info = {0};
if (::DeviceIoControl(volume, IOCTL_STORAGE_GET_HOTPLUG_INFO, 0, 0, &Info, sizeof(Info), &bytesReturned, NULL))
{
if (!(Info.MediaRemovable || Info.DeviceHotplug))
{
::CloseHandle(volume);
::SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
}
return volume;
}
回答by Anton Semenov
I thinks the key is drive properties, eg Cylinder count. You can use WMI interface to determine such information. Here is an example http://www.computerperformance.co.uk/vbscript/wmi_disks_physical.htm
我认为关键是驱动器属性,例如气缸数。您可以使用 WMI 接口来确定此类信息。这是一个例子http://www.computerperformance.co.uk/vbscript/wmi_disks_physical.htm
回答by monoceres
Actually windows doesn't, GetDriveType returns 3 (DRIVE_FIXED) for both my usb hard-drives.
实际上 windows 没有,GetDriveType 为我的两个 USB 硬盘驱动器返回 3 (DRIVE_FIXED)。
回答by camilohe
Windows returns DRIVE_FIXED for external USB hard drives and usually returns DRIVE_REMOVABLE for USB flash sticks. For this reason if you want to access multiple partitions on a flash memory you have to install a filter driver to tell windows it's not a DRIVE_REMOVABLE but a DRIVE_FIXED instead. Windows only "sees" the first partition on flash sticks causing a lot of trouble for ESXi boot usb stick users ;-)
Windows 为外部 USB 硬盘驱动器返回 DRIVE_FIXED,通常为 USB 闪存棒返回 DRIVE_REMOVABLE。出于这个原因,如果您想访问闪存上的多个分区,您必须安装一个过滤驱动程序来告诉 Windows 它不是 DRIVE_REMOVABLE 而是 DRIVE_FIXED。Windows 只能“看到”闪存盘上的第一个分区,这给 ESXi 引导 USB 闪存盘用户带来了很多麻烦;-)
回答by Ana Betts
http://en.wikipedia.org/wiki/SCSI_Pass_Through_Interfacewill let you send raw SCSI commands to the device - you want to send down either INQUIRY or MODE SENSE to find out what you're looking for. However, a far better alternative may be the VDS APIs, if it will provide you correct information (I'm not sure whether it will in this case)
http://en.wikipedia.org/wiki/SCSI_Pass_Through_Interface可让您向设备发送原始 SCSI 命令 - 您想发送 INQUIRY 或 MODE SENSE 以找出您要查找的内容。但是,一个更好的替代方案可能是 VDS API,如果它会为您提供正确的信息(我不确定在这种情况下是否会)
回答by Adam Robinson
The drive type is ultimately determined by the drivers; there's no fail-safe way to make the sort of determination that you're looking for.
驱动器类型最终由驱动程序决定;没有万无一失的方法可以做出您正在寻找的那种决定。
I can say, however, that while I haveseen a USB flash stick return DRIVE_FIXED
, I have neverseen a normal hard drive return DRIVE_REMOVEABLE
. That's not to say that it's completely impossible for that to happen, but I've never seen it.
不过,我可以说的是,虽然我已经看到了USB闪存盘的回报DRIVE_FIXED
,我从来没有见过一个正常的硬盘驱动器的回报DRIVE_REMOVEABLE
。这并不是说这种情况完全不可能发生,但我从未见过。
I'd say relying on those two values is probably the closest that you're going to get.
我想说依靠这两个值可能是你最接近的。