В эталоне BlackBox есть модуль DevPacker
, используемый для упаковки в исполняемый файл произвольных ресурсов. Ресурсы размещаются внутри исполняемого файла по определенным правилам. Эти правила известны в модуле HostPackedFiles
, который реализует фабрику Files.dir
для работы с упакованными ранее файлами.
В процессе пересмотра внутренней структуры BlackBox, в модуле DevPacker
обнаружилась негерметичность.
Она заключалась в прямой зависимости от HostFiles
и HostPackedFiles
. Кроме этого, HostPackedFiles
опирался на структуру данных, формируемую в DevPacker
(имплицитная зависимоcть). Негерметичность мешала использовать модуль в новой сборке ББ.
Для использования DevPacker
в новой сборке ББ необходимо провести герметизацию модуля.
При взаимодействии DevPacker
с пользователем создаётся список файлов (его тип - платформонезависимая структура FileList
), который передается записывателю.
Создадим отдельную подсистему Packed
. Процедуры записи (их логика зависит от структуры исполняемого файла PE EXE) отделим в модуль PackedExeWriter
. Команды упаковки вынесем в модуль PackedCmds. Структуру FileList переместим в модуль PackedCore
. Там же объявим записыватель, чей абстрактный метод PackList
реализуется в PackedExeWriter
.
Таким образом, функциональность DevPacker
отделилась от платформозависимых модулей. Модуль PackedCore
представляет для модуля PackedCmds
герметичный прикладной слой.
Модуль HostPackedFiles
имеет неявную зависимость от алгоритмов DevPacker
и опирается на эталонный интерфейс HostFiles
, реализации файловых абстракций BlackBox
.
Это делает его уязвимым как при смене платформы, так и при смене формата записи. Поэтому указания на конкретные особенности имеет смысл отделить от остальной логики.
Создадим модуль PackedWinConst
, который будет содержать необходимую информацию для работы с форматом записи (для эталонной реализации это константы версии и тэга). Эти же константы используем внутри модуля PackedExeWriter
.
Модуль PackedExeWriter
реализует функции записи файлов, которые описаны типом PackedCore.FileList
. Этот тип описывает значение даты и времени последней модификации файла, которые затем использует PackedExeWriter
. На различных платформах (а так же при использовании пользовательских реализаций Files.Directory
) способы получения информации о времени последнего изменения могут различаться. Следовательно, модуль PackedExeWriter
не должен зависеть от конкретной реализации файловой подсистемы BB, согласно принципа «черного ящика». Для изоляции PackedExeWriter
опишем в модуле PackedCore
хук для получения нужной информации, который реализуем в модуле PackedOldWinSelector
(для работы в эталонном ББ). Данный модуль одновременно будет устанавливать и реализацию записывателя.
Таким образом из негерметичного модуля DevPacker
мы получили герметичную реализацию упаковщика файлов, подсистему https://bitbucket.org/petryxa/packed, в которой представлен абстрактный интерфейс упаковки файлов, пользовательский интерфейс, который не зависит от реализации, а также конкретная реализация, которая скрыта и соответствует строго определенной платформе. Это открывает возможность как для использования в новой сборке ББ, так и для дальнейшего расширения подсистемы на новые платформы.1)
Для реализации упаковщика под новую платформу, например, Linux, необходимо: описать константы платформы (см. PackedLinConst
), реализовать модули записывателя (см. PackedSOWriter
), и реализовать модуль PackedLinFiles
, который возможно будет взаимодействовать с модулем-реализацией файловой системы в Linux-сборке ББ. Также необходим селектор платформы (см. PackedLinSelector
) который позволит инициализировать подсистему для работы под Linux.