/*
  ACX plugin interface for oMega Commander.
  Interface version: 3.0
  Pylonos.com LLC (c)
  https://pylonos.com
*/

#pragma pack(push,1)

/* Version of the plugin interface */
#define PlugACXVers_Major            3
#define PlugACXVers_Minor            0

#define PlugWCXVers_Major            2
#define PlugWCXVers_Minor            21

/* The error codes are returned to the calling application */
#define E_SUCCESS                    0  // Successful execution
#define E_END_ARCHIVE                10 // No more files in archive (archive end)
#define E_NO_MEMORY                  11 // Not enough memory
#define E_BAD_DATA                   12 // Data error
#define E_BAD_ARCHIVE                13 // CRC error in archive data
#define E_UNKNOWN_FORMAT             14 // Invalid archive format
#define E_EOPEN                      15 // Impossible to open existing file
#define E_ECREATE                    16 // Impossible to create a file
#define E_ECLOSE                     17 // Error closing the file
#define E_EREAD                      18 // Error reading file
#define E_EWRITE                     19 // Error writing file
#define E_SMALL_BUF                  20 // Buffer is too small
#define E_EABORTED                   21 // Operation was interrupted by the user
#define E_NO_FILES                   22 // Files not found
#define E_TOO_MANY_FILES             23 // Too many files to archive
#define E_NOT_SUPPORTED              24 // Not supported operation

#define E_EX_UNKNOWN_ERR             201 // Unknown error
#define E_EX_ENCRYPTED               202 // File/archive is encrypted and not be processed (decryption isn't supported)
#define E_EX_FILE_TOO_BIG            203 // File is too big
#define E_EX_FILE_IN_USE             204 // File is locked/in use and can't be processed
#define E_EX_NOT_SUPPORTED_METHOD    205 // Archive method isn't supported
#define E_EX_SKIP                    206 // File was skipped
#define E_EX_MAYBE_DISKFULL          207 // Maybe disk full

/* Open archive flags */
#define PK_OM_LIST                   0   // View archive content
#define PK_OM_EXTRACT                1   // Unpack archive

/* Flags for ProcessFile, ProcessFileW */
#define PK_SKIP                      0   // Skip file (without unpacking)
#define PK_TEST                      1   // Test integrity of the file
#define PK_EXTRACT                   2   // Unpack the file to disk

/* Flags for ChangeVolProcW */
#define PK_VOL_ASK                   0   // Ask the user about location of the next volume
#define PK_VOL_NOTIFY                1   // Notify the application, that the next volume can be unpackd

/* Flags for PackFiles, PackFilesW */
#define PK_PACK_MOVE_FILES           1   // Delete the input file after archiving
#define PK_PACK_SAVE_PATHS           2   // Save file paths
#define PK_PACK_ENCRYPT              4   // Request file password during encryption

/* Flags for ArcPackFilesW */
#define PK_PACKEX_MOVE_FILES         1
#define PK_PACKEX_SAVE_PATHS         2
#define PK_PACKEX_ENCRYPT            4
#define PK_PACKEX_ENCRYPTLIST        8
#define PK_PACKEX_SOLID              16

/* Flags of the ArcPlugInitData.out_PackerCaps, GetPackCaps */
#define PK_CAPS_NEW                  1   // Can create new archives
#define PK_CAPS_MODIFY               2   // Can change existing archives
#define PK_CAPS_MULTIPLE             4   // Archive can contain multiple files
#define PK_CAPS_DELETE               8   // Can delete files
#define PK_CAPS_OPTIONS              16  // Settings dialog exists
#define PK_CAPS_MEMPACK              32  // Supports archiving to memory
#define PK_CAPS_BY_CONTENT           64  // Detect archive type by content
#define PK_CAPS_SEARCHTEXT           128 // Can search text in archive
#define PK_CAPS_HIDE                 256 // Show as a regular file (hide archive icon), don't open on Enter, only on Ctrl+PgDn
#define PK_CAPS_ENCRYPT              512 // Plug-in supports parameter PK_PACK_ENCRYPT

/* Flags for StartMemPackW, StartMemPack */
#define MEM_OPTIONS_WANTHEADERS      1   // Return archive headers with packed data

/* Return values of PackToMem */
#define MEMPACK_OK                   0   // Function call finished OK, but there is more data
#define MEMPACK_DONE                 1   // Function call finished OK, there is no more data

/* Flags for PkSetCryptCallback */
#define PK_CRYPTOPT_MASTERPASS_SET   1   // The user already has a master password defined

