7z Parameter API 1.0
Данный документ описывает неофициальный API для работы с параметрами упаковки при работе с плагинами, основанными на архитектуре 7z.
Цель
В 7z API не предусмотрено единого способа настройки параметров упаковки. Т.е. каждый разработчик плагинов может использовать собственный набор параметров и их значений и диапазонов. Например, один плагин может использовать параметр Уровень сжатия с диапазоном 0..9, а второй может использовать этот же параметр с диапазоном 0..39. Третий плагин вообще может не использовать параметр Уровень сжатия, а использовать только параметр Метод сжатия с возможностью выбора значения из списка. Это делает достаточно сложным написание универсального приложения, дающего возможность использовать сторонние плагинов для создания новых файлов, поскольку для построения корректного UI приложение должно знать об особенностях параметров упаковки каждого конкретного плагина.
Предлагаемый стандарт 7z Parameter API позволяет стандартизировать метод получения доступных параметров упаковки и их свойств.
Поддержка
Данный API поддерживается следующими программами и плагинами:
Программы:
Плагины:
Описание
Плагины, основанные на архитектуре 7z, можно разделить на два типа: форматные плагины и плагины кодеки. Первые позволяют работать с конкретными форматами файлов, например, zip, rar или cab. Вторые позволяют работать с методами сжатия, например, LZMA или ZSTD, и предназначены для совместного использования с плагинами первого типа, поддерживающими выбор метода упаковки, например, с плагином 7z. Физически плагины располагаются в обыкновенных dll файлах, при этом в dll файле может быть реализовано произвольное количество плагинов разного типа. Далее под термином плагин будет подразумеваться плагин любого типа, если не оговорено иное, а под термином клиент будет подразумеваться приложение, использующее плагины.
Независимо от типа плагина экземпляр плагина создается с использованием функции CreateObject, которая всегда есть в таблице экспорта библиотеки, в которой реализован плагин. При этом каждый плагин имеет уникальный CLSID идентификатор. Функция CreateObject имеет следующий прототип:
function CreateObject(const ACLSID: TCLSID; const AIID: TIID; out AObj): HRESULT; stdcall;
где параметр ACLSID является идентификатором плагина, а параметр AIID является идентификатором запрашиваемого интерфейса.
ICompressParameterSet
В соответствии со стандартом 7z Parameter API функция CreateObject также используется и для получения экземпляра объекта, позволяющего клиенту получить список параметров упаковки и их особенности. Делается это следующим вызовом:
CreateObject(CLSID, IID_CompressParameterSet, ParameterSet)
где CLSID является идентификатором плагина, параметры которого требуется настроить.
Полученный объект ParameterSet реализует следующий интерфейс:
ICompressParameterSet = interface(IUnknown) [SID_ICompressParameterSet] procedure SetUpdateMode(AUpdateMode: BOOL); stdcall; procedure Reset; stdcall; function GetCount: DWORD; stdcall; function GetParameterID(AIndex: DWORD; out AParameterID: TGUID): HRESULT; stdcall; function GetParameter(const AParameterID: TGUID; const AIID: TIID; out AParameter): HRESULT; stdcall; procedure SetFinishMode(AFinishMode: BOOL); stdcall; end;
Полученный объект содержит внутри себя набор параметров и их значений для конкретной операции упаковки. По умолчанию после создания объекта параметры установлены в оптимальные для плагина значения. Каждый параметр обладает собственным уникальным в рамках данного набора.
Описание методов:
- SetUpdateMode
Устанавливает режим настройки параметров: FALSE - параметры настраиваются для операции создания нового файла, TRUE - параметры настраиваются для операции модификации существующего файла. Значение по умолчанию - FALSE. При смене режима объект может изменить количество и состав доступных параметров.
- Reset
Сбрасывает набор значений параметров на исходный. Данная операция не изменяет режим, установленный методом SetUpdateMode.
- GetCount
Возвращает количество параметров.
- GetParameterID
Возвращает ID параметра по индексу.
- GetParameter
Возвращает объект настройки конкретного параметра по его ID.
- SetFinishMode
Вызывается непосредственно перед передачей параметров (см. раздел Передача параметров). После вызова данного метода могут измениться значения, возвращаемые методами ICompressParameter.GetCurrentValue и ICompressParameter.GetKey. При этом ICompressParameter.GetCurrentValue может вернуть значение с типом отличающимся от типа, возвращаемого ICompressParameter.GetType.
При построении плагином списка доступных параметров РЕКОМЕНДУЕТСЯ, что бы основные параметры шли первыми, и что бы зависимые параметры шли после параметров, от которых они зависят. Например, если параметр Размер словаря зависит от параметра Метод сжатия, то параметр Метод сжатия должен идти до параметра Размер словаря.
ICompressParameter
Каждый из объектов настройки параметра может быть получен следующим вызовом:
ParameterSet.GetParameter(ID, IID_ICompressParameter, Parameter)
Полученный объект Parameter реализует следующий интерфейс:
ICompressParameter = interface(IUnknown) [SID_ICompressParameter] function GetID: TGUID; stdcall; function GetGroup: DWORD; stdcall; function GetDisplayName: PWideChar; stdcall; function GetStatus: DWORD; stdcall; function GetType: TVarType; stdcall; function GetOffset: DWORD; stdcall; function GetWidth: DWORD; stdcall; function GetMinValue: TPropVariant; stdcall; function GetMaxValue: TPropVariant; stdcall; function GetCurrentValue: TPropVariant; stdcall; function SetCurrentValue(const Value: TPropVariant): HRESULT; stdcall; function GetKey: PWideChar; stdcall; end;
Описание методов:
- GetID
Возвращает ID параметра. ДОЛЖЕН совпадать с ID, возвращаемым методом ICompressParameterSet.GetParameterID.
- GetGroup
Возвращает группу, к которой относится параметр. Определены следующие группы:
- PARAMETER_GROUP_COMPRESSION
Параметры данной группы имеют отношение к сжатию данных. Пример - параметр Уровень сжания.
- PARAMETER_GROUP_STORE
Параметры данной группы имеют отношение к хранению данных. Пример - параметр Сохранять дату модификации файла.
- PARAMETER_GROUP_ENCRYPTION
Параметры данной группы имеют отношение к шифрованию данных. Пример - параметр Метод шифрации.
- PARAMETER_GROUP_SFX
Параметры данной группы имеют отношение к процессу созданию самораспаковывающегося архива. Пример - параметр Sfx Модуль.
- PARAMETER_GROUP_CONTAINER
Параметры данной группы имеют отношение к свойствам архива. Пример - параметр Комментарий к архиву.
Метод должен возвращать одно и то же значение при разных вызовах в рамках одной операции.
- PARAMETER_GROUP_COMPRESSION
- GetDispayName
Возвращает название параметра для отображения в UI клиента, например "@Compression level". Символ @ в первой позиции строки имеет особое значение. Его наличие обозначает, что строку можно поискать во внутреннем словаре клиента и вывести ее локализованную версию. Если локализации нет или клиент не поддерживает локализацию, то символ @ просто удаляется. Строка без символа @ в первой позиции строки должна выводится как есть.
- GetStatus
Возвращает битовую маску, определяющую состояние параметра. Определены следующие флаги:
- PARAMETER_STATUS_ENABLED
Наличие флага обозначает, что данный параметр доступен для модификации. Важно! В рамках одной операции данный флаг может как присутствовать, так и отсутствовать, поскольку доступность конкретного параметра может зависеть от значений других связанных параметров. Например, параметр Размер словаря может быть запрещен при значении параметра Метод сжатия равном ZSTD, но разрешен при при значении LZMA. Данный флаг имеет смысл только при установленном флаге PARAMETER_STATUS_AVAILABLE. При отсутствии флага PARAMETER_STATUS_AVAILABLE флаг PARAMETER_STATUS_ENABLED ДОЛЖЕН отсутствовать.
- PARAMETER_STATUS_AVAILABLE
Наличие флага обозначает, что данный параметр МОЖЕТ БЫТЬ доступен для модификации при текущей или иной комбинации параметров. Реальная доступность параметра определяется флагом PARAMETER_STATUS_ENABLED. Данный флаг имеет больший приоритет, нежели флаг PARAMETER_STATUS_ENABLED. Клиент ДОЛЖЕН игнорировать флаг PARAMETER_STATUS_ENABLED, если флаг PARAMETER_STATUS_AVAILABLE отсутствует.
- PARAMETER_STATUS_ALIAS
Наличие флага обозначает, что данный параметр может иметь произвольное значение из диапазона, образованного значениями, возвращаемыми методами GetMinValue и GetMaxValue, но клиенту РЕКОМЕНДУЕТСЯ при отображении UI данного параметра использовать графический элемент вида ComboBox с псевдонимами значений без возможности ввода значений вручную (см. раздел ICompressParameterAlias).
- PARAMETER_STATUS_FORCEALIAS
Наличие флага обозначает, что данный параметр может иметь только значение, соответствующее одному из значений, возвращаемых методом GetValue, и клиент ДОЛЖЕН при отображении UI данного параметра использовать графический элемент вида ComboBox с псевдонимами значений без возможности ввода значений вручную (см. раздел ICompressParameterAlias).
- PARAMETER_STATUS_HIDDEN
Наличие флага обозначает, что данный параметр является скрытым и не должен учувствовать в построении UI клиента.
- PARAMETER_STATUS_NOHISTORY
Наличие флага обозначает, что для данного параметра не должна вестись история ввода (если клиент поддерживает такую функциональность).
Метод не должен менять значения флагов PARAMETER_STATUS_AVAILABLE, PARAMETER_STATUS_ALIAS, PARAMETER_STATUS_FORCEALIAS, PARAMETER_STATUS_HIDDEN и PARAMETER_STATUS_NOHISTORY при разных вызовах в рамках одной операции.
- PARAMETER_STATUS_ENABLED
- GetType
Возвращает тип параметра. Допустимые значения: VT_BSTR, VT_BOOL, VT_UI4, VT_UI8. Метод должен возвращать одно и то же значение при разных вызовах в рамках одной операции.
- GetOffset
Возвращает смещение в символах от базовой линии вертикального выравнивания элементов UI. Может быть использовано для визуального подчеркивания зависимости параметров друг от друга.
- GetWidth
Возвращает рекомендуемую ширину в символах графического элемента UI. При значении 0 клиент должен использовать собственное значение по умолчанию.
- GetMinValue и GetMaxValue
Возвращают минимальное и максимальное допустимое значение параметра. Имеет смысл только для типов VT_UI4 и VT_UI8. Для типа VT_BSTR GetMaxValue определяет максимальную длину строки. Могут возвращаться значения с типом VT_EMPTY, что соответствует отсутствию соответствующего ограничения.
- GetCurrentValue
Возвращает текущее значение параметра.
- SetCurrentValue
Устанавливает текущее значение параметра. Установка параметра ДОЛЖНА менять зависимые параметры на оптимальные (с точки зрения плагина) значения. Например, при установке параметра Уровень сжатия в значение Ультра параметр Размер словаря автоматически устанавливается в значение 2048 Мб. Результат выполнения SetCurrentValue трактуется следующим образом:
- S_OK – внутренне значение изменено
- S_FALSE – внутренне значение изменено, но возможно присвоено иное значение или был изменен зависимый параметр. Клиент обязан обновить UI в соответствии с новыми значениями, учитывая результаты метода GetStatus и GetCurrentValue (или ICompressParameterAlias.GetCurrentIndex) всех элементов.
- E_FAIL или любой другой код ошибки – не удалось изменить значение.
- GetKey
Возвращает внутреннее имя ключа, используется при передаче списка параметров в методе ISetProperties (см. раздел Передача параметров)
Важно! Ответственность за освобождение памяти, выделенной при вызовах методов GetDispayName, GetCurrentValue и GetKey, несет плагин. Клиент НЕ ДОЛЖЕН освобождать переданные ссылки. При вызове метода SetCurrentValue плагин ДОЛЖЕН копировать переданные данные в свои внутренние переменные.
Стандартные ParameterID
Определены следующие стандартные ParameterID:
ID | Тип параметра | Группа параметра |
---|---|---|
PARAMETER_ID_COMPRESSION_LEVEL | VT_UI4 | PARAMETER_GROUP_COMPRESSION |
PARAMETER_ID_COMPRESSION_METHOD | VT_BSTR | |
PARAMETER_ID_COMPRESSION_SUBMETHOD | VT_BSTR | |
PARAMETER_ID_COMPRESSION_DICTIONARYSIZE | VT_UI8 | |
PARAMETER_ID_COMPRESSION_WORDSIZE | VT_UI4 | |
PARAMETER_ID_COMPRESSION_THREADS | VT_UI4 | |
PARAMETER_ID_COMPRESSION_SOLID | VT_BOOL | |
PARAMETER_ID_COMPRESSION_SOLIDBLOCKSIZE | VT_UI8 | |
PARAMETER_ID_COMPRESSION_SORT | VT_BOOL | |
PARAMETER_ID_STORE_SYMLINKS | VT_BOOL | PARAMETER_GROUP_STORE |
PARAMETER_ID_STORE_HARDLINKS | VT_BOOL | |
PARAMETER_ID_STORE_ALTSTREAMS | VT_BOOL | |
PARAMETER_ID_STORE_FILESECURITY | VT_BOOL | |
PARAMETER_ID_STORE_DATECREATED | VT_BOOL | |
PARAMETER_ID_STORE_DATEMODIFIED | VT_BOOL | |
PARAMETER_ID_STORE_DATEACCESSED | VT_BOOL | |
PARAMETER_ID_STORE_ATTRIBUTES | VT_BOOL | |
PARAMETER_ID_ENCRYPTION | VT_BOOL | PARAMETER_GROUP_ENCRYPTION |
PARAMETER_ID_ENCRYPTION_PASSWORD | VT_BSTR | |
PARAMETER_ID_ENCRYPTION_METHOD | VT_BSTR | |
PARAMETER_ID_ENCRYPTION_HEADER | VT_BOOL | |
PARAMETER_ID_ENCRYPTION_HEADERPASSWORD | VT_BSTR | |
PARAMETER_ID_SFX_CREATE | VT_BOOL | PARAMETER_GROUP_SFX |
PARAMETER_ID_SFX_MODULE | VT_BSTR | |
PARAMETER_ID_CONTAINER_VOLUMES | VT_BOOL | PARAMETER_GROUP_CONTAINER |
PARAMETER_ID_CONTAINER_VOLUMESIZE | VT_UI8 | |
PARAMETER_ID_CONTAINER_COMMENTS | VT_BSTR |
ICompressParameterAlias
Объект, реализующий интерфейс ICompressParameter, дополнительно может реализовывать интерфейс ICompressParameterAlias:
ICompressParameterAlias = interface(ICompressParameter) [SID_ICompressParameterAlias] function GetCount: DWORD; stdcall; function GetCurrentIndex: DWORD; stdcall; function GetAlias(AIndex: DWORD): PWideChar; stdcall; function GetValue(AIndex: DWORD): TPropVariant; stdcall; end;
Данный интерфейс позволяет упрощать построение UI клиента путем отображения графических элементов вида ComboBox со списком предопределенных значений вместо простых полей ввода.
Описание методов:
- GetCount
Возвращает количество значений. Например, для параметра Уровень сжатия метод может вернуть значение 6, несмотря на то, что внутреннее значение параметра имеет диапазон 0..9.
- GetCurrentIndex
Возвращает индекс, к которому наиболее близко внутреннее значение параметра.
- GetAlias
Возвращает строку в соответствии с индексом, которая используется в UI клиента для отображения значения. Например, для параметра Уровень сжатия для индекса 5 метод может вернуть строку @Ultra. Аналогично методу ICompressParameter.GetDispayName символ @ в первой позиции строки имеет особое значение. Его наличие обозначает, что строку можно поискать во внутреннем словаре клиента и вывести ее локализованную версию. Если локализации нет или клиент не поддерживает локализацию, то символ @ просто удаляется. Строка без символа @ в первой позиции строки должна выводится как есть.
Символ # в первой позиции также имеет особое значение для параметров, имеющих тип VT_UI4 и VT_UI8. Он обозначает, что последующий текст является строковым представление размера данных. Например, метод может вернуть строку #1Kb или #200 MB. В этом случае клиент может использовать локализованную версию строки, самостоятельно сформировав ее на основе значения, возвращенного методом GetValue. Если клиент не поддерживает локализацию, то символ # просто удаляется.
- GetValue
Возвращает значение параметра, которое нужно передать в ICompressParameter.SetCurrentValue при выборе пользователем значения с соответствующим индексом.
Важно! Ответственность за освобождение памяти, выделенной при вызовах методов GetAlias и GetValue, несет плагин. Клиент НЕ ДОЛЖЕН освобождать переданные ссылки.
Особенности реализации форматного плагина с поддержкой Parameter API
Если форматный плагин поддерживает создание или модификацию файлов с использованием внешних кодеков, то объект, реализующий интерфейс ICompressParameterSet, также дополнительно ДОЛЖЕН реализовывать интерфейс ISetCompressCodecsInfo2, через который передается список внешних по отношению к плагину кодеков:
ISetCompressCodecsInfo2 = interface(IUnknown) [SID_ISetCompressCodecsInfo2] function SetCompressCodecsInfo2(CompressCodecsInfo: ICompressCodecsInfo2): HRESULT; stdcall; end; ICompressCodecsInfo2 = interface(ICompressCodecsInfo) [SID_ICompressCodecsInfo2] function CreateParameterSet(AIndex: DWORD; const AIID: TIID; out AParameterSet): HRESULT; stdcall; end;
Вызов метода CreateParameterSet аналогичен вызову CreateObject и служит для получения экземпляра объекта, реализующего интерфейс ICompressParameterSet, соответствующего конкретному кодеку.
Если библиотека плагина экспортирует функцию SetCodec, то клиент, использующий Parameter API, также передает в нее объект, реализующий как ISetCompressCodecsInfo, так и ICompressCodecsInfo2. Плагин должен учитывать ситуацию, в которой SetCodec может вызываться из клиента, не использующего Parameter API, в этом случае запрос ICompressCodecsInfo2 будет неудачным.
Форматный плагин должен самостоятельно аккумулировать собственные свойства и свойства внешних плагинов, и при вызовах методов интерфейса ICompressParameterSet должен возвращать данные с учетом собственных параметров и доступных параметров внешних кодеков.
Особенности реализации клиента с поддержкой Parameter API
При построении UI клиент может использовать различные стратегии и их комбинации.
Клиент может использовать упрощенный UI, в котором можно настроить только предопределенные свойства, такие как Метод сжатия. В этом случае клиент может не заниматься перечислением доступных свойств с использованием методов GetCount и GetParameterID объекта, реализующего интерфейс ICompressParameterSet, а может просто пытаться получить их вызовом GetParameter с предопределенными ID.
Клиент может строить динамический UI, основываясь на списке доступных параметров. В этом случае РЕКОМЕНДУЕТСЯ отображать графические элементы в той последовательности, в которой возвращаются объектом, реализующим интерфейс ICompressParameterSet.
Клиент должен учитывать, что плагин может передавать свойства с выключенным флагом PARAMETER_STATUS_AVAILABLE. Клиент может скрывать или делать запрещенными соответствующие графические элементы в своем UI.
Клиент должен учитывать, что плагин может передавать свойства, у которых при различных комбинациях значений параметров флаг PARAMETER_STATUS_ENABLED может как присутствовать, так и отсутствовать. Клиент может скрывать или делать запрещенными соответствующие графические элементы в своем UI.
Особенности параметров группы PARAMETER_GROUP_ENCRYPTION
Наличие параметра PARAMETER_ID_ENCRYPTION в списке параметров обозначает, что плагин поддерживает шифрование данных.
Наличие параметра PARAMETER_ID_ENCRYPTION_PASSWORD в списке параметров обозначает, что плагин поддерживает передачу пароля для упаковки стандартным путем через интерфейс ICryptoGetTextPassword2. Тем не менее плагин должен корректно сохранять и возвращать переданную строку при вызове методов GetCurrentValue и SetCurrentValue. Наличие данного параметра при отсутствии параметра PARAMETER_ID_ENCRYPTION обозначает, что плагин всегда создает зашифрованные файлы и пользователь ДОЛЖЕН ввести пароль.
Особенности параметров группы PARAMETER_GROUP_CONTAINER
Наличие параметров PARAMETER_ID_CONTAINER_VOLUMES или PARAMETER_ID_CONTAINER_VOLUMESIZE в списке параметров обозначает, что плагин поддерживает разбитие на тома создаваемого архива собственным алгоритмом, отличным от стандартного метода 7Zip. В этом случае клиент не должен самостоятельно создавать тома с использованием стандартного алгоритма.
Наличие параметра PARAMETER_ID_CONTAINER_VOLUMESIZE при отсутствии параметра PARAMETER_ID_CONTAINER_VOLUMES обозначает, что плагин всегда разбивает на тома создаваемый архив и пользователь ДОЛЖЕН ввести размер тома.
Передача параметров
Для передачи настроенных параметров в плагин нужно использовать следующую последовательность действий:
- У объекта, реализующего интерфейс IOutArchive, запросить интерфейс ISetProperties.
- Вызвать ICompressParameterSet.SetFinishMode(True)
- Создать список Keys и Values на основе значений GetKey и GetCurrentValue объектов ICompressParameter. В список ДОЛЖНЫ попадать тольке те параметры, для которых установлены флаги PARAMETER_STATUS_AVAILABLE и PARAMETER_STATUS_ENABLED.
Важно! В список НЕ ДОЛЖНЫ попадать параметры, у которых метод GetKey возвращает пустую строку.
Важно! Параметры с флагом PARAMETER_STATUS_HIDDEN также ДОЛЖНЫ попадать в список.
Важно! Порядок следования ключей и значений ДОЛЖЕН совпадать с порядком следования самих параметров. - Вызвать ISetProperties. SetProperties(Keys, Values).
Заголовочные файлы
Тестирование
Для тестирования реализации Parameter API в плагинах можно использовать специальную утилиту. Утилита представляет собой исполняемый exe файл, не требующий инсталляции. Просто поместите dll файл вашего плагина в ту же папку и запустите утилиту. Утилита покажет, как может выглядеть окно настроек параметров упаковки при использовании вашего плагина.
Для тестирования реализации Parameter API в клиенте можно использовать специальную dll, в которой реализовано два плагина с поддержкой Parameter API. Первый представляет собой форматный плагин, второй является кодеком для формата 7z.