【问题标题】:Differentiating between USB flash drive and USB hard drive on Windows在 Windows 上区分 USB 闪存驱动器和 USB 硬盘驱动器
【发布时间】:2011-03-24 09:10:19
【问题描述】:

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

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

提前致谢。

【问题讨论】:

  • 只是出于好奇,你为什么要这样做?你会根据驱动器的类型做一些不同的事情吗?正如其他人所说,DriveType 不是很一致(尽管它可能“足够好”)。

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


【解决方案1】:

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

EnumUsbDrivesLetters - 帖子是俄文的,但它包含 C++ 源代码,所以很容易理解。

干杯, 安德烈

【讨论】:

  • 请不要复制粘贴多个问题的答案,链接到您自己的博客。这将被视为垃圾邮件。
【解决方案2】:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//  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;
}

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 不开玩笑,谢谢。而且您的 USB 硬盘驱动器是普通的,没有特殊的驱动程序设置或类似的东西可能导致 Windows 将它们视为 DRIVE_FIXED 而不是 DRIVE_REMOVABLE?
    • 它们只是标准的西方数字驱动器,我的 Windows 安装非常新,因此驱动程序前端的默认设置没有任何变化。
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      我认为关键是驱动属性,例如气缸数。您可以使用 WMI 接口来确定此类信息。这是一个例子http://www.computerperformance.co.uk/vbscript/wmi_disks_physical.htm

      【讨论】:

        【解决方案6】:

        驱动类型最终由驱动决定;没有万无一失的方法来做出您正在寻找的那种决定。

        不过,我可以说,虽然我已经看到 USB 闪存棒返回 DRIVE_FIXED,但我从未看到普通硬盘驱动器返回 DRIVE_REMOVEABLE。这并不是说完全不可能发生这种情况,但我从未见过。

        我想说依赖这两个值可能是您将获得的最接近的值。

        【讨论】:

        • 有趣的是,您说您已经看到闪存棒返回 DRIVE_FIXED,因为我在阅读您的评论前几​​分钟发现了这一点:social.msdn.microsoft.com/forums/en-US/…
        • 它最终不是由驱动程序决定的,因为驱动程序是根据设备报告的内容来决定的,这并不总是一致的。
        【解决方案7】:

        http://en.wikipedia.org/wiki/SCSI_Pass_Through_Interface 将允许您向设备发送原始 SCSI 命令 - 您想要向下发送 INQUIRY 或 MODE SENSE 以找出您要查找的内容。但是,如果 VDS API 可以为您提供正确的信息(我不确定在这种情况下是否会提供),更好的替代方案可能是 VDS API。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-02
          • 2013-01-29
          • 2021-03-22
          • 2013-09-12
          • 1970-01-01
          • 2012-08-07
          • 1970-01-01
          • 2010-10-03
          相关资源
          最近更新 更多