简体   繁体   English

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

[英]How to match linux device path to windows drive name?

I'm writing an application that on some stage performs low-level disk operations in Linux environment. 我正在编写一个应用程序,在某些阶段在Linux环境中执行低级磁盘操作。 The app actually consists of 2 parts, one runs on Windows and interacts with a user and another is a linux part that runs from a LiveCD. 该应用程序实际上由两部分组成,一部分在Windows上运行并与用户交互,另一部分是从LiveCD运行的Linux部分。 User makes a choice of Windows drive letters and then a linux part performs actions with corresponding partitions. 用户可以选择Windows驱动器号,然后Linux部件执行相应分区的操作。 The problem is finding a match between a Windows drive letter (like C:) and a linux device name (like /dev/sda1). 问题是在Windows驱动器号(如C :)和Linux设备名称(如/ dev / sda1)之间找到匹配项。 This is my current solution that I rate as ugly: 这是我目前的解决方案,我认为丑陋:

  • store partitions information (ie drive letter, number of blocks, drive serial number etc.) in Windows in some pre-defined place (ie the root of the system partition). 在Windows中的某个预定义位置(即系统分区的根目录)中存储分区信息(即驱动器号,块数,驱动器序列号等)。

  • read a list of partitions from /proc/partitions. 从/ proc / partitions读取分区列表。 Get only those partitions that has major number for SCSI or IDE hard drives and minor number that identifies them as real partitions and not the whole disks. 仅获取具有SCSI或IDE硬盘驱动器主编号的分区以及将其标识为真实分区而非整个磁盘的次编号。

  • Try to mount each of them with either ntfs or vfat file systems. 尝试使用ntfs或vfat文件系统安装它们。 Check whether the mounted partition contains the information stored by Windows app. 检查已安装的分区是否包含Windows应用程序存储的信息。

  • Upon finding the required information written by the Windows app make the actual match. 找到Windows应用程序编写的所需信息后,进行实际匹配。 For each partition found in /proc/partitions acquire drive serial number (via HDIO_GET_IDENTITY syscall), number of blocks (from /proc/partitions) and drive offset (/sys/blocks/drive_path/partition_name/start), compare this to the Windows information and if this matches - store a Windows drive letter along with a linux device name. 对于在/ proc / partitions中找到的每个分区获取驱动器序列号(通过HDIO_GET_IDENTITY系统调用),块数(来自/ proc / partitions)和驱动器偏移量(/ sys / blocks / drive_path / partition_name / start),将其与Windows进行比较信息,如果匹配 - 存储Windows驱动器号和Linux设备名称。

There are a couple of problems in this scheme: 这个方案有几个问题:

  • This is ugly. 这很难看。 Writing data in Windows and then reading it in Linux makes testing a nightmare. 在Windows中编写数据然后在Linux中读取数据会使测试成为一场噩梦。

  • linux device major number is compared only with IDE or SCSI devices. linux设备主要编号仅与IDE或SCSI设备进行比较。 This would probably fail, ie on USB or FireWire disks. 这可能会失败,即在USB或FireWire磁盘上。 It's possible to add these types of disks, but limiting the app to only known subset of possible devices seems to be rather bad idea. 可以添加这些类型的磁盘,但将应用限制为仅可能设备的已知子集似乎是相当糟糕的主意。

  • looks like HDIO_GET_IDENTITY works only on IDE and SATA drives. 看起来HDIO_GET_IDENTITY仅适用于IDE和SATA驱动器。

  • /sys/block hack may not work on other than IDE or SATA drives. / sys / block hack可能不适用于IDE或SATA驱动器。

Any ideas on how to improve this schema? 有关如何改进此架构的任何想法? Perhaps there is another way to determine windows names without writing all the data in windows app? 也许有另一种方法来确定Windows名称而无需在Windows应用程序中写入所有数据?

PS The language of the app is C++. PS该应用程序的语言是C ++。 I can't change this. 我无法改变这一点。

Partitions have UUIDs associated with them 分区具有与之关联的UUID

My knowledge of this is very shallow, but I thought that was only true for disks formatted with GPT (Guid Partition Table) partitions, rather than the old-style MBR format which 99% of the world is still stuck with? 我对此的了解非常浅薄,但我认为仅适用于使用GPT(Guid分区表)分区格式化的磁盘,而不是99%的世界仍然坚持使用的旧式MBR格式?

Partitions have UUIDs associated with them. 分区具有与之关联的UUID。 I don't know how to find these in Windows but in linux you can find the UUID for each partition with: 我不知道如何在Windows中找到它们但在linux中你可以找到每个分区的UUID:

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

If there is an equivilent function in Windows you could simply store the UUIDs for whatever partition they pick then iterate through all known partitions in linux and match the UUIDs. 如果Windows中存在等效功能,您只需将UUID存储到他们选择的任何分区,然后遍历linux中的所有已知分区并匹配UUID。

