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

在Windows上区分USB闪存驱动器和USB硬盘驱动器,windows,winapi,usb,usb-drive,usb-flash-drive,Windows,Winapi,Usb,Usb Drive,Usb Flash Drive,我正在尝试使用Win32 API区分Windows上的USB闪存驱动器和USB硬盘驱动器 如果驱动器可移动,该函数将返回驱动器可移动,USB闪存驱动器当然可移动。但我认为Windows可能也会认为USB硬盘是可移动的(不幸的是,我无法访问USB硬盘进行测试) 提前感谢。实际上windows没有,GetDriveType为我的两个usb硬盘驱动器返回3(驱动器已修复)。驱动器类型最终由驱动程序决定;没有一种自动防故障的方法可以做出你想要的那种决定 然而,我可以说,虽然我看到USB闪存棒返回驱动器\

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

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


提前感谢。

实际上windows没有,GetDriveType为我的两个usb硬盘驱动器返回3(驱动器已修复)。

驱动器类型最终由驱动程序决定;没有一种自动防故障的方法可以做出你想要的那种决定

然而,我可以说,虽然我看到USB闪存棒返回
驱动器\u固定
,但我从未看到正常的硬盘驱动器返回
驱动器\u可移动
。这并不是说这完全不可能发生,但我从未见过


我想说,依赖这两个值可能是最接近的结果。

Windows返回用于外部USB硬盘驱动器的固定驱动器,通常返回用于USB闪存棒的可移动驱动器。因此,如果你想访问闪存上的多个分区,你必须安装一个过滤器驱动程序,告诉windows它不是一个可移动的驱动器,而是一个固定的驱动器。Windows仅“看到”闪存棒上的第一个分区,这给ESXi引导usb棒用户带来了很多麻烦;-)

将允许您向设备发送原始SCSI命令-您要发送查询或模式检测以了解您要查找的内容。然而,一个更好的选择可能是VDS API,如果它能提供正确的信息(我不确定在这种情况下它是否会提供正确的信息)

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

—帖子是俄文,但包含C++源代码,所以可以很容易理解。 干杯,


安德烈

我认为关键在于驱动性能,例如气缸数。您可以使用WMI接口来确定此类信息。这是一个例子

别开玩笑了,谢谢。你的USB硬盘是普通的,没有特殊的驱动程序设置或类似的东西,这可能会导致Windows考虑它们的驱动程序而不是驱动程序。它们只是标准的西部数字驱动器,而我的Windows安装非常新鲜,所以驱动程序前面没有任何东西从默认设置改变。有趣的是,你看到了闪存棒。返回DRIVE_FIXED,因为我在阅读您的评论前几分钟发现了这一点:它不是由驱动程序最终决定的,因为驱动程序根据设备报告的内容来决定它,这并不总是一致的。只是出于好奇,你为什么要这样做?你会根据驱动器的类型做一些不同的事情吗?正如其他人所说,驱动类型不是很一致(尽管它可能“足够好”)。请不要在许多问题上复制粘贴答案,链接到您自己的blogspot。这将被视为垃圾邮件。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//  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;
}