我将一个文件系统移植到Windows,并为贴片机可执行文件写一个更类似于Windows的界面。 这个过程的一部分是让用户find一个分区并select一个驱动器号。 最终分区的select必须导致我可以使用CreateFile()
, open()
, fopen()
或类似的东西打开。
Windows似乎围绕卷的概念,似乎不像磁盘相似,只有在已经挂载的文件系统才会出现。
有前途的领导我已经包括:
IOCTL_DISK_GET_DRIVE_LAYOUT_EX
但是,这些都以卷或偏移量结束,而不是我后面的/dev/sda1
分区特定风格的句柄。
这个问题是在一个非常类似的事情之后,我认为是赏金,直到我观察到OP是物理磁盘名称之后,而不是分区。 这个答案包含了强制分区名称的方法,我想避免这种情况(或者查看包含可能path边界的文档)。
我想要:
虽然主要目标仍然是打开原始分区,但是似乎解决scheme可能涉及首先获取每个磁盘驱动器的句柄,然后依次使用它来获取每个分区。 如何枚举所有的磁盘驱动器(甚至那些没有安装卷已经在他们身上)是必需的。
如您所述,您可以使用IOCTL_DISK_GET_DRIVE_LAYOUT_EX来获取分区列表。
这里有一个很好的相关概念的概述。 我想知道你是否缺少链接
检测磁盘的类型
没有特定的功能来以编程方式检测特定文件或目录所在的磁盘的类型。 有一个间接的方法。
首先,调用
GetVolumePathName
。 然后,调用CreateFile
使用路径打开卷。 接下来,使用带卷处理的IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS
来获取磁盘编号,并使用磁盘编号构建磁盘路径,如“\?\ PhysicalDriveX”。 最后,使用IOCTL_DISK_GET_DRIVE_LAYOUT_EX
获取分区列表,并检查分区列表中每个条目的PartitionType。
磁盘管理控制代码的完整列表可能有更多的将是有用的。 说实话,我不知道如何将Unix分区名称映射到Windows上,也许它不直接。
如果您可以想象从用户空间和Windows API (win32)的安全避风港转到使用NTTDK编码设备驱动程序,您可以尝试使用IoReadPartitionTableEx或其他一些低级磁盘功能。
说白了,可靠地获取所有挂载/卸载的磁盘分区的最好方法是自己分析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一样的东西)。 那些只是我想到的情况,不要把我抱到他们身上。
我认为你在早期阶段有些误会。 例如,你似乎认为“安装”在Windows中工作,就像在Unix中工作一样。 这有点不同。
让我们从最熟悉的结局开始。 路径像C:\
使用驱动器号。 这些基本上只是一套现在的符号链接(在Windows上,它们更正式地称为“路口”)。 所有用户都有一个基本集,每个用户都可以添加自己的基本集。 即使卷没有驱动器盘符,仍然会有一个卷名称,如\\?\Volume{4c1b02c1-d990-11dc-99ae-806e6f6e6963}\
。 你可以在调用CreateFile()
等等时使用这个卷名。我不确定fopen()
喜欢它们。
QueryDosDevice
函数将为您提供驱动器号或卷名的Windows设备名称。 设备名称看起来像“\ Device \ HarddiskVolume1”,但不能将其传递给CreateFile
微软有枚举所有分区的示例代码 。
在Windows上,就像在Linux上一样,您可以像打开文件一样打开分区。 这在CreateFile
下有很好的记录。