/* Flags for PkCryptProc callback */
#define PK_CRYPT_SAVE_PASSWORD       1
#define PK_CRYPT_LOAD_PASSWORD       2
#define PK_CRYPT_LOAD_PASSWORD_NO_UI 3   // Load password only if master password has already been entered!
#define PK_CRYPT_COPY_PASSWORD       4   // Copy encrypted password to new archive name
#define PK_CRYPT_MOVE_PASSWORD       5   // Move password when renaming an archive
#define PK_CRYPT_DELETE_PASSWORD     6   // Delete password

/* Parameter types for ArcParamToPlug */
#define PK_PARTOPLUG_PASSWORD        0
#define PK_PARTOPLUG_LANGUAGE        1

/* Parameter types for ArcParamFromPlug */
#define PK_PARFROMPLUG_STAGE         0
#define PK_PARFROMPLUG_FILESIZE      1

/* Return values of ArcGetPasswordW */
#define PK_GETPASS_OK                0
#define PK_GETPASS_CANCEL            1
#define PK_GETPASS_SKIP              2
#define PK_GETPASS_UNEXPECTED_ERR    -1

/* Flags for ArcInitPluginDataW.out_PackerCapsEx */
#define PK_CAPEX_MYSELF_ASK_PASS     1
#define PK_CAPEX_CURFILE_ASK_PASS    2
#define PK_CAPEX_ENCRYPTLIST         4
#define PK_CAPEX_SOLID               8

/* Codes of ArcOpenDataW.out_ArcPropFlags */
#define PK_ARC_VOLUME                0x001 // Volume attribute (archive volume)
#define PK_ARC_COMMENT               0x002 // Archive comment present
#define PK_ARC_LOCK                  0x004 // Archive lock attribute
#define PK_ARC_SOLID                 0x008 // Solid attribute
#define PK_ARC_AUTHENCITY_INFO       0x020 // Authenticity information present
#define PK_ARC_RECOVERY_RECORD       0x040 // Recovery record present
#define PK_ARC_HEADERS_ENCRYPTED     0x080 // Block headers are encrypted
#define PK_ARC_FIRST_VOL             0x100 // First volume

/* Codes of ArcOpenDataW.ExFlags */
#define PK_ARCEX_LOCK_ASK_PASS       0x001

/* Codes of tHeaderDataExW.Flags, tHeaderDataEx.Flags, THeaderData.Flags */
#define PK_HF_PREVVOL                0x0001;
#define PK_HF_NEXTVOL                0x0002;
#define PK_HF_ENCRYPT                0x0004;
#define PK_HF_COMMENT                0x0008;
#define PK_HF_SOLID                  0x0010;

/* Threshold for progressbars double percents for ArcProcessDataProcW, ProcessDataProcW, ProcessDataProc */
#define PK_DOUBLEPROGRESS            -100000

/* The functions calling by a plugin */
typedef int (__stdcall *ArcProcessDataProcW)(_In_ LONG_PTR Session, _In_ wchar_t *FileName, _In_ int Size);
typedef int (__stdcall *ArcGetPasswordProcW)(_In_ LONG_PTR Session, _In_ HANDLE hArcData, _In_ wchar_t *ArcFileName, _In_ wchar_t *FileNameInArc, _Out_ wchar_t *Password, _In_ int PasswordMaxLen);
typedef int (__stdcall *ArcShowDialogProcW)(_In_ LONG_PTR Session, _In_ wchar_t *WinCaption, _In_ wchar_t *FormattedText, _In_ wchar_t *ControlsDesc, _Out_opt_ wchar_t *ResultsBuffer, _Inout_ int *pResultsBufferLen, _In_ int ImageIndex);
typedef int (__stdcall *ArcParamFromPlugProc)(_In_ LONG_PTR Session, _In_ HANDLE hArcData, _In_ int ParameterType, _In_ LONG_PTR ParameterData);

typedef int (__stdcall *tChangeVolProc)(_Inout_ unsigned char *ArcVolName, _In_ int Mode);
typedef int (__stdcall *tChangeVolProcW)(_Inout_ wchar_t *ArcVolName, _In_ int Mode);
typedef int (__stdcall *tProcessDataProc)(_In_ unsigned char *FileName, _In_ int Size);
typedef int (__stdcall *tProcessDataProcW)(_In_ wchar_t *FileName, _In_ int Size);
typedef int (__stdcall *tPkCryptProc)(_In_ int CryptoNr, _In_ int Mode, _In_ char *ArchiveName, _In_ char *Password, _In_ int MaxLen);
typedef int (__stdcall *tPkCryptProcW)(_In_ int CryptoNr, _In_ int Mode, _In_ wchar_t *ArchiveName, _In_ wchar_t *Password, _In_ int MaxLen);

