【问题标题】:How to enumerate disk volume names?如何枚举磁盘卷名?
【发布时间】:2015-05-26 13:57:33
【问题描述】:

如何枚举磁盘上所有逻辑卷的列表?我想要适合用CreateFile 打开的卷的名称。

你有什么尝试?

我使用了FindFirstVolume/FindNextVolume API 来枚举卷列表。它返回一个名称列表,例如:

  • \\?\Volume{0b777018-3313-11e2-8ccd-806e6f6e6963}\
  • \\?\Volume{0b777019-3313-11e2-8ccd-806e6f6e6963}\
  • \\?\Volume{758a2cf2-cf3a-11e4-8dce-c86000d0b92a}\
  • \\?\Volume{4f81d34b-34f4-11e2-9f6e-c86000d0b92a}\

但是这些卷名都不是有效的卷名。也就是说,这些名称都不能传递给CreateFile 来打开卷:

0x00000003 (The system cannot find the path specified)

问题可能是我如何将FindFirstVolume 返回的东西转换成卷名?

但真正的问题是我首先如何枚举卷?

为什么不直接使用\\.\C:

我不是在问如何硬编码卷名;我在问如何枚举卷名。

此外,并非每个卷都有驱动器号,例如:

  • \\?\Volume{0b777019-3313-11e2-8ccd-806e6f6e6963}\ ==> \\.\C:
  • \\?\Volume{758a2cf2-cf3a-11e4-8dce-c86000d0b92a}\ ==> \\.\D:
  • \\?\Volume{0b777018-3313-11e2-8ccd-806e6f6e6963}\ ==> 没有盘符的系统保留卷
  • \\?\Volume{4f81d34b-34f4-11e2-9f6e-c86000d0b92a}\ ==> 安装在文件夹中的 CD ROM

我发誓有一个 API 可以枚举卷。

GetLogicalDriveStrings

GetLogicalDriveStrings 函数的问题在于它只返回逻辑驱动器:

  • C:\
  • D:\

而不是。就我而言,它错过了两卷:

  • 系统保留
  • D:\CDROM

FindFirstVolume确实正确返回。

阅读奖励

【问题讨论】:

    标签: windows winapi


    【解决方案1】:

    您的问题的答案隐藏在Naming a Volume 中。使用卷 GUID 路径时,规则略有不同:

    所有将卷 GUID 路径作为输入参数的卷和装载的文件夹函数都需要尾部反斜杠。 [...] 但CreateFile 函数并非如此。 您可以通过调用 CreateFile 来打开一个卷,并从您指定的卷名中省略尾随反斜杠。 CreateFile 处理一个带有附加反斜杠的卷 GUID 路径作为卷的根目录。

    解决方案很简单:从卷 GUID 路径中去除尾部反斜杠,以使用 CreateFile 打开卷。

    也就是说,同时卷管理功能如:

    • 获取音量信息
    • GetVolumePathNamesForVolumeName

    FindFirstVolume/FindNextVolume返回的完整卷名,CreateFile要求删除返回的尾部反斜杠:

    • \\?\Volume{0b777018-3313-11e2-8ccd-806e6f6e6963}
    • \\?\Volume{0b777019-3313-11e2-8ccd-806e6f6e6963}
    • \\?\Volume{758a2cf2-cf3a-11e4-8dce-c86000d0b92a}
    • \\?\Volume{4f81d34b-34f4-11e2-9f6e-c86000d0b92a}

    【讨论】:

    • 如果请求FILE_FLAG_BACKUP_SEMANTICSCreateFile 实际上会成功打开根目录。否则ERROR_PATH_NOT_FOUND 并没有什么帮助,但来自ntdll!RtlGetLastNtStatus 的NT 状态代码显示真正的错误是STATUS_FILE_IS_A_DIRECTORY,即调用试图将目录作为常规文件打开。
    • 有趣的是,当lpFileName 以反斜杠结尾时,Windows 只会将 NT 的 STATUS_FILE_IS_A_DIRECTORY 转换为 ERROR_PATH_NOT_FOUND。否则,尝试打开没有尾随反斜杠的目录会导致 ERROR_ACCESS_DENIED
    • @eryksun:有趣的信息。现在一切都说得通了(除了信息量不足的错误代码)。 CreateFile 的文档确实指出 FILE_FLAG_BACKUP_SEMANTICS 标志是获取目录句柄所必需的,但它没有连接到 ERROR_PATH_NO_FOUND 错误代码,直到您将其拼写出来。
    • @IInspectable:虽然目录句柄需要FILE_FLAG_BACKUP_SEMANTICS,但不需要备份权限。对此似乎有些困惑,因为我看到一些开发人员在使用 FILE_FLAG_BACKUP_SEMANTICS 之前尝试启用备份权限。
    猜你喜欢
    • 2010-11-15
    • 1970-01-01
    • 2013-02-06
    • 2011-04-02
    • 1970-01-01
    • 2020-03-01
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多