tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

LoadCodecs.h (11166B)


      1 // LoadCodecs.h
      2 
      3 #ifndef __LOAD_CODECS_H
      4 #define __LOAD_CODECS_H
      5 
      6 /*
      7 Client application uses LoadCodecs.* to load plugins to
      8 CCodecs object, that contains 3 lists of plugins:
      9  1) Formats - internal and external archive handlers
     10  2) Codecs  - external codecs
     11  3) Hashers - external hashers
     12 
     13 EXTERNAL_CODECS
     14 ---------------
     15 
     16  if EXTERNAL_CODECS is defined, then the code tries to load external
     17  plugins from DLL files (shared libraries).
     18 
     19  There are two types of executables in 7-Zip:
     20  
     21  1) Executable that uses external plugins must be compiled
     22     with EXTERNAL_CODECS defined:
     23       - 7z.exe, 7zG.exe, 7zFM.exe
     24    
     25     Note: EXTERNAL_CODECS is used also in CPP/7zip/Common/CreateCoder.h
     26           that code is used in plugin module (7z.dll).
     27  
     28  2) Standalone modules are compiled without EXTERNAL_CODECS:
     29    - SFX modules: 7z.sfx, 7zCon.sfx
     30    - standalone versions of console 7-Zip: 7za.exe, 7zr.exe
     31 
     32  if EXTERNAL_CODECS is defined, CCodecs class implements interfaces:
     33    - ICompressCodecsInfo : for Codecs
     34    - IHashers            : for Hashers
     35  
     36  The client application can send CCodecs object to each plugin module.
     37  And plugin module can use ICompressCodecsInfo or IHashers interface to access
     38  another plugins.
     39 
     40  There are 2 ways to send (ICompressCodecsInfo * compressCodecsInfo) to plugin
     41    1) for old versions:
     42        a) request ISetCompressCodecsInfo from created archive handler.
     43        b) call ISetCompressCodecsInfo::SetCompressCodecsInfo(compressCodecsInfo)
     44    2) for new versions:
     45        a) request "SetCodecs" function from DLL file
     46        b) call SetCodecs(compressCodecsInfo) function from DLL file
     47 */
     48 
     49 #include "../../../Common/MyBuffer.h"
     50 #include "../../../Common/MyCom.h"
     51 #include "../../../Common/MyString.h"
     52 #include "../../../Common/ComTry.h"
     53 
     54 #ifdef EXTERNAL_CODECS
     55 #include "../../../Windows/DLL.h"
     56 #endif
     57 
     58 #include "../../ICoder.h"
     59 
     60 #include "../../Archive/IArchive.h"
     61 
     62 
     63 #ifdef EXTERNAL_CODECS
     64 
     65 struct CDllCodecInfo
     66 {
     67  unsigned LibIndex;
     68  UInt32 CodecIndex;
     69  bool EncoderIsAssigned;
     70  bool DecoderIsAssigned;
     71  CLSID Encoder;
     72  CLSID Decoder;
     73 };
     74 
     75 struct CDllHasherInfo
     76 {
     77  unsigned LibIndex;
     78  UInt32 HasherIndex;
     79 };
     80 
     81 #endif
     82 
     83 struct CArcExtInfo
     84 {
     85  UString Ext;
     86  UString AddExt;
     87  
     88  CArcExtInfo() {}
     89  CArcExtInfo(const UString &ext): Ext(ext) {}
     90  CArcExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {}
     91 };
     92 
     93 
     94 struct CArcInfoEx
     95 {
     96  UInt32 Flags;
     97  
     98  Func_CreateInArchive CreateInArchive;
     99  Func_IsArc IsArcFunc;
    100 
    101  UString Name;
    102  CObjectVector<CArcExtInfo> Exts;
    103  
    104  #ifndef _SFX
    105    Func_CreateOutArchive CreateOutArchive;
    106    bool UpdateEnabled;
    107    bool NewInterface;
    108    // UInt32 Version;
    109    UInt32 SignatureOffset;
    110    CObjectVector<CByteBuffer> Signatures;
    111    #ifdef NEW_FOLDER_INTERFACE
    112      UStringVector AssociateExts;
    113    #endif
    114  #endif
    115  
    116  #ifdef EXTERNAL_CODECS
    117    int LibIndex;
    118    UInt32 FormatIndex;
    119    CLSID ClassID;
    120  #endif
    121 
    122  bool Flags_KeepName() const { return (Flags & NArcInfoFlags::kKeepName) != 0; }
    123  bool Flags_FindSignature() const { return (Flags & NArcInfoFlags::kFindSignature) != 0; }
    124 
    125  bool Flags_AltStreams() const { return (Flags & NArcInfoFlags::kAltStreams) != 0; }
    126  bool Flags_NtSecure() const { return (Flags & NArcInfoFlags::kNtSecure) != 0; }
    127  bool Flags_SymLinks() const { return (Flags & NArcInfoFlags::kSymLinks) != 0; }
    128  bool Flags_HardLinks() const { return (Flags & NArcInfoFlags::kHardLinks) != 0; }
    129 
    130  bool Flags_UseGlobalOffset() const { return (Flags & NArcInfoFlags::kUseGlobalOffset) != 0; }
    131  bool Flags_StartOpen() const { return (Flags & NArcInfoFlags::kStartOpen) != 0; }
    132  bool Flags_BackwardOpen() const { return (Flags & NArcInfoFlags::kBackwardOpen) != 0; }
    133  bool Flags_PreArc() const { return (Flags & NArcInfoFlags::kPreArc) != 0; }
    134  bool Flags_PureStartOpen() const { return (Flags & NArcInfoFlags::kPureStartOpen) != 0; }
    135  
    136  UString GetMainExt() const
    137  {
    138    if (Exts.IsEmpty())
    139      return UString();
    140    return Exts[0].Ext;
    141  }
    142  int FindExtension(const UString &ext) const;
    143  
    144  /*
    145  UString GetAllExtensions() const
    146  {
    147    UString s;
    148    for (int i = 0; i < Exts.Size(); i++)
    149    {
    150      if (i > 0)
    151        s += ' ';
    152      s += Exts[i].Ext;
    153    }
    154    return s;
    155  }
    156  */
    157 
    158  void AddExts(const UString &ext, const UString &addExt);
    159 
    160  bool IsSplit() const { return StringsAreEqualNoCase_Ascii(Name, "Split"); }
    161  // bool IsRar() const { return StringsAreEqualNoCase_Ascii(Name, "Rar"); }
    162 
    163  CArcInfoEx():
    164      Flags(0),
    165      CreateInArchive(NULL),
    166      IsArcFunc(NULL)
    167      #ifndef _SFX
    168      , CreateOutArchive(NULL)
    169      , UpdateEnabled(false)
    170      , NewInterface(false)
    171      // , Version(0)
    172      , SignatureOffset(0)
    173      #endif
    174      #ifdef EXTERNAL_CODECS
    175      , LibIndex(-1)
    176      #endif
    177  {}
    178 };
    179 
    180 #ifdef NEW_FOLDER_INTERFACE
    181 
    182 struct CCodecIcons
    183 {
    184  struct CIconPair
    185  {
    186    UString Ext;
    187    int IconIndex;
    188  };
    189  CObjectVector<CIconPair> IconPairs;
    190 
    191  void LoadIcons(HMODULE m);
    192  bool FindIconIndex(const UString &ext, int &iconIndex) const;
    193 };
    194 
    195 #endif
    196 
    197 #ifdef EXTERNAL_CODECS
    198 
    199 struct CCodecLib
    200  #ifdef NEW_FOLDER_INTERFACE
    201    : public CCodecIcons
    202  #endif
    203 {
    204  NWindows::NDLL::CLibrary Lib;
    205  FString Path;
    206  
    207  Func_CreateObject CreateObject;
    208  Func_GetMethodProperty GetMethodProperty;
    209  Func_CreateDecoder CreateDecoder;
    210  Func_CreateEncoder CreateEncoder;
    211  Func_SetCodecs SetCodecs;
    212 
    213  CMyComPtr<IHashers> ComHashers;
    214  
    215  #ifdef NEW_FOLDER_INTERFACE
    216  void LoadIcons() { CCodecIcons::LoadIcons((HMODULE)Lib); }
    217  #endif
    218  
    219  CCodecLib():
    220      CreateObject(NULL),
    221      GetMethodProperty(NULL),
    222      CreateDecoder(NULL),
    223      CreateEncoder(NULL),
    224      SetCodecs(NULL)
    225      {}
    226 };
    227 
    228 #endif
    229 
    230 
    231 class CCodecs:
    232  #ifdef EXTERNAL_CODECS
    233    public ICompressCodecsInfo,
    234    public IHashers,
    235  #else
    236    public IUnknown,
    237  #endif
    238  public CMyUnknownImp
    239 {
    240  CLASS_NO_COPY(CCodecs);
    241 public:
    242  #ifdef EXTERNAL_CODECS
    243  
    244  CObjectVector<CCodecLib> Libs;
    245  FString MainDll_ErrorPath;
    246 
    247  void CloseLibs();
    248 
    249  class CReleaser
    250  {
    251    CLASS_NO_COPY(CReleaser);
    252 
    253    /* CCodecsReleaser object releases CCodecs links.
    254         1) CCodecs is COM object that is deleted when all links to that object will be released/
    255         2) CCodecs::Libs[i] can hold (ICompressCodecsInfo *) link to CCodecs object itself.
    256       To break that reference loop, we must close all CCodecs::Libs in CCodecsReleaser desttructor. */
    257 
    258    CCodecs *_codecs;
    259      
    260    public:
    261    CReleaser(): _codecs(NULL) {}
    262    void Set(CCodecs *codecs) { _codecs = codecs; }
    263    ~CReleaser() { if (_codecs) _codecs->CloseLibs(); }
    264  };
    265 
    266  bool NeedSetLibCodecs; // = false, if we don't need to set codecs for archive handler via ISetCompressCodecsInfo
    267 
    268  HRESULT LoadCodecs();
    269  HRESULT LoadFormats();
    270  HRESULT LoadDll(const FString &path, bool needCheckDll, bool *loadedOK = NULL);
    271  HRESULT LoadDllsFromFolder(const FString &folderPrefix);
    272 
    273  HRESULT CreateArchiveHandler(const CArcInfoEx &ai, bool outHandler, void **archive) const
    274  {
    275    return Libs[ai.LibIndex].CreateObject(&ai.ClassID, outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive);
    276  }
    277  
    278  #endif
    279 
    280  #ifdef NEW_FOLDER_INTERFACE
    281  CCodecIcons InternalIcons;
    282  #endif
    283 
    284  CObjectVector<CArcInfoEx> Formats;
    285  
    286  #ifdef EXTERNAL_CODECS
    287  CRecordVector<CDllCodecInfo> Codecs;
    288  CRecordVector<CDllHasherInfo> Hashers;
    289  #endif
    290 
    291  bool CaseSensitiveChange;
    292  bool CaseSensitive;
    293 
    294  CCodecs():
    295      #ifdef EXTERNAL_CODECS
    296      NeedSetLibCodecs(true),
    297      #endif
    298      CaseSensitiveChange(false),
    299      CaseSensitive(false)
    300      {}
    301 
    302  ~CCodecs()
    303  {
    304    // OutputDebugStringA("~CCodecs");
    305  }
    306 
    307  const wchar_t *GetFormatNamePtr(int formatIndex) const
    308  {
    309    return formatIndex < 0 ? L"#" : (const wchar_t *)Formats[formatIndex].Name;
    310  }
    311 
    312  HRESULT Load();
    313  
    314  #ifndef _SFX
    315  int FindFormatForArchiveName(const UString &arcPath) const;
    316  int FindFormatForExtension(const UString &ext) const;
    317  int FindFormatForArchiveType(const UString &arcType) const;
    318  bool FindFormatForArchiveType(const UString &arcType, CIntVector &formatIndices) const;
    319  #endif
    320 
    321  #ifdef EXTERNAL_CODECS
    322 
    323  MY_UNKNOWN_IMP2(ICompressCodecsInfo, IHashers)
    324    
    325  STDMETHOD(GetNumMethods)(UInt32 *numMethods);
    326  STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
    327  STDMETHOD(CreateDecoder)(UInt32 index, const GUID *iid, void **coder);
    328  STDMETHOD(CreateEncoder)(UInt32 index, const GUID *iid, void **coder);
    329 
    330  STDMETHOD_(UInt32, GetNumHashers)();
    331  STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value);
    332  STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher);
    333 
    334  #else
    335 
    336  MY_UNKNOWN_IMP
    337 
    338  #endif // EXTERNAL_CODECS
    339 
    340  
    341  #ifdef EXTERNAL_CODECS
    342 
    343  int GetCodec_LibIndex(UInt32 index) const;
    344  bool GetCodec_DecoderIsAssigned(UInt32 index) const;
    345  bool GetCodec_EncoderIsAssigned(UInt32 index) const;
    346  UInt32 GetCodec_NumStreams(UInt32 index);
    347  HRESULT GetCodec_Id(UInt32 index, UInt64 &id);
    348  AString GetCodec_Name(UInt32 index);
    349 
    350  int GetHasherLibIndex(UInt32 index);
    351  UInt64 GetHasherId(UInt32 index);
    352  AString GetHasherName(UInt32 index);
    353  UInt32 GetHasherDigestSize(UInt32 index);
    354 
    355  #endif
    356 
    357  HRESULT CreateInArchive(unsigned formatIndex, CMyComPtr<IInArchive> &archive) const
    358  {
    359    const CArcInfoEx &ai = Formats[formatIndex];
    360    #ifdef EXTERNAL_CODECS
    361    if (ai.LibIndex < 0)
    362    #endif
    363    {
    364      COM_TRY_BEGIN
    365      archive = ai.CreateInArchive();
    366      return S_OK;
    367      COM_TRY_END
    368    }
    369    #ifdef EXTERNAL_CODECS
    370    return CreateArchiveHandler(ai, false, (void **)&archive);
    371    #endif
    372  }
    373  
    374  #ifndef _SFX
    375 
    376  HRESULT CreateOutArchive(unsigned formatIndex, CMyComPtr<IOutArchive> &archive) const
    377  {
    378    const CArcInfoEx &ai = Formats[formatIndex];
    379    #ifdef EXTERNAL_CODECS
    380    if (ai.LibIndex < 0)
    381    #endif
    382    {
    383      COM_TRY_BEGIN
    384      archive = ai.CreateOutArchive();
    385      return S_OK;
    386      COM_TRY_END
    387    }
    388    
    389    #ifdef EXTERNAL_CODECS
    390    return CreateArchiveHandler(ai, true, (void **)&archive);
    391    #endif
    392  }
    393  
    394  int FindOutFormatFromName(const UString &name) const
    395  {
    396    FOR_VECTOR (i, Formats)
    397    {
    398      const CArcInfoEx &arc = Formats[i];
    399      if (!arc.UpdateEnabled)
    400        continue;
    401      if (arc.Name.IsEqualTo_NoCase(name))
    402        return i;
    403    }
    404    return -1;
    405  }
    406 
    407  #endif // _SFX
    408 };
    409 
    410 #ifdef EXTERNAL_CODECS
    411  #define CREATE_CODECS_OBJECT \
    412    CCodecs *codecs = new CCodecs; \
    413    CExternalCodecs __externalCodecs; \
    414    __externalCodecs.GetCodecs = codecs; \
    415    __externalCodecs.GetHashers = codecs; \
    416    CCodecs::CReleaser codecsReleaser; \
    417    codecsReleaser.Set(codecs);
    418 #else
    419  #define CREATE_CODECS_OBJECT \
    420    CCodecs *codecs = new CCodecs; \
    421    CMyComPtr<IUnknown> __codecsRef = codecs;
    422 #endif
    423  
    424 #endif