typedef struct tHeaderData {
  char         ArcName[260];
  char         FileName[260];
  unsigned int Flags;
  unsigned int PackSize;
  unsigned int UnpSize;
  unsigned int HostOS;
  unsigned int FileCRC;
  unsigned int FileTime;
  unsigned int UnpVer;
  unsigned int Method;
  unsigned int FileAttr;
  char         *CmtBuf;
  unsigned int CmtBufSize;
  unsigned int CmtSize;
  unsigned int CmtState;
};

typedef struct tHeaderDataEx {
  char         ArcName[1024];
  char         FileName[1024];
  unsigned int Flags;
  unsigned int PackSize;
  unsigned int PackSizeHigh;
  unsigned int UnpSize;
  unsigned int UnpSizeHigh;
  unsigned int HostOS;
  unsigned int FileCRC;
  unsigned int FileTime;
  unsigned int UnpVer;
  unsigned int Method;
  unsigned int FileAttr;
  char         *CmtBuf;
  unsigned int CmtBufSize;
  unsigned int CmtSize;
  unsigned int CmtState;
  char         Reserved[1024];
};

typedef struct tHeaderDataExW {
  wchar_t      ArcName[1024];
  wchar_t      FileName[1024];
  unsigned int Flags;
  unsigned int PackSize;
  unsigned int PackSizeHigh;
  unsigned int UnpSize;
  unsigned int UnpSizeHigh;
  unsigned int HostOS;
  unsigned int FileCRC;
  unsigned int FileTime;
  unsigned int UnpVer;
  unsigned int Method;
  unsigned int FileAttr;
  char         *CmtBuf;
  unsigned int CmtBufSize;
  unsigned int CmtSize;
  unsigned int CmtState;
  char         Reserved[1024];
};

typedef struct tOpenArchiveData {
  char *ArcName;
  int  OpenMode;
  int  OpenResult;
  char *CmtBuf;
  int  CmtBufSize;
  int  CmtSize;
  int  CmtState;
};

typedef struct tOpenArchiveDataW {
  wchar_t *ArcName;
  int     OpenMode;
  int     OpenResult;
  wchar_t *CmtBuf;
  int     CmtBufSize;
  int     CmtSize;
  int     CmtState;
};

typedef struct ArcOpenDataW {
  wchar_t             *ArcNameW;
  unsigned int        OpenMode;
  unsigned int        out_OpenResult;
  unsigned int        out_ArcPropFlags;
  unsigned int        ExFlags;
  LONG_PTR            Session;
  ArcProcessDataProcW ProcessDataW;
  LONG_PTR            Reserved[8];
};

typedef struct ArcInitPluginDataW {
  unsigned short       VersMajor;
  unsigned short       VersMinor;
  unsigned short       out_VersMajor;
  unsigned short       out_VersMinor;
  wchar_t              *PluginFileName;
  ArcGetPasswordProcW  ArcGetPasswordW;
  ArcShowDialogProcW   ArcShowDialogW;
  ArcParamFromPlugProc ArcParamFromPlug;
  tChangeVolProc       ChangeVol;
  tChangeVolProcW      ChangeVolW;
  wchar_t              DefaultIniNameW[MAX_PATH];
  wchar_t              *out_Extensions;
  unsigned int         out_PackerCaps;
  unsigned int         out_PackerCapsEx;
  LONG_PTR             Reserved[8];
};

enum ArcStageTypes { astNormal, astPrepareArchive };
typedef struct ArcProcessingStageData {
  ArcStageTypes ArcStageType;
  __int64 TotalFilesSize;
  __int64 TotalFilesCount;
  LONG_PTR Reserved;
};

typedef struct PackDefaultParamStruct {
  int   size;
  DWORD PluginInterfaceVersionLow;
  DWORD PluginInterfaceVersionHi;
  char  DefaultIniName[MAX_PATH];
};

#pragma pack(pop)


/* The functions of a plugin */
typedef BOOL (__stdcall *ArcInitPluginProcW)(_Inout_ ArcInitPluginDataW *pData);
typedef HANDLE (__stdcall *ArcOpenProcW)(_Inout_ ArcOpenDataW *ArchiveData);
typedef int (__stdcall *ArcParamToPlugProc)(_In_ LONG_PTR Session, _In_ HANDLE hArcData, _In_ int ParameterType, _In_ LONG_PTR ParameterData);
typedef int (__stdcall *ArcPackFilesProcW)(_In_ wchar_t *PackedFile, _In_ wchar_t *SubPath, _In_ wchar_t *SrcPath, _In_ wchar_t *AddList, _In_ int Flags, _In_ __int64 Size, _In_ LONG_PTR Session, _In_ ArcProcessDataProcW ProcessDataW, _In_ LONG_PTR Reserved);
typedef int (__stdcall *ArcDeleteFilesProcW)(_In_ wchar_t *PackedFile, _In_ wchar_t *DeleteList, _In_ LONG_PTR Session, _In_ ArcProcessDataProcW ProcessDataW, _In_ LONG_PTR Reserved);

