engrus

7z Parameter API 1.0

This document describes the unofficial API that you can use to handle the packing parameters when using plugins based on the 7z architecture.

Objective

The 7z API doesn’t provide a uniform way to configure packing parameters. That is, plugin developers can use their own packing parameter sets, parameter values, ​and parameter value ranges. For example, one plugin may use the Compression level parameter with the range from 0 to 9; another plugin may use the same parameter with the range from 0 to 39; yet another plugin may not use the Compression level parameter at all, but only use the Compression method parameter, allowing the user to select a value from the list. This approach makes it quite difficult to create a universal application that can use third-party plugins to create new files: If you want the application’s UI to be correct, the application must be aware of the specifics of each plugin’s packing parameters.

The proposed 7z Parameter API standard is intended to standardize the method for obtaining the available packing parameters and their properties.

Compatibility

The following applications and plugins support the 7z Parameter API:

Applications:

Plugins:

Description

There are two plugin types based on the 7z architecture: format plugins and codec plugins. Format plugins allow you to handle specific file formats (for example, Zip, Rar, or Cab). Сodec plugins allow you to use compression methods (for example, LZMA or ZSTD) and are intended to be used together with format plugins that let the user select the packing method (for example, with the 7z plugin). The plugins are stored on the disk as ordinary .dll files. A single .dll file can implement multiple plugins of different types. From now on, the term “plugin” will mean a plugin of any type (unless specified otherwise), and the term “client” will mean an application that uses such plugins.

Regardless of the plugin type, its instance is created using the CreateObject function, which is always available in the export table of the library implementing the plugin. Each plugin has a unique CLSID identifier. The CreateObject function has the following prototype:

function CreateObject(const ACLSID: TCLSID; const AIID: TIID; out AObj): HRESULT; stdcall;

Here the ACLSID parameter is the plugin identifier, and the AIID parameter identifies the requested interface.

ICompressParameterSet

According to the 7z Parameter API standard, the CreateObject function is also used to get an object instance that allows the client to get a list of packing parameters and their specifics. It is done using the following call:

CreateObject(CLSID, IID_CompressParameterSet, ParameterSet)

Here CLSID is the identifier of the plugin whose parameters you want to configure.

The obtained ParameterSet object implements the following interface:

  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;

The object obtained contains a set of parameters and their values ​​for a specific packing operation. By default, after creating an object, the parameters are set to the values ​​that are optimal for the plugin. Each parameter has an ID that is unique within the set.

Description of methods:

  • SetUpdateMode

    Sets the parameter configuration mode: FALSE – the parameters are set for creating a new file; TRUE – the parameters are set for modifying an existing file. The default value is FALSE. If the mode changes, the object may change the number and composition of the available parameters.

  • Reset

    Resets the set ​of parameter values to the original one. This operation doesn’t change the mode set by the SetUpdateMode method.

  • GetCount

    Returns the number of parameters.

  • GetParameterID

    Returns the parameter ID by index.

  • GetParameter

    Returns the object for setting a specific parameter by its ID.

  • SetFinishMode

    Call it just before you pass the parameters (see the "Passing parameters" section). Calling this method may change the values returned by the ICompressParameter.GetCurrentValue and ICompressParameter.GetKey methods. The value returned by ICompressParameter.GetCurrentValue may be of a different type than the value returned by ICompressParameter.GetType.

When the plugin makes a list of available parameters, IT IS RECOMMENDED that the main parameters are put in the beginning of the list, and the dependent parameters go after the parameters they depend on. For example, if Dictionary size depends on Compression method, put Compression method before Dictionary size in the list.

ICompressParameter

You can get any parameter configuration object by using the following call:

ParameterSet.GetParameter(ID, IID_ICompressParameter, Parameter)

The Parameter object obtained implements the following interface:

  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;

