如何将Linux设备路径与Windows驱动器名称进行匹配?


3

我在写一个应用程序,在某个阶段在Linux环境下执行低级别的磁盘操作。该应用程序实际上由两部分组成,一部分在Windows上运行并与用户交互,另一部分是从LiveCD运行的Linux部分。用户可以选择Windows驱动器盘符,然后Linux部件执行相应分区的操作。问题是在Windows驱动器盘符(如C :)和Linux设备名称(如/ dev/sda1)之间找到匹配项。这是我认为它是丑陋的我目前的解决方案:

  • 存储分区信息(即驱动器盘符,块的数量,驱动器序列号等),在Windows中的一些预先定义的地方(即的根系统分区)。

  • 从/ proc/partitions中读取分区列表。只获取那些主要用于SCSI或IDE硬盘驱动器的分区以及将其标识为实际分区而不是整个磁盘的次要分区。

  • 尝试使用ntfs或vfat文件系统挂载它们中的每一个。检查装入的分区是否包含Windows应用程序存储的信息。

  • 在找到Windows应用程序写入的所需信息后,会进行实际匹配。对于在/ proc/partitions中找到的每个分区,获取驱动器序列号(通过HDIO_GET_IDENTITY syscall),块数(从/ proc /分区)和驱动器偏移量(/ sys/blocks/drive_path/partition_name/start),将其与Windows信息,如果匹配 - 存储Windows驱动器盘符以及Linux设备名称。

有几个问题在这个方案:

  • 这是丑陋的。在Windows中写入数据然后在Linux中读取数据使得测试成为一场噩梦。

  • linux设备主号码仅与IDE或SCSI设备进行比较。这可能会失败,即在USB或FireWire磁盘上。可以添加这些类型的磁盘,但将应用程序限制为只有可能的设备的已知子集似乎是一个相当糟糕的主意。

  • 看起来像HDIO_GET_IDENTITY只适用于IDE和SATA驱动器。

  • /sys/block hack可能无法在IDE或SATA驱动器上运行。

有关如何改进此模式的任何想法?也许有另一种方式来确定Windows名称,而无需在Windows应用程序中编写所有数据?

P.S.该应用的语言是C++。我无法改变这一点。

1

分区具有与它们关联的UUID。我不知道如何在Windows中找到这些,但在linux下你可以找到与每个分区的UUID:

须藤vol_id -u设备(例如/ dev/sda1的)

如果有在Windows中是一个equivilent函数,您可以简单地存储他们选择的任何分区的UUID,然后遍历Linux中所有已知的分区并匹配UUID。

编辑:这可能是一个linux的唯一的东西,它可能是一个volid util,它可以从某些东西中产生这些东西(而不是读取驱动器的元数据)。话虽如此,没有什么能阻止你获得volid的来源并检查它的功能。


2

分区具有与之相关的UUID

我这方面的知识很浅,但我认为这是仅适用于具有GPT(GUID分区表)分区格式化的磁盘真实的,而不是OLD-世界上99%的人仍然坚持使用MBR格式?


1

我这方面的知识很浅, 但我认为这是仅适用于具有GPT(GUID 分区表)分区,格式化,而 比旧式MBR格式的这 99% 盘真世界还在坚持?

不是听起来像一个Linux用户陈词滥调,但它适用于我..我用它与NTFS分区,并没有任何问题。正如我在编辑中所说的,vol_id可能会自己生成它们。如果是这种情况,就不会依赖任何特定的分区格式,这种分区格式会很大。


0

您需要以某种方式标记驱动器(例如写入文件等),或者找到仅与该特定驱动器关联的标识符。

这是非常困难的,几乎不可能找出什么字母Windows将分配给特定的驱动器分区,而实际上没有运行Windows。这是因为Windows始终将其从C:运行的驱动器关联起来。如果您安装了多个操作系统,则可能是任何驱动器。 Windows还允许您选择首先尝试使用哪个驱动器号,针对特定的分区,从而导致更多问题。

在Linux内部完成GUI的工作比试用混合的Window/Linux解决方案要容易得多。我不是说不要这样试试,我说的是这种方法有很多可能的缺陷。我确定我甚至都不知道他们全部。

另一种选择是查看你是否可以在Windows内部实际执行Linux部分。如果你是一个非常优秀的Windows程序员,你实际上可以访问原始文件系统。这种方法可能存在许多缺陷,因为在所有这些都在运行时,Windows将会运行。如果可以的话,我会看看你是否可以在Linux内部做所有事情。从长远来看,这只是一个更简单的过程。


1

分区具有与它们关联的UUID。我不知道如何在Windows中找到这些,但在linux下你可以找到与每个分区的UUID:

须藤vol_id -u设备(例如/ dev/sda1的)

如果有在Windows中是一个equivilent函数,您可以简单地存储他们选择的任何分区的UUID,然后遍历Linux中所有已知的分区并匹配UUID。

这是一个很好的观点,谢谢!我查看了vol_id(udev tarball的一部分)的来源,看起来对于FAT(32)和NTFS,它使用从分区上的预定义位置读取的卷序列号来生成UUUD。由于我不指望fat32和ntfs以外的任何其他东西,我认为将这些信息用作分区标识符。


0

在Windows中,您可以阅读与Linux下的UUID匹配的“NTFS卷序列号”。因为XP

  • 命令行:

    可能性从的Windows得到 “NTFS卷的序列” fsutil.exe FSINFO ntfsinfo C:

  • 下C++

    HANDLE fileHandle = CreateFile(L"\\\\.\\C:", // or use syntax "\\?\Volume{GUID}" 
               GENERIC_READ, 
               FILE_SHARE_READ|FILE_SHARE_WRITE, 
               NULL, 
               OPEN_EXISTING, 
               NULL, 
               NULL); 
    DWORD i; 
    NTFS_VOLUME_DATA_BUFFER ntfsInfo; 
    DeviceIoControl(fileHandle, 
           FSCTL_GET_NTFS_VOLUME_DATA, 
           NULL, 
           0, 
           &ntfsInfo, 
           sizeof(ntfsInfo), 
           &i, 
           NULL)); 
    cout << "UUID is " << std::hex << ntfsInfo.VolumeSerialNumber.HighPart << std::hex << ntfsInfo.VolumeSerialNumber.LowPart << endl; 
    

可能性,以获得下的Linux的UUID:

  • ls -l命令的/ dev /磁盘/副UUID
  • ls -l命令的/ dev /磁盘/按标签
  • BLKID/dev/sda1