unit ModuleDef;
{$ALIGN 1}
{$MINENUMSIZE 4}

interface

uses
  Windows;

// Extract progress callbacks
type
  TExtractProgressFunc = function (Handle: THandle; Progress: int64): integer; stdcall;
  TExtractProcessCallbacks = record
    signalContext: THandle;
    FileProgress: TExtractProgressFunc;
  end;

const
  ACTUAL_API_VERSION = 6;
  STORAGE_FORMAT_NAME_MAX_LEN = 32;
  STORAGE_PARAM_MAX_LEN = 64;

type
  TStorageGeneralInfo = packed record
    Format: array[0..STORAGE_FORMAT_NAME_MAX_LEN-1] of WideChar;
    Compression: array[0..STORAGE_PARAM_MAX_LEN-1] of WideChar;
    Comment: array[0..STORAGE_PARAM_MAX_LEN-1] of WideChar;
    Created: TFileTime;
  end;

  TStorageOpenParams = packed record
    StructSize: {$IFDEF UNICODE} SIZE_T {$ELSE} DWORD {$ENDIF} ;
    FilePath: PWideChar;
    Password: PAnsiChar;
    Data: Pointer;
    DataSize: {$IFDEF UNICODE} SIZE_T {$ELSE} DWORD {$ENDIF} ;
  end;

  TStorageItemInfo = packed record
    Size: int64;
    PackedSize: int64;
    Attributes: DWORD;
    CreationTime: TFileTime;
    ModificationTime: TFileTime;
    NumHardlinks: Word;
    Owner: array[0..63] of WideChar;
    Path: array[0..1023] of WideChar;
  end;

  TExtractOperationParams = packed record
    ItemIndex: integer;
    Flags: integer;
    DestPath: PWideChar;
    Password: PAnsiChar;
    Callbacks: TExtractProcessCallbacks;
  end;

  // Open storage return results
  TOpenStorageResult = (
    SOR_INVALID_FILE = 0,
    SOR_SUCCESS = 1,
    SOR_PASSWORD_REQUIRED = 2
  );

  // Item retrieval result
  TGetItemResult = (
    GET_ITEM_ERROR = 0,
    GET_ITEM_OK = 1,
    GET_ITEM_NOMOREITEMS = 2
  );

  // Extract result
  TExtractResult = (
    SER_SUCCESS = 0,
    SER_ERROR_WRITE = 1,
    SER_ERROR_READ = 2,
    SER_ERROR_SYSTEM = 3,
    SER_USERABORT = 4,
    SER_PASSWORD_REQUIRED = 5
  );

  TOpenStorageFunc = function(Params: TStorageOpenParams; var Handle: THandle; var Info: TStorageGeneralInfo): TOpenStorageResult; stdcall;
  TPrepareFilesFunc = function(Handle: THandle): boolean; stdcall;
  TCloseStorageFunc = procedure(Handle: THandle); stdcall;
  TGetItemFunc = function(Handle: THandle; ItemIndex: integer; var Info: TStorageItemInfo): TGetItemResult; stdcall;
  TExtractFunc = function(Handle: THandle; Params: TExtractOperationParams): TExtractResult; stdcall;

  TModuleCBS = packed record
    OpenStorage: TOpenStorageFunc;
    CloseStorage: TCloseStorageFunc;
    GetItem: TGetItemFunc;
    ExtractItem: TExtractFunc;
    PrepareFiles: TPrepareFilesFunc;
  end;

  TModuleLoadParameters = packed record
    //IN
    StructSize: {$IFDEF UNICODE} SIZE_T {$ELSE} DWORD {$ENDIF} ;
    Settings: PWideChar;
    //OUT
    ModuleID: TGUID;
    ModuleVersion: DWORD;
    ApiVersion: DWORD;
    ApiFuncs: TModuleCBS;
  end;

  // Function that should be exported from modules
  TLoadSubModuleFunc = function (var Params: TModuleLoadParameters): boolean; stdcall;
  TUnloadSubModuleFunc = procedure; stdcall;

function MakeModuleVersion(Major, Minor: Word): DWORD;

implementation

function MakeModuleVersion(Major, Minor: Word): DWORD; {$IFDEF UNICODE} inline; {$ENDIF}
begin
  Result := (DWORD(Major) shl 16) or DWORD(Minor);
end;

end.