Description of methods:

  • GetID

    Returns the parameter ID. MUST match the ID returned by the ICompressParameterSet.GetParameterID method.

  • GetGroup

    Returns the group the parameter belongs to. The following groups are defined:

    • PARAMETER_GROUP_COMPRESSION

      The parameters in this group are related to data compression. An example of such parameter: Compression level.

    • PARAMETER_GROUP_STORE

      The parameters in this group are related to data storing. An example of such parameter: Store file modification time.

    • PARAMETER_GROUP_ENCRYPTION

      The parameters in this group are related to data encryption. An example of such parameter: Encryption method.

    • PARAMETER_GROUP_SFX

      The parameters in this group are related to creating a self-extracting (SFX) archive. An example of such parameter: SFX Module.

    • PARAMETER_GROUP_CONTAINER

      The parameters in this group are related to archive properties. An example of such parameter: Comment to archive.

    The method must always return the same value for different calls within the same operation.

  • GetDispayName

    Returns the parameter name to be displayed in the client UI (for example, “@Compression level”). The @ character in the first position has a special meaning. Its presence means that you can search for the string in the client’s internal dictionary, and then display its localized version. If there is no specific localization or the client doesn’t support localization, the @ character will be simply deleted. The string without the @ character in the first position should be displayed as-is.

  • GetStatus

    Returns the bit mask that determines the parameter state. The following flags are defined:

    • PARAMETER_STATUS_ENABLED

      The presence of this flag means the parameter can be modified. An important note: Within one operation, the presence of this flag is optional because the availability of a specific parameter may depend on the values ​​of other related parameters. For example, the Dictionary size may be forbidden if the Compression method is ZSTD, and allowed if it is LZMA. The PARAMETER_STATUS_ENABLED flag is only useful if the PARAMETER_STATUS_AVAILABLE flag is on. If the PARAMETER_STATUS_AVAILABLE flag is not used, the PARAMETER_STATUS_ENABLED flag MUST NOT be used.

    • PARAMETER_STATUS_AVAILABLE

      The presence of this flag means that the parameter POSSIBLY can be modified at the current or different combination of parameters. But the actual availability of the parameter is determined by the PARAMETER_STATUS_ENABLED flag. The PARAMETER_STATUS_AVAILABLE flag has a higher priority than the PARAMETER_STATUS_ENABLED flag. The client MUST ignore the PARAMETER_STATUS_ENABLED flag if the PARAMETER_STATUS_AVAILABLE flag is not used.

    • PARAMETER_STATUS_ALIAS

      The presence of this flag indicates that the parameter can be anywhere in the range between the values returned by GetMinValue and GetMaxValue, but it is RECOMMENDED that the client uses a ComboBox with value aliases to select from, not allowing the user to enter any values manually (see the ICompressParameterAlias section).

    • PARAMETER_STATUS_FORCEALIAS

      The presence of this flag indicates that the parameter can only be equal to one of the values returned by GetValue, and the client MUST use a ComboBox with value aliases, not allowing the user to enter any values manually (see the ICompressParameterAlias section).

    • PARAMETER_STATUS_HIDDEN

      The presence of this flag means that the parameter is hidden and MUST NOT be used to create the client’s UI.

    • PARAMETER_STATUS_NOHISTORY

      The presence of this flag means that input history MUST NOT be logged logged for the parameter (provided that the client application supports such functionality).

    The method MUST NOT modify the PARAMETER_STATUS_AVAILABLE, PARAMETER_STATUS_FORCEALIAS, PARAMETER_STATUS_HIDDEN, or PARAMETER_STATUS_NOHISTORY flag in case of calls within the same operation.

  • GetType

    Returns the parameter type. The allowed values are VT_BSTR, VT_BOOL, VT_UI4, and VT_UI8. The method MUST always return the same value for different calls within the same operation.

  • GetOffset

    Returns the offset (in characters) from the base line used for vertical alignment of the UI elements. Can visually emphasize that certain parameters depend on each other.

  • GetWidth

    Returns the recommended width (in characters) of a UI graphic element. In case the value is 0, the client application should use its own default value.

  • GetMinValue and GetMaxValue

    These methods return the minimum and maximum allowed values ​​of the parameter, respectively. They are only useful for VT_UI4 and VT_UI8. In case of VT_BSTR, GetMaxValue sets the maximum string length. They can return a value with the VT_EMPTY type, which means an absence of the respective limitation.

  • GetCurrentValue

    Returns the current value of the parameter.

  • SetCurrentValue

    Sets the current value of the parameter. Setting the parameter MUST set the dependent parameters to the values ​​that are optimal for the plugin. For example, if the Compression level is set to Ultra, the Dictionary size will be automatically set to 64 MB. The result returned by SetCurrentValue is interpreted as follows:

    • S_OK – The internal value has been changed
    • S_FALSE – The internal value has been changed, but a different value may have been set, or a dependent parameter may have been changed. The client must update its UI based on the new values and on the results returned by GetStatus and GetCurrentValue (or ICompressParameterAlias.GetCurrentIndex) for all the elements.
    • E_FAIL or any other error code – Couldn’t changed the value.
  • GetKey

    Returns the internal key name and is used when passing a parameters list in the ISetProperties method (see the section "Passing parameters").