Edit: This may be a linux-only thing, and it may speficially be the volid util that generates these from something (instead of reading off meta-data for the drive). 编辑:这可能只是一个linux的东西,它可能特别是volid util从某些东西生成这些(而不是读取驱动器的元数据)。 Having said that, there is nothing stopping you getting the source for volid and checking out what it does. 话虽如此,没有什么可以阻止你获得volid的来源并检查它的作用。

My knowledge of this is very shallow, but I thought that was only true for disks formatted with GPT (Guid Partition Table) partitions, rather than the old-style MBR format which 99% of the world is still stuck with? 我对此的了解非常浅薄,但我认为仅适用于使用GPT(Guid分区表)分区格式化的磁盘,而不是99%的世界仍然坚持使用的旧式MBR格式?

Not to sounds like a linux user cliche but it Works For Me.. I use it with NTFS partitions and have had no problems. 听起来不像是linux用户的陈词滥调,但它适用于我..我使用它与NTFS分区并没有任何问题。 As I said in my edit, vol_id may be generating them itself. 正如我在编辑中所说,vol_id可能会自己生成它们。 If that were the case there would be no reliance on any particular partition format, which would be swell. 如果是这种情况,则不会依赖任何特定的分区格式,这种格式会膨胀。

Partitions have UUIDs associated with them. 分区具有与之关联的UUID。 I don't know how to find these in Windows but in linux you can find the UUID for each partition with: 我不知道如何在Windows中找到它们但在linux中你可以找到每个分区的UUID:

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

If there is an equivilent function in Windows you could simply store the UUIDs for whatever partition they pick then iterate through all known partitions in linux and match the UUIDs. 如果Windows中存在等效功能,您只需将UUID存储到他们选择的任何分区,然后遍历linux中的所有已知分区并匹配UUID。

That's a good point, thank you! 这是一个好点,谢谢! I've looked to the sources of vol_id (a part of the udev tarball) and it seems that for FAT(32) and NTFS it generates UUUD using the volume serial number that is read from the predefined location on the partition. 我已经查看了vol_id(udev tarball的一部分)的来源,似乎对于FAT(32)和NTFS,它使用从分区上的预定义位置读取的卷序列号生成UUUD。 Since I don't expect anything other then fat32 and ntfs I consider to use this information as a partition identifier. 由于我不期望任何其他的fat32和ntfs,我认为将此信息用作分区标识符。

You need to either mark the drive in some way (eg write a file etc.), or find some identifier that is only associated with that particular drive. 您需要以某种方式标记驱动器(例如,写入文件等),或者找到仅与该特定驱动器关联的标识符。

It is very hard, almost impossible to figure out what letter Windows would assign to a particular drive partition, without actually running Windows. 在没有实际运行Windows的情况下,很难找出Windows将分配给特定驱动器分区的字母。 This is because Windows always associates the drive that it is run from with C:. 这是因为Windows始终将运行它的驱动器与C:相关联。 Which could be any drive, if you have more than one operating system installed. 如果您安装了多个操作系统,则可以是任何驱动器。 Windows also allows you to choose what drive letter it will try first, for a specific partition, causing further problems. Windows还允许您为特定分区选择首先尝试的驱动器号,从而导致进一步的问题。

It would be a whole lot easier to do the GUI stuff inside Linux, than to try this mixed Window/Linux solution. 在Linux中运行GUI内容要比尝试这种混合的Window / Linux解决方案容易得多。 I'm not say don't try it this way, what I am saying is there are very many possible pitfalls with this approach. 我不是说不要这样试试,我所说的是这种方法存在很多可能的陷阱。 I'm sure I don't even know about all of them. 我相信我甚至都不知道所有这些。

Another option would be to see if you could actually do the Linux part, inside of Windows. 另一个选择是看看你是否可以在Windows中实际执行Linux部分。 If you are a very good Windows programmer, you can actually get access to the raw file-system. 如果您是一名非常优秀的Windows程序员,您实际上可以访问原始文件系统。 There are probably just as many pitfalls with this approach, because Windows will be running while all of this is in operation. 这种方法可能存在许多陷阱,因为Windows将在所有这些运行时运行。

So to re-iterate I would see if you could do everything from within Linux, if you can. 所以要重新迭代,我会看看你是否可以在Linux内做任何事情,如果可以的话。 It's just a whole lot simpler in the long run. 从长远来看,它只是简单得多。

In Windows you can read the "NTFS Volume Serial Number" which seams to match the UUID under Linux. 在Windows中,您可以读取“NTFS卷序列号”,其接缝与Linux下的UUID相匹配。

Possibilities to get the "NTFS Volume Serial" from Windows : Windows获得“NTFS卷序列”的可能性:

  • commandline since XP: fsutil.exe fsinfo ntfsinfo C: XP以来的命令行: fsutil.exe fsinfo ntfsinfo C:

  • under 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; 

Possibilities to get the UUID under Linux : Linux下获取UUID的可能性:

  • ls -l /dev/disk/by-uuid ls -l / dev / disk / by-uuid
  • ls -l /dev/disk/by-label ls -l / dev / disk / by-label
  • blkid /dev/sda1 blkid / dev / sda1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM