engrus

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

      Параметры данной группы имеют отношение к свойствам архива. Пример - параметр Комментарий к архиву.

    Метод должен возвращать одно и то же значение при разных вызовах в рамках одной операции.

  • 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 при разных вызовах в рамках одной операции.

  • 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_LEVELVT_UI4PARAMETER_GROUP_COMPRESSION
PARAMETER_ID_COMPRESSION_METHODVT_BSTR
PARAMETER_ID_COMPRESSION_SUBMETHODVT_BSTR
PARAMETER_ID_COMPRESSION_DICTIONARYSIZEVT_UI8
PARAMETER_ID_COMPRESSION_WORDSIZEVT_UI4
PARAMETER_ID_COMPRESSION_THREADSVT_UI4
PARAMETER_ID_COMPRESSION_SOLIDVT_BOOL
PARAMETER_ID_COMPRESSION_SOLIDBLOCKSIZEVT_UI8
PARAMETER_ID_COMPRESSION_SORTVT_BOOL
PARAMETER_ID_STORE_SYMLINKSVT_BOOLPARAMETER_GROUP_STORE
PARAMETER_ID_STORE_HARDLINKSVT_BOOL
PARAMETER_ID_STORE_ALTSTREAMSVT_BOOL
PARAMETER_ID_STORE_FILESECURITYVT_BOOL
PARAMETER_ID_STORE_DATECREATEDVT_BOOL
PARAMETER_ID_STORE_DATEMODIFIEDVT_BOOL
PARAMETER_ID_STORE_DATEACCESSEDVT_BOOL
PARAMETER_ID_STORE_ATTRIBUTESVT_BOOL
PARAMETER_ID_ENCRYPTIONVT_BOOLPARAMETER_GROUP_ENCRYPTION
PARAMETER_ID_ENCRYPTION_PASSWORDVT_BSTR
PARAMETER_ID_ENCRYPTION_METHODVT_BSTR
PARAMETER_ID_ENCRYPTION_HEADERVT_BOOL
PARAMETER_ID_ENCRYPTION_HEADERPASSWORDVT_BSTR
PARAMETER_ID_SFX_CREATEVT_BOOLPARAMETER_GROUP_SFX
PARAMETER_ID_SFX_MODULEVT_BSTR
PARAMETER_ID_CONTAINER_VOLUMESVT_BOOLPARAMETER_GROUP_CONTAINER
PARAMETER_ID_CONTAINER_VOLUMESIZEVT_UI8
PARAMETER_ID_CONTAINER_COMMENTSVT_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).

Заголовочные файлы

dec7zParameterAPI.pas

Тестирование

Для тестирования реализации Parameter API в плагинах можно использовать специальную утилиту. Утилита представляет собой исполняемый exe файл, не требующий инсталляции. Просто поместите dll файл вашего плагина в ту же папку и запустите утилиту. Утилита покажет, как может выглядеть окно настроек параметров упаковки при использовании вашего плагина.

Для тестирования реализации Parameter API в клиенте можно использовать специальную dll, в которой реализовано два плагина с поддержкой Parameter API. Первый представляет собой форматный плагин, второй является кодеком для формата 7z.

Скачать