An important note: The plugin is responsible for freeing the memory allocated when calling the GetDispayName, GetCurrentValue, or GetKey method. The client application MUST NOT free the pointers passed. When calling the SetCurrentValue method, the plugin MUST create a copy of each piece of data passed in its internal variables.

Standard ParameterID’s

The following standard ParameterID’s are defined:

IDParameter typeParameter group
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

The object that implements the ICompressParameter interface can also implement the ICompressParameterAlias interface:

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;

This interface makes it easier to build the client UI by displaying UI elements like ComboBox containing a list of predefined values ​​instead of using simple input fields.

Description of methods:

  • GetCount

    Returns the number of values. For example, for the Compression level, it can return 6, though the internal value of the parameter has a range from 0 to 9.

  • GetCurrentIndex

    Returns an index closest to the internal value of the parameter.

  • GetAlias

    Returns a string based on the index, to be used in the client UI to display the value. For example, if the parameter is Compression level and the index is 5, this method may return the string @Ultra. Like in the ICompressParameter.GetDispayName method, the @ character in the first position has a special meaning. Its presence means that you can search for the string in the client’s internal dictionary, and then display its localized version. If there is no specific localization or the client doesn’t support localization, the @ character will be simply deleted. The string without the @ character in the first position should be displayed as-is.

    The # character in the first position has a special meaning for parameters of the type VT_UI4 or VT_UI8. It indicates that the text immediately following that character is a string representation of data size. For example, the method may return a string like #1KB or #200 MB. In that case, the client application can use a localized version of the string by independently generating it based on the value returned by the GetValue method. If the client doesn’t support localization, the # character will be simply deleted.

  • GetValue

    Returns the parameter value to be passed to ICompressParameter.SetCurrentValue when the user selects a value with the corresponding index.

An important note: The plugin is responsible for freeing the memory allocated when calling the GetAlias or GetValue method. The client application MUST NOT free the pointers passed.

Considerations when implementing a format plugin supporting the Parameter API

If the format plugin supports file creation or modification using external codecs, the object that implements the ICompressParameterSet interface MUST also implement the ISetCompressCodecsInfo2 interface for passing the external codecs list:

  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;

Calling the CreateParameterSet method is similar to calling CreateObject and allows you to get an object instance that implements the ICompressParameterSet interface for a specific codec. Please keep in mind that some codecs cannot be configured, so calling CreateParameterSet may return an error.

If the plugin library exports the SetCodec function, the client that uses the Parameter API will also pass an object that implements both ISetCompressCodecsInfo and ICompressCodecsInfo2 to that library. The plugin must provide for a situation when SetCodec is called from a client that doesn’t use the Parameter API; in that case, calling ICompressCodecsInfo2 will fail.

