我正在将文件系统移植到Windows,并且正在为mounter可执行文件编写更像Windows的界面。此过程的一部分是让用户找到分区并选择驱动器号。最终,分区的选择必须导致我可以使用CreateFile()
,open()
,fopen()
或类似内容打开。
Windows似乎围绕卷的概念展开,这些概念似乎与磁盘不太相似,而且仅适用于已安装的文件系统。
有前途的潜在客户包括:
然而,这些都以卷或其偏移结束,而不是我所追求的/dev/sda1
特定于分区的句柄。
This question是一个非常类似的事情,我认为是赏金,直到我发现OP是在物理磁盘名称之后,而不是分区。 This answer包含一个强制分区名称的方法,我想避免这种情况(或者查看包含可能路径边界的文档)。
我想:
虽然主要目标仍然是打开原始分区,但似乎解决方案可能涉及首先获取每个磁盘驱动器的句柄,然后依次使用它来获取每个分区。如何枚举所有磁盘驱动器(即使那些已经没有安装卷的磁盘驱动器)也是必需的。
答案 0 :(得分:4)
如您所述,您可以使用IOCTL_DISK_GET_DRIVE_LAYOUT_EX获取分区列表。
对相关概念here有一个很好的概述。我想知道你缺少的链接是否
检测磁盘类型
没有具体的功能 以编程方式检测其类型 磁盘特定的文件或目录 位于。有间接的 方法
首先,致电
GetVolumePathName
。然后, 致电CreateFile
打开音量 使用路径。接下来,使用IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
用卷句柄来获取 磁盘编号并使用磁盘编号 构造磁盘路径,例如 “\?\ PhysicalDriveX”。最后,使用IOCTL_DISK_GET_DRIVE_LAYOUT_EX
来 获取分区列表,然后检查 中的每个条目的PartitionType 分区列表。
disk management control codes的完整列表可能包含更多有用的内容。说实话,我不确定Unix分区名称是如何映射到Windows的,也许它不是直接的。
答案 1 :(得分:3)
如果您可以想象从用户空间的安全港和Windows API(win32)转移到使用NTTDK编码设备驱动程序,您可以尝试使用IoReadPartitionTableEx或其他low level disk功能。< / p>
答案 2 :(得分:1)
说实话,可靠地获取所有已安装/未安装的磁盘分区的最佳方法是自己解析mbr / gpt。
首先要清除一些内容:磁盘包含分区和分区组合以创建卷。因此,您可以拥有一个卷,该卷由两个不同磁盘的两个分区组成。
IOCTL_DISK_GET_DRIVE_LAYOUT_EX
是您手动完成的最接近的解决方案。这个问题是它依赖于可以错误地解析MBR的窗口,因为上帝知道是什么原因。我目前的工作理论是,如果Windows是通过EFI安装的,但是通过MBR启动,你会看到这种问题。 Windows设法逃脱了这一点,因为大多数分区管理器将重要的分区信息与GPT一起复制到MBR。但这意味着您不会获得分区UUID(仅存储在GPT中)等重要信息。
所有其他解决方案都涉及获取与分区信息完全不同的卷信息。
备注:卷ID 通常的格式为\\.\Volume{PARTITION_UUID}
。这种情况不成立的情况:如果驱动器使用MBR进行分区而不是GPT(MBR没有分区UUID,因此Windows会启动一个),如果你有一个raid驱动器,或者你有一个包含来自分区的卷多个磁盘(有点像raid一样)。这些只是我想到的情况,不要诱使我。
答案 3 :(得分:0)
我认为你在早期阶段有点误会。例如,您似乎认为“挂载”在Windows中可以像在Unix中一样工作。它有点不同。
让我们从最熟悉的一端开始吧。 C:\
之类的路径使用驱动器号。这些现在基本上只是一组符号链接(在Windows上,它们更正式地称为“联结”)。所有用户都有一个基础集,每个用户都可以添加自己的基础集。即使卷没有驱动器号,仍然会有{em>卷名,如\\?\Volume{4c1b02c1-d990-11dc-99ae-806e6f6e6963}\
。您可以在调用CreateFile()
等时使用此卷名。但我不确定fopen()
是否喜欢它们。
函数QueryDosDevice
将为您提供驱动器号或卷名的Windows设备名称。设备名称类似于“\ Device \ HarddiskVolume1”,但您无法将其传递给CreateFile
Microsoft example code枚举所有分区。
在Windows上,就像在Linux上一样,您可以打开分区本身,就好像它是一个文件一样。这在CreateFile
下有很好的记录。