在Windows上区分USB闪存驱动器和USB硬盘驱动器

时间:2010-08-02 18:56:41

标签: windows winapi usb usb-drive usb-flash-drive

我正在尝试使用Win32 API在Windows上区分USB闪存驱动器和USB硬盘驱动器。

如果驱动器是可移动的,GetDriveType()功能将返回DRIVE_REMOVABLE,USB闪存驱动器当然是可移动的。但我认为Windows可能也认为USB硬盘也是可移动的(遗憾的是我无法访问USB硬盘来测试它)。

提前致谢。

7 个答案:

答案 0 :(得分:1)

实际上Windows没有,GetDriveType为我的两个USB硬盘驱动器返回3(DRIVE_FIXED)。

答案 1 :(得分:1)

Windows为外部USB硬盘驱动器返回DRIVE_FIXED,并且通常会返回DRIVE_REMOVABLE以用于USB闪存盘。因此,如果要访问闪存上的多个分区,则必须安装过滤器驱动程序以告知Windows它不是DRIVE_REMOVABLE而是DRIVE_FIXED。 Windows只能“看到”闪存棒上的第一个分区,为ESXi引导usb棒用户带来很多麻烦; - )

答案 2 :(得分:1)

如果要确定设备是USB设备,可以打开其句柄并使用DeviceIoControl()发送IOCTL查询以获取设备所连接的总线类型。

EnumUsbDrivesLetters - 帖子是俄语的,但它包含C ++源代码,因此可以很容易地理解这个问题。

干杯, 安德烈

答案 3 :(得分:1)

我认为关键是驱动器属性,例如圆柱数。您可以使用WMI界面来确定此类信息。以下是http://www.computerperformance.co.uk/vbscript/wmi_disks_physical.htm

的示例

答案 4 :(得分:1)

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//  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;
}

答案 5 :(得分:0)

驱动器类型最终由驱动程序决定;没有任何失败安全的方法来做出你正在寻找的那种决心。

然而,我可以说,当我看到USB闪存棒返回DRIVE_FIXED时,我从未看到正常的硬盘返回{{ 1}}。这并不是说这完全不可能发生,但我从未见过它。

我说依赖这两个值可能是你最接近的。

答案 6 :(得分:0)

http://en.wikipedia.org/wiki/SCSI_Pass_Through_Interface将允许您将原始SCSI命令发送到设备 - 您想要向下发送询问或模式感知以找出您正在寻找的内容。但是,一个更好的选择可能是VDS API,如果它能为您提供正确的信息(我不确定它是否会在这种情况下)