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

发布于 2024-07-04 23:17:13 字数 1218 浏览 5 评论 0原文

我正在编写一个应用程序,该应用程序在某个阶段在 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 驱动器以外的其他驱动器上工作。

关于如何改进这个模式有什么想法吗? 也许还有另一种方法可以确定窗口名称,而无需在窗口应用程序中写入所有数据?

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

I'm writing an application that on some stage performs low-level disk operations in Linux environment. 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. User makes a choice of Windows drive letters and then a linux part performs actions with corresponding partitions. The problem is finding a match between a Windows drive letter (like C:) and a linux device name (like /dev/sda1). This is my current solution that I rate as ugly:

  • store partitions information (i.e. drive letter, number of blocks, drive serial number etc.) in Windows in some pre-defined place (i.e. the root of the system partition).

  • read a list of partitions from /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.

  • Try to mount each of them with either ntfs or vfat file systems. Check whether the mounted partition contains the information stored by Windows app.

  • Upon finding the required information written by the Windows app make the actual match. 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.

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.

  • linux device major number is compared only with IDE or SCSI devices. This would probably fail, i.e. on USB or FireWire disks. 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.

  • /sys/block hack may not work on other than IDE or SATA drives.

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?

P.S. The language of the app is C++. I can't change this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

追星践月 2024-07-11 23:17:13

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

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

在 Linux 中完成 GUI 工作比尝试这种混合 Window/Linux 解决方案要容易得多。 我并不是说不要尝试这种方式,我的意思是这种方法有很多可能的陷阱。 我确信我什至都不知道他们所有人。

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

因此,重申一下,如果可以的话,我想看看您是否可以在 Linux 中完成所有操作。 从长远来看,这要简单得多。

You need to either mark the drive in some way (e.g. 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. This is because Windows always associates the drive that it is run from with 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.

It would be a whole lot easier to do the GUI stuff inside Linux, than to try this mixed Window/Linux solution. 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. If you are a very good Windows programmer, you can actually get access to the raw file-system. There are probably just as many pitfalls with this approach, because Windows will be running while all of this is in operation.

So to re-iterate I would see if you could do everything from within Linux, if you can. It's just a whole lot simpler in the long run.

何止钟意 2024-07-11 23:17:13

分区具有与其关联的 UUID。 我不知道如何在 Windows 中找到这些,但在 Linux 中您可以通过以下方式找到每个分区的 UUID:

<块引用>

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

如果 Windows 中有等效的函数,您可以简单地存储它们选择的任何分区的 UUID,然后迭代 Linux 中的所有已知分区并匹配 UUID。

这是一个很好的观点,谢谢! 我查看了 vol_id(udev tarball 的一部分)的来源,似乎对于 FAT(32) 和 NTFS,它使用从分区上的预定义位置读取的卷序列号生成 UUUD。 由于我不期望除了 fat32 和 ntfs 之外的任何内容,我考虑使用此信息作为分区标识符。

Partitions have UUIDs associated with them. I don't know how to find these in Windows but in linux you can find the UUID for each partition with:

sudo vol_id -u device (e.g. /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.

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. Since I don't expect anything other then fat32 and ntfs I consider to use this information as a partition identifier.

耳根太软 2024-07-11 23:17:13

我对此的了解很浅薄,
但我认为这只适用于
使用 GPT 格式化的磁盘(Guid
分区表)分区,而不是
比旧式的 MBR 格式
世界上 99% 的人仍然陷于困境?

听起来不像是 Linux 用户的陈词滥调,但它对我有用。我将它与 NTFS 分区一起使用,没有遇到任何问题。 正如我在编辑中所说,vol_id 可能会自行生成它们。 如果是这样的话,就不会依赖任何特定的分区格式,这将是膨胀的。

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?

Not to sounds like a linux user cliche but it Works For Me.. I use it with NTFS partitions and have had no problems. As I said in my edit, vol_id may be generating them itself. If that were the case there would be no reliance on any particular partition format, which would be swell.

貪欢 2024-07-11 23:17:13

分区具有与其关联的 UUID。 我不知道如何在 Windows 中找到这些,但在 Linux 中,您可以使用以下命令找到每个分区的 UUID:

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

如果 Windows 中有一个等效的函数,您可以简单地存储它们选择的任何分区的 UUID,然后迭代 Linux 中的所有已知分区并匹配 UUID。

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

Partitions have UUIDs associated with them. I don't know how to find these in Windows but in linux you can find the UUID for each partition with:

sudo vol_id -u device (e.g. /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.

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). Having said that, there is nothing stopping you getting the source for volid and checking out what it does.

指尖微凉心微凉 2024-07-11 23:17:13

分区具有与其关联的 UUID

我对此的了解非常肤浅,但我认为这只适用于使用 GPT(指导分区表)分区格式化的磁盘,而不是世界上 99% 的地区仍然卡住的旧式 MBR 格式和?

Partitions have UUIDs associated with them

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?

眼泪都笑了 2024-07-11 23:17:13

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

Windows获取“NTFS卷序列号”的可能性:

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

  • c++ 下

    HANDLE fileHandle = CreateFile(L"\\\\.\\C:", // 或使用语法 "\\?\Volume{GUID}"  
                                     GENERIC_READ, 
                                     FILE_SHARE_READ | FILE_SHARE_WRITE, 
                                     无效的, 
                                     OPEN_现有, 
                                     无效的, 
                                     无效的); 
      双字我; 
      NTFS_VOLUME_DATA_BUFFER ntfsInfo; 
      DeviceIoControl(文件句柄,  
                      FSCTL_GET_NTFS_VOLUME_DATA,  
                      无效的,  
                      0,  
                      &ntfs信息, 
                      大小(ntfsInfo),  
                      &我,  
                      无效的)); 
      计算<<   “UUID 是”<<   std::hex <<   ntfsInfo.VolumeSerialNumber.HighPart <<   std::hex <<   ntfsInfo.VolumeSerialNumber.LowPart <<   结束; 
      

Linux 下获取 UUID 的可能性:

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

In Windows you can read the "NTFS Volume Serial Number" which seams to match the UUID under Linux.

Possibilities to get the "NTFS Volume Serial" from Windows:

  • commandline since XP: fsutil.exe fsinfo ntfsinfo C:

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

  • ls -l /dev/disk/by-uuid
  • ls -l /dev/disk/by-label
  • blkid /dev/sda1
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文