Внутренняя структура файла конфигурации (*.cf) описана в публикации Андрея Овсянкина, за что ему огромное спасибо! Но с приходом в платформе релиза 8.3.16 произошли изменения в структуре хранения конфигурации.
В данной публикации изложен опыт по распаковке конфигурации в проекте https://github.com/e8tools/v8unpack после изменения формата хранения в 8.3.16
Так пустая конфигурация в формате 8.3.16 стала занимать на диске порядка 74-75 Кб, хотя ранее "пустышка" была размером в 5 Кб.
При этом если конфигурация создается в более свежей платформе чем 8.3.16, но с режимом совместимости до 8.3.15 включительно, структура конфигурации остается прежняя.
Рассмотрим за счет чего произошли такие изменения в размере файла.
Если открыть файл в любом HEX редакторе можно не сразу заметить изменения в структуре хранения данных в файле. Все вроде бы как на своих местах...Но это только впечатление.
На самом же деле реальные данные обнаруживаются совсем в другом месте, а именно начиная со смещения 0х1359 (4953)
Внутри контейнера тут и там встречаем волшебная константу, обозначающая некую «пустоту» – это число 0xFFFFFFFFFFFFFFFF - максимальное значение 8-байтового, ранее такой константой была 0х7FFFFFFF - максимальное значение 4-байтового целого числа со знаком.
Надо больше буковок FFFFFFFFFFFFFFFFFFFFFFFF...
В структуре блока изменилось значение размера с 0х200 (512) на 0х10000 (65536)
Заголовок блока увеличил длину с 31 байта до 54 из-за увеличения разрядности в 2 раза и принял следующий вид:
[CRLF][Размер всего документа][Пробел][Размер текущего блока][Пробел][Адрес следующего блока][Пробел][CRLF], где
- Размер всего документа - общая длина документа в байтах. Записана в виде строкового представления hex-числа. Длина – 16 байт.
- Размер текущего блока – длина тела блока в байтах. Записана также в виде строкового представления числа INT64 (было INT32) в hex-формате. Если документ состоит из единственного блока, то размер всего документа либо меньше, либо совпадает с размером текущего блока (что логично)
- Адрес следующего блока – адрес по которому расположен очередной блок документа. Если адрес следующего блока равен INT64_MAX (0xFFFFFFFFFFFFFFFF), то это значит, что следующего блока нет. Адрес следующего блока также записан в виде строкового представления числа.
Формат заголовка контейнера претерпел изменения в сторону увеличения адреса первого свободного блока в 2 раза (INT32 -> INT64):
Поле | Тип | Пояснение |
---|---|---|
Адрес первого свободного блока | INT64 (8 байт) | Смещение, по которому начинается цепочка свободных блоков |
Размер блока по умолчанию | INT32 (4 байта) | Блок может иметь произвольную длину, но значение по умолчанию можно использовать для добавления новых блоков, например. |
Поле неизвестного назначения (см. комментарии к статье) Часто совпадает с количеством файлов в контейнере | INT32 (4 байта) | Число, отражающее некоторую величину, как правило, совпадающую с количеством файлов в контейнере, однако, коллеги в комментариях считают, что это не совсем так. На алгоритм интерпретации контейнера данное число никак не влияет, его можно игнорировать |
Зарезервированное поле | INT32 (4 байта) | Всегда равно 0 (всегда ли?) |
Формат записи документа оглавления.
Оглавление содержит перечень указателей на файлы, размещенные в контейнере
Поле | Тип | Пояснение |
---|---|---|
Адрес документа атрибутов | INT64 (8 байт) | Адрес документа атрибутов файла |
Адрес документа содержимого | INT64 (8 байт) | Адрес документа содержимого файлов |
Зарезервированное поле | INT64 (8 байт) | Всегда равно 0xFFFFFFFFFFFFFFFF |
Казалось бы, переходи по данным адресам и получай данные, но...
Пытаемся получить атрибуты файла...пусто.
Аналогичная ситуация и с содержимым:
Данных, по указанным адресам не оказывается. Чтобы найти реальные данные необходимо вспомнить про волшебную константу 0х1359 и данные сразу обнаружатся.
Данные атрибутов = 0x0001004B + 0x1359 = 0x113A4
Данные содержимого = 0x000100E2 + 0x1359 = 0x1143B
Файлы внутри корневого контейнера как известно сжаты по алгоритму Deflate, файлы внутри вложенных контейнеров записаны без сжатия. После распаковки алгоритм поиска данных в контейнере необходимо использовать тот, что описан в статье Андрея, т.е. в сжатом контейнере волшебная константа 0х1359 при сохранении данных не участвовала.
В заключение
Возможно, приведенная статья кому-то сократит путь к пониманию чтения файлов конфигурации 8.3.16. Жду конструктивную критику и желаю всем удачи!