Как сопоставить путь к устройству Linux с именем диска Windows?

StackOverflow https://stackoverflow.com/questions/18959

  •  09-06-2019
  •  | 
  •  

Вопрос

Я пишу приложение, которое на каком-то этапе выполняет низкоуровневые дисковые операции в среде Linux.Приложение на самом деле состоит из 2 частей, одна работает в Windows и взаимодействует с пользователем, а другая - это часть Linux, которая запускается с LiveCD.Пользователь выбирает буквы дисков 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?

P.S.Язык приложения - C ++.Я не могу этого изменить.

Это было полезно?

Решение

Разделы имеют связанные с ними UUID.Я не знаю, как найти их в Windows, но в linux вы можете найти UUID для каждого раздела с помощью:

sudo vol_id -u устройство (например/dev/sda1)

Если в Windows есть эквивалентная функция, вы могли бы просто сохранить UUID для любого выбранного раздела, затем выполнить итерацию по всем известным разделам в Linux и сопоставить UUID.

Редактировать: Это может быть программа только для Linux, и это может быть специально утилита volid, которая генерирует их из чего-то (вместо считывания метаданных для диска).Сказав это, ничто не мешает вам получить исходный код для volid и проверить, что он делает.

Другие советы

Разделы имеют связанные с ними UUID

Мои знания об этом очень поверхностны, но я думал, что это справедливо только для дисков, отформатированных с использованием разделов GPT (Guid Partition Table), а не старого формата MBR, который все еще используется 99% стран мира?

Мои знания об этом очень поверхностны, но я думал, что это справедливо только для дисков, отформатированных с использованием разделов GPT (Guid Partition Table), а не старого формата MBR, который 99% населения мира все еще застряло на?

Не хочу показаться клише пользователя Linux, но у меня это работает..Я использую его с разделами NTFS, и у меня не возникло никаких проблем.Как я уже говорил в своей правке, vol_id может генерировать их сам.Если бы это было так, не было бы никакой зависимости от какого-либо конкретного формата раздела, что было бы здорово.

Разделы имеют связанные с ними UUID.Я не знаю, как найти их в Windows, но в linux вы можете найти UUID для каждого раздела с помощью:

sudo vol_id -u устройство (например/dev/sda1)

Если в Windows есть эквивалентная функция, вы могли бы просто сохранить UUID для любого выбранного раздела, затем выполнить итерацию по всем известным разделам в Linux и сопоставить UUID.

Это хороший момент, спасибо!Я просмотрел источники vol_id (часть архива udev), и кажется, что для FAT (32) и NTFS он генерирует UUUD, используя серийный номер тома, который считывается из предопределенного местоположения в разделе.Поскольку я не ожидаю ничего, кроме fat32 и ntfs, я считаю целесообразным использовать эту информацию в качестве идентификатора раздела.

Вам нужно либо каким-то образом пометить диск (например,записать файл и т.д.), или найдите какой-нибудь идентификатор, который связан только с этим конкретным диском.

Очень сложно, почти невозможно определить, какую букву Windows присвоила бы определенному разделу диска, фактически не запуская Windows.Это связано с тем, что Windows всегда связывает диск, с которого она запускается, с C:.Это может быть любой диск, если у вас установлено более одной операционной системы.Windows также позволяет вам выбрать, какую букву диска она будет использовать в первую очередь для конкретного раздела, что вызовет дополнительные проблемы.

Было бы намного проще создать графический интерфейс внутри Linux, чем попробовать это смешанное решение Window / Linux.Я не говорю, что не стоит пробовать этот способ, я говорю о том, что при таком подходе существует очень много возможных подводных камней.Я уверен, что даже не знаю обо всех из них.

Другим вариантом было бы посмотреть, действительно ли вы могли бы выполнить часть Linux внутри Windows.Если вы очень хороший программист Windows, вы действительно можете получить доступ к файловой системе raw.Вероятно, при таком подходе существует не меньше подводных камней, потому что Windows будет работать, пока все это работает.

Итак, чтобы повторить итерацию, я хотел бы посмотреть, сможете ли вы все сделать из Linux, если сможете.Просто в долгосрочной перспективе все намного проще.

В Windows вы можете прочитать "Серийный номер тома NTFS", который соответствует UUID в Linux.

Возможности получения "Серийного номера тома NTFS" из Windows:

  • командная строка начиная с 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;
    

Возможности получения UUID в Linux:

  • ls -l /dev/disk/по-uuid
  • ls -l /dev/disk/пометке
  • blkid /dev/sda1
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top