10

目标

我正在将一个文件系统移植到 Windows,并且正在为 mounter 可执行文件编写一个更像 Windows 的界面。这个过程的一部分是让用户找到一个分区并选择一个驱动器号。最终,分区的选择必须导致我可以使用 、 或类似打开CreateFile()open()东西fopen()

潜在客户

Windows 似乎围绕着卷的概念展开,这似乎与磁盘不太相似,并且只发生在已经挂载的文件系统上。

我拥有的有希望的潜在客户包括:

但是,这些都以卷或偏移量结尾,而不是/dev/sda1我所追求的特定于分区的样式句柄。

这个问题是在一个非常相似的事情之后,我认为是赏金,直到我观察到 OP 是在物理磁盘名称之后,而不是分区之后。这个答案包含一种暴力破解分区名称的方法,我想避免这种情况(或查看包含可能路径边界的文档)。

问题

我想要:

  • 更正 Windows 中未挂载分区的术语和文档。
  • 可靠地检索所有可用分区的有效且记录在案的方法。
  • 最接近 Linux 中可用的分区文件抽象,其中所有 IO 都绑定到打开的分区的磁盘的适当区域。

更新0

虽然主要目标仍然是打开原始分区,但似乎解决方案可能涉及首先获取每个磁盘驱动器的句柄,然后依次使用该句柄来获取每个分区。需要如何枚举所有磁盘驱动器(即使是那些尚未安装卷的磁盘驱动器)。

4

4 回答 4

6

如您所述,您可以使用IOCTL_DISK_GET_DRIVE_LAYOUT_EX来获取分区列表。

这里有一个很好的相关概念概述。我想知道您缺少的链接是否是

检测磁盘类型

没有特定的函数可以以编程方式检测特定文件或目录所在的磁盘类型。有一种间接的方法。

首先,调用GetVolumePathName. 然后,调用CreateFile以使用路径打开卷。接下来, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS 配合卷句柄获取磁盘号,使用磁盘号构造磁盘路径,如“\?\PhysicalDriveX”。最后,使用 IOCTL_DISK_GET_DRIVE_LAYOUT_EX获取分区列表,并检查分区列表中每个条目的PartitionType。

磁盘管理控制代码的完整列表可能有更多有用的信息。老实说,我不确定 Unix 分区名称是如何映射到 Windows 上的,也许它只是不直接映射。

于 2010-10-28T11:43:55.087 回答
4

如果您可以想象从安全的用户空间和Windows API (win32) 转移到使用 NTTDK 编写设备驱动程序,您可以尝试IoReadPartitionTableEx或其他一些低级磁盘功能。

于 2010-10-28T11:23:48.810 回答
2

坦率地说,可靠地获取所有已挂载/未挂载的磁盘分区的最佳方法是自己解析 mbr/gpt。

首先要弄清楚一些事情:磁盘包含分区,并且分区结合起来创建卷。因此,您可以拥有一个包含来自两个不同磁盘的两个分区的卷。

IOCTL_DISK_GET_DRIVE_LAYOUT_EX是您无需手动操作即可获得的最接近的解决方案。问题在于它依赖于可能错误地解析 MBR 的窗口,因为天知道是什么原因。我目前的工作理论是,如果 Windows 是通过 EFI 安装但通过 MBR 启动的,你会看到这类问题。Windows 设法解决了这个问题,因为大多数分区管理器将重要的分区信息复制到 GPT 旁边的 MBR。但这意味着您不会获得分区 UUID(仅存储在 GPT 中)之类的重要信息。

所有其他解决方案都涉及获取与分区信息完全不同的卷信息。

Side Note: a Volume id will usually be of the form \\.\Volume{PARTITION_UUID}. Cases where this would not hold: if the drive is partitioned with MBR and not GPT (MBR does not have a partition UUID, therefore windows makes one up), if you have a raid drive, or if you have a volume consisting of partitions from multiple disks (kinda the same thing as raid). Those are just the cases that come to my mind, dont hold me to them.

于 2013-05-25T20:55:59.263 回答
1

我认为你在早期阶段有点错误。例如,您似乎认为“挂载”在 Windows 中的工作方式与在 Unix 中的工作方式相同。这有点不同。

让我们从最熟悉的一端开始。C:\使用驱动器号之类的路径。如今,这些本质上只是一组符号链接(在 Windows 上,它们更正式地称为“联结”)。所有用户都有一个基本集,每个用户都可以添加自己的。即使没有卷的驱动器号,仍然会有一个卷名,如\\?\Volume{4c1b02c1-d990-11dc-99ae-806e6f6e6963}\. 您可以在调用CreateFile()等时使用此卷名。不过,我不确定是否fopen()喜欢它们。

该函数QueryDosDevice将为您获取驱动器号或卷名的 Windows 设备名称。设备名称看起来像“\Device\HarddiskVolume1”,但您不能将其传递给CreateFile

Microsoft 有枚举所有分区的示例代码。

在 Windows 上,就像在 Linux 上一样,您可以像打开文件一样打开分区本身。这在CreateFile.

于 2010-10-28T11:57:42.583 回答