The format plugin must automatically accumulate both its own properties and the properties of external plugins; when calling ICompressParameterSet interface methods, it should return data based both on its own parameters and on the available parameters of external codecs.

Considerations when implementing a client supporting the Parameter API

The client can use different strategies or their combinations to build its UI.

The client can use a simple UI that allows setting only some predefined properties, such as Compression method. In that case, the client doesn’t need to be concerned with enumerating the available properties using the GetCount and GetParameterID methods of the object implementing the ICompressParameterSet interface; instead, it can simply try to get the properties by calling GetParameter with the predefined IDs.

The client can build a dynamic UI based on a list of available parameters. In that case, IT IS RECOMMENDED that the client displays the UI elements in the order in which they are returned by the object implementing the ICompressParameterSet interface.

The client should provide for a situation when the plugin passes properties with the PARAMETER_STATUS_AVAILABLE flag set off. The client can hide or forbid using the respective UI elements.

The client should provide for a situation when the plugin passes properties with the PARAMETER_STATUS_ENABLED flag being set on or off depending on the combination of parameter values. The client can hide or forbid using the respective UI elements.

Considerations when using PARAMETER_GROUP_ENCRYPTION parameters

The presence of PARAMETER_ID_ENCRYPTION in the parameter list indicates that the plugin supports data encryption.

The presence of PARAMETER_ID_ENCRYPTION_PASSWORD in the parameter list indicates that the plugin supports password passing via the ICryptoGetTextPassword2 interface when packing data using the standard methods. However, the plugin must correctly save or return the string passed when calling SetCurrentValue or GetCurrentValue, respectively. The presence of this parameter in the absence of PARAMETER_ID_ENCRYPTION indicates that the plugin always creates encrypted files and the user MUST enter the password.

Considerations when using PARAMETER_GROUP_CONTAINER parameters

The presence of PARAMETER_ID_CONTAINER_VOLUMES or PARAMETER_ID_CONTAINER_VOLUMESIZE in the parameter list indicates that the plugin supports packing into a multi-volume archive using its own algorithm that is different from the standard 7-Zip algorithms. In that case, there is no need for the client to create archive volumes on its own using the standard algorithm.

The presence of PARAMETER_ID_CONTAINER_VOLUMESIZE in the absence of PARAMETER_ID_CONTAINER_VOLUMES indicates that the plugin always packs data into a multi-volume archive, so the user MUST enter the volume size.

Passing parameters

When you need to pass any parameters to the plugin, follow these steps:

  • Request the ISetProperties interface from the object implementing the IOutArchive interface.
  • Call ICompressParameterSet.SetFinishMode(True).
  • Generate a list of Keys and Values based on the GetKey and GetCurrentValue values of the ICompressParameter objects. The list MUST contain only parameters for which both of the PARAMETER_STATUS_AVAILABLE and PARAMETER_STATUS_ENABLED flags are set.
    An important note: The list MUST NOT contain any parameters for which the GetKey method returns an empty string.
    An important note: The list MUST also contain all the parameters for which the PARAMETER_STATUS_HIDDEN flag is set.
    An important note: The keys and values MUST be in the same order as the respective parameters.
  • Call ISetProperties. SetProperties(Keys, Values).

Headers

dec7zParameterAPI.pas

Testing

You can use our special tool to test a 7z Parameter API implementation in your plugin. The tool is an .exe file that doesn’t require installation. Just place the .dll file implementing your plugin in the same folder with the .exe file, and run it. The tool will show you how the packing settings dialog box is going to look when using your plugin.

You can also use our special .dll library to test a 7z Parameter API implementation in your client application. The .dll library implements two plugins supporting the 7z Parameter API. The first one is a format plugin, and the second one is a codec for the 7z format.

Download