Чтение UUID логических разделов дисков в Qt

Писал свой диплом на Qt 5.0.1 (beta). Одной из промежуточных была задача идентификации моей программой логических разделов дисков на всех поддерживаемых Qt5 платформах. На момент написания сообщения имели 3 платформы: Linux-based, Windows family, Mac OS X. Нужно было определять на любой из них при выборе какого-либо файла для анализа, рассматривался ли он на другой системе до этого, или нет (внутренние базы данных каждой копии программы способны синхронизироваться). Конечно, самый надежный способ – распознавать файлы по их контрольным суммам. Но было решено, что нужны дополнительные более быстрые способы для редкоизменяемых файловых систем, в ситуациях, когда раздел монтируется на разных операционках, а его файловая система не меняется (например, для флэшки, с которой ничего не делали, а просто подключи сначала на один, а потом на другой ПК с программой). Поэтому и появилась задача идентификации логических разделов. (TODO: оценить эффективность такой оптимизации).

Т.к. фактически каждая (TODO: проверить, насколько это правда) файловая система имеет в своей спецификации суперблок с записанным в него уникальным идентификатором (правда, к сожалению, самые ходовые FAT32 и NTFS используют для этих целей 16 и 32 байта соответственно, что кажется маловатым), решения в духе “записать в корень раздела файлик с значением собственноручно реализованной идентифицирующей хэш-функции для раздела” мной было решено отбросить сразу. Следующим было отклонено решение в духе “нагуглить позиции суперблоков в каждой спецификации той или иной файловой системы и запилить чтения нужных идентификаторов в лоб как сырых данных”, т.к. в API всех рассматриваемых операционок (про Mac OS X абзацем ниже отдельно) есть средства по получению необходимой информации.

Т.к. я нищеброд, и Mac OS X не было времени искать / ставить на виртуалку (амбициозность основных задач, поставленных в дипломе, сделала его одним сплошным дедлайном уже с момента утверждения ТЗ), на макось я позволил себе забить на какое-то время (понадеялся на unix-подобность, но, похоже, для нее придется искать решение дополнительно).

Среди основных модулей Qt5 модуля по работе с информацией о дисках не нашлось. К счастью, нашелся дополнительный модуль Qt System Info (странно, почему-то не вижу его сейчас в списке “All Modules”). В нем описан класс QStorageInfo, имеющий методы QStringList allLogicalDrives() и Q_INVOKABLE QString uriForDrive(const QString &drive) const, но, к сожалению, предоставляющий информацию лишь о индентификаторах, используемых операционками для монтирования разделов, и они вычисляются на каждой платформе разные.

В linux-based операционках идентификаторы, о которых идет речь, используются самой ОС для монтирования файловых систем, и это приятно. В Windows (и, похоже, и в Mac OS X) по причинам, не до конца мне понятным (а найти их в интернете не очень-то легко в силу закрытости последних) для монтирования используются идентификаторы свои-альтернативные-не-понятно-как-вычисляемые, но при этом те, что имеют сами файловые системы в своем суперблоке, как я уже и сказал, читать средствами API можно.

Т.к. я не умею пока хорошо писать на Qt, первым делом было решено попробовать грубо заменить реализацию uriForDrive для винды. Все получилось. Код прилагаю. (К слову, не помню уже, как это выяснял, но собирать System Info для Windows 7 x32 стоило в MSVC2010 не ниже SP1, а для Windows 8 x64 – с MSVC2012. С MinGW тоже собиралось, но испытывал трудности в чем-то другом с ним). Дальше хочу привести этот код к адекватному виду (всмысле не тупо заменять существующую uriForDrive, а сделать дополнительным функционалом), добить и Mac OS X, переписать покрасивше этот пост, подготовить его на англ. (сделал) и запилить коммит в qtsystems.

P.S. этот пост изначально был в тамблере, как и многие другие, пока не нашел для себя jekyll и githubpages.

 █████╗  █████╗  ██╗██████╗  ██████╗ 
██╔══██╗██╔══██╗███║╚════██╗██╔═══██╗
███████║███████║╚██║ █████╔╝██║   ██║
██╔══██║██╔══██║ ██║ ╚═══██╗██║▄▄ ██║
██║  ██║██║  ██║ ██║██████╔╝╚██████╔╝
╚═╝  ╚═╝╚═╝  ╚═╝ ╚═╝╚═════╝  ╚══▀▀═╝