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

Я пишу приложение, которое на каком-то этапе выполняет операции с дисками низкого уровня в среде 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 может не работать, кроме дисков IDE или SATA.

Любые идеи о том, как улучшить эту схему? Возможно, есть другой способ определить имена окон без записи всех данных в приложении Windows?

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

20.08.2008 22:06:11
6 ОТВЕТОВ
РЕШЕНИЕ

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

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

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

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

1
20.08.2008 22:25:21

С разделами связаны идентификаторы UUID

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

2
20.08.2008 22:53:12

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

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

1
21.08.2008 00:38:59

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

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

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

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

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

0
21.08.2008 00:49:58

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

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

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

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

1
21.08.2008 07:37:10

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

Возможности получить «NTFS Volume Serial» из Windows :

  • командная строка с XP: fsutil.exe fsinfo ntfsinfo 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 / by-uuid
  • ls -l / dev / disk / by-label
  • blkid / dev / sda1
0
3.02.2010 18:13:01