如何将linux设备路径与windows驱动器名称相匹配?

时间:2008-08-20 22:06:11

标签: c++ linux drives

我正在编写一个应用程序,在某些阶段在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系统调用),块数(来自/ proc / partitions)和驱动器偏移量(/ 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 app中写入所有数据?

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

6 个答案:

答案 0 :(得分:2)

  

分区具有与之关联的UUID

我对此的了解很浅,但我认为仅适用于使用GPT(Guid Partition Table)分区格式化的磁盘,而不是99%的世界仍然坚持的旧式MBR格式? / p>

答案 1 :(得分:1)

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

  

sudo vol_id -u device(例如/ dev / sda1)

如果Windows中存在等效功能,您可以简单地存储他们选择的任何分区的UUID,然后遍历linux中的所有已知分区并匹配UUID。

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

答案 2 :(得分:1)

  

我对此的了解很浅,   但我认为这只是真的   用GPT格式化的磁盘(Guid   分区表)分区,而不是   比旧式MBR格式哪个   世界上99%的人仍然坚持使用?

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

答案 3 :(得分:1)

  

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

     
    

sudo vol_id -u device(例如/ dev / sda1)

  
     

如果Windows中存在等效功能,您可以简单地存储他们选择的任何分区的UUID,然后遍历linux中的所有已知分区并匹配UUID。

这是一个好点,谢谢!我已经查看了vol_id(udev tarball的一部分)的来源,似乎对于FAT(32)和NTFS,它使用从分区上的预定义位置读取的卷序列号生成UUUD。由于我没有想到除了fat32和ntfs以外的任何其他内容,我认为将此信息用作分区标识符。

答案 4 :(得分:0)

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

在没有实际运行Windows的情况下,很难找出Windows将分配给特定驱动器分区的字母。这是因为Windows始终将运行它的驱动器与C:相关联。如果您安装了多个操作系统,则可以是任何驱动器。 Windows还允许您为特定分区选择首先尝试的驱动器号,从而导致进一步的问题。

在Linux中运行GUI内容要比尝试这种混合的Window / Linux解决方案容易得多。我不是说不要这样试试,我所说的是这种方法存在很多可能的陷阱。我相信我甚至都不知道所有这些。

另一种选择是看看你是否可以在Windows内部实际执行Linux部分。如果您是一名非常优秀的Windows程序员,您实际上可以访问原始文件系统。这种方法可能存在许多陷阱,因为Windows将在所有这些运行时运行。

所以要重新迭代我会看看你是否可以在Linux内做任何事情,如果可以的话。从长远来看,它只是简单得多。

答案 5 :(得分:0)

在Windows中,您可以阅读“NTFS卷序列号”,其接缝与Linux下的UUID相匹配。

Windows

获取“NTFS卷序列”的可能性
    自XP以来
  • 命令行: 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 / disk / by-uuid
  • ls -l / dev / disk / by-label
  • blkid / dev / sda1