Windows 上 USB 闪存驱动器和 USB 硬盘的区别

发布于 2024-09-12 11:51:10 字数 169 浏览 8 评论 0原文

我试图使用 Win32 API 来区分 Windows 上的 USB 闪存驱动器和 USB 硬盘驱动器。

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

提前致谢。

I'm trying to differentiate between a USB flash drive and a USB hard drive on Windows using the Win32 API.

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).

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

樱&纷飞 2024-09-19 11:51:10

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

EnumUsbDrivesLetters - 该帖子是俄语的但它包含C++源代码,因此很容易理解。

干杯,
安德烈

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.

EnumUsbDrivesLetters - the post is in Russian but it contains C++ source code, so the matter could be understood easily.

Cheers,
Andriy

放手` 2024-09-19 11:51:10
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//  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;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//  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;
}
随风而去 2024-09-19 11:51:10

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

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 ;-)

━╋う一瞬間旳綻放 2024-09-19 11:51:10

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

Actually windows doesn't, GetDriveType returns 3 (DRIVE_FIXED) for both my usb hard-drives.

海夕 2024-09-19 11:51:10

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

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

泛泛之交 2024-09-19 11:51:10

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

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

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

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 have seen a USB flash stick return DRIVE_FIXED, I have never seen 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.

I'd say relying on those two values is probably the closest that you're going to get.

玉环 2024-09-19 11:51:10

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

http://en.wikipedia.org/wiki/SCSI_Pass_Through_Interface will 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)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文