typedef HANDLE (__stdcall *OpenArchiveProc)(_Inout_ tOpenArchiveData *ArchiveData);
typedef HANDLE (__stdcall *OpenArchiveProcW)(_Inout_ tOpenArchiveDataW *ArchiveData);
typedef int (__stdcall *ReadHeaderProc)(_In_ HANDLE hArcData, _Out_ tHeaderData *HeaderData);
typedef int (__stdcall *ReadHeaderExProc)(_In_ HANDLE hArcData, _Out_ tHeaderDataEx *HeaderDataEx);
typedef int (__stdcall *ReadHeaderExProcW)(_In_ HANDLE hArcData, _Out_ tHeaderDataExW *HeaderDataEx);
typedef int (__stdcall *ProcessFileProc)(_In_ HANDLE hArcData, _In_ int Operation, _In_opt_ char *DestPath, _In_opt_ char *DestName);
typedef int (__stdcall *ProcessFileProcW)(_In_ HANDLE hArcData, _In_ int Operation, _In_opt_ wchar_t *DestPath, _In_opt_ wchar_t *DestName);
typedef int (__stdcall *DeleteFilesProc)(_In_ char *PackedFile, _In_ char *DeleteList);
typedef int (__stdcall *DeleteFilesProcW)(_In_ wchar_t *PackedFile, _In_ wchar_t *DeleteList);
typedef int (__stdcall *CloseArchiveProc)(_In_ HANDLE hArcData);
typedef int (__stdcall *PackFilesProc)(_In_ char *PackedFile, _In_ char *SubPath, _In_ char *SrcPath, _In_ char *AddList, _In_ int Flags);
typedef int (__stdcall *PackFilesProcW)(_In_ wchar_t *PackedFile, _In_ wchar_t *SubPath, _In_ wchar_t *SrcPath, _In_ wchar_t *AddList, _In_ int Flags);
typedef int (__stdcall *GetPackerCapsProc)();
typedef void (__stdcall *SetProcessDataProcProc)(_In_ HANDLE hArcData, _In_ tProcessDataProc pProcessDataProc);
typedef void (__stdcall *SetProcessDataProcProcW)(_In_ HANDLE hArcData, _In_ tProcessDataProcW pProcessDataProc);
typedef void (__stdcall *SetChangeVolProcProc)(_In_ HANDLE hArcData, _In_ tChangeVolProc pChangeVolProc);
typedef void (__stdcall *SetChangeVolProcProcW)(_In_ HANDLE hArcData, _In_ tChangeVolProcW pChangeVolProc);
typedef void (__stdcall *ConfigurePackerProc)(_In_ HWND Parent, _In_ HINSTANCE DllInstance);
typedef HANDLE (__stdcall *StartMemPackProc)(_In_ int Options, _In_ char *FileName);
typedef HANDLE (__stdcall *StartMemPackProcW)(_In_ int Options, _In_ wchar_t *FileName);
typedef int (__stdcall *PackToMemProc)(_In_ int hMemPack, _In_ char *BufIn, _In_ int InLen, _Out_ int *Taken, _Out_ char *BufOut, _In_ int OutLen, _Out_ int *Written, _In_ int SeekBy);
typedef int (__stdcall *DoneMemPackProc)(_In_ int hMemPack);
typedef BOOL (__stdcall *CanYouHandleThisFileProc)(_In_ char *FileName);
typedef BOOL (__stdcall *CanYouHandleThisFileProcW)(_In_ wchar_t *FileName);
typedef void (__stdcall *PackSetDefaultParamsProc)(_In_ PackDefaultParamStruct* dps);
typedef void (__stdcall *PkSetCryptCallbackProc)(_In_ tPkCryptProc pPkCryptProc, _In_ int CryptoNr, _In_ int Flags);
typedef void (__stdcall *PkSetCryptCallbackProcW)(_In_ tPkCryptProcW pPkCryptProc, _In_ int CryptoNr, _In_ int Flags);
typedef int (__stdcall *GetBackgroundFlagsProc)();