Home | History | Annotate | Download | only in Common
      1 // LoadCodecs.h
      2 
      3 #ifndef __LOAD_CODECS_H
      4 #define __LOAD_CODECS_H
      5 
      6 #include "../../../Common/MyBuffer.h"
      7 #include "../../../Common/MyCom.h"
      8 #include "../../../Common/MyString.h"
      9 #include "../../../Common/ComTry.h"
     10 
     11 #include "../../ICoder.h"
     12 
     13 #ifdef EXTERNAL_CODECS
     14 #include "../../../Windows/DLL.h"
     15 #endif
     16 
     17 struct CDllCodecInfo
     18 {
     19   CLSID Encoder;
     20   CLSID Decoder;
     21   bool EncoderIsAssigned;
     22   bool DecoderIsAssigned;
     23   int LibIndex;
     24   UInt32 CodecIndex;
     25 };
     26 
     27 struct CDllHasherInfo
     28 {
     29   int LibIndex;
     30   UInt32 HasherIndex;
     31 };
     32 
     33 #include "../../Archive/IArchive.h"
     34 
     35 struct CArcExtInfo
     36 {
     37   UString Ext;
     38   UString AddExt;
     39 
     40   CArcExtInfo() {}
     41   CArcExtInfo(const UString &ext): Ext(ext) {}
     42   CArcExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {}
     43 };
     44 
     45 
     46 struct CArcInfoEx
     47 {
     48   UInt32 Flags;
     49 
     50   Func_CreateInArchive CreateInArchive;
     51   Func_IsArc IsArcFunc;
     52 
     53   UString Name;
     54   CObjectVector<CArcExtInfo> Exts;
     55 
     56   #ifndef _SFX
     57     Func_CreateOutArchive CreateOutArchive;
     58     bool UpdateEnabled;
     59     bool NewInterface;
     60     // UInt32 Version;
     61     UInt32 SignatureOffset;
     62     CObjectVector<CByteBuffer> Signatures;
     63     #ifdef NEW_FOLDER_INTERFACE
     64       UStringVector AssociateExts;
     65     #endif
     66   #endif
     67 
     68   #ifdef EXTERNAL_CODECS
     69     int LibIndex;
     70     UInt32 FormatIndex;
     71     CLSID ClassID;
     72   #endif
     73 
     74   bool Flags_KeepName() const { return (Flags & NArcInfoFlags::kKeepName) != 0; }
     75   bool Flags_FindSignature() const { return (Flags & NArcInfoFlags::kFindSignature) != 0; }
     76 
     77   bool Flags_AltStreams() const { return (Flags & NArcInfoFlags::kAltStreams) != 0; }
     78   bool Flags_NtSecure() const { return (Flags & NArcInfoFlags::kNtSecure) != 0; }
     79   bool Flags_SymLinks() const { return (Flags & NArcInfoFlags::kSymLinks) != 0; }
     80   bool Flags_HardLinks() const { return (Flags & NArcInfoFlags::kHardLinks) != 0; }
     81 
     82   bool Flags_UseGlobalOffset() const { return (Flags & NArcInfoFlags::kUseGlobalOffset) != 0; }
     83   bool Flags_StartOpen() const { return (Flags & NArcInfoFlags::kStartOpen) != 0; }
     84   bool Flags_BackwardOpen() const { return (Flags & NArcInfoFlags::kBackwardOpen) != 0; }
     85   bool Flags_PreArc() const { return (Flags & NArcInfoFlags::kPreArc) != 0; }
     86   bool Flags_PureStartOpen() const { return (Flags & NArcInfoFlags::kPureStartOpen) != 0; }
     87 
     88   UString GetMainExt() const
     89   {
     90     if (Exts.IsEmpty())
     91       return UString();
     92     return Exts[0].Ext;
     93   }
     94   int FindExtension(const UString &ext) const;
     95 
     96   /*
     97   UString GetAllExtensions() const
     98   {
     99     UString s;
    100     for (int i = 0; i < Exts.Size(); i++)
    101     {
    102       if (i > 0)
    103         s += ' ';
    104       s += Exts[i].Ext;
    105     }
    106     return s;
    107   }
    108   */
    109 
    110   void AddExts(const UString &ext, const UString &addExt);
    111 
    112   bool IsSplit() const { return StringsAreEqualNoCase_Ascii(Name, "Split"); }
    113   // bool IsRar() const { return StringsAreEqualNoCase_Ascii(Name, "Rar"); }
    114 
    115   CArcInfoEx():
    116       Flags(0),
    117       CreateInArchive(NULL),
    118       IsArcFunc(NULL)
    119       #ifndef _SFX
    120       , CreateOutArchive(NULL)
    121       , UpdateEnabled(false)
    122       , NewInterface(false)
    123       // , Version(0)
    124       , SignatureOffset(0)
    125       #endif
    126       #ifdef EXTERNAL_CODECS
    127       , LibIndex(-1)
    128       #endif
    129   {}
    130 };
    131 
    132 #ifdef EXTERNAL_CODECS
    133 
    134 #ifdef NEW_FOLDER_INTERFACE
    135 struct CCodecIcons
    136 {
    137   struct CIconPair
    138   {
    139     UString Ext;
    140     int IconIndex;
    141   };
    142   CObjectVector<CIconPair> IconPairs;
    143   void LoadIcons(HMODULE m);
    144   bool FindIconIndex(const UString &ext, int &iconIndex) const;
    145 };
    146 #endif
    147 
    148 struct CCodecLib
    149   #ifdef NEW_FOLDER_INTERFACE
    150     : public CCodecIcons
    151   #endif
    152 {
    153   NWindows::NDLL::CLibrary Lib;
    154   FString Path;
    155   Func_GetMethodProperty GetMethodProperty;
    156   Func_CreateObject CreateObject;
    157   CMyComPtr<IHashers> Hashers;
    158 
    159   #ifdef NEW_FOLDER_INTERFACE
    160   void LoadIcons() { CCodecIcons::LoadIcons((HMODULE)Lib); }
    161   #endif
    162 
    163   CCodecLib(): GetMethodProperty(NULL) {}
    164 };
    165 #endif
    166 
    167 class CCodecs:
    168   #ifdef EXTERNAL_CODECS
    169   public ICompressCodecsInfo,
    170   public IHashers,
    171   #else
    172   public IUnknown,
    173   #endif
    174   public CMyUnknownImp
    175 {
    176 public:
    177   #ifdef EXTERNAL_CODECS
    178   CObjectVector<CCodecLib> Libs;
    179   CRecordVector<CDllCodecInfo> Codecs;
    180   CRecordVector<CDllHasherInfo> Hashers;
    181 
    182   #ifdef NEW_FOLDER_INTERFACE
    183   CCodecIcons InternalIcons;
    184   #endif
    185 
    186   HRESULT LoadCodecs();
    187   HRESULT LoadFormats();
    188   HRESULT LoadDll(const FString &path, bool needCheckDll);
    189   HRESULT LoadDllsFromFolder(const FString &folderPrefix);
    190 
    191   HRESULT CreateArchiveHandler(const CArcInfoEx &ai, void **archive, bool outHandler) const
    192   {
    193     return Libs[ai.LibIndex].CreateObject(&ai.ClassID, outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive);
    194   }
    195   #endif
    196 
    197 public:
    198   CObjectVector<CArcInfoEx> Formats;
    199   bool CaseSensitiveChange;
    200   bool CaseSensitive;
    201 
    202   CCodecs(): CaseSensitiveChange(false), CaseSensitive(false) {}
    203 
    204   const wchar_t *GetFormatNamePtr(int formatIndex)
    205   {
    206     return formatIndex < 0 ? L"#" : (const wchar_t *)Formats[formatIndex].Name;
    207   }
    208 
    209   HRESULT Load();
    210 
    211   #ifndef _SFX
    212   int FindFormatForArchiveName(const UString &arcPath) const;
    213   int FindFormatForExtension(const UString &ext) const;
    214   int FindFormatForArchiveType(const UString &arcType) const;
    215   bool FindFormatForArchiveType(const UString &arcType, CIntVector &formatIndices) const;
    216   #endif
    217 
    218   #ifdef EXTERNAL_CODECS
    219 
    220   MY_UNKNOWN_IMP2(ICompressCodecsInfo, IHashers)
    221 
    222   STDMETHOD(GetNumberOfMethods)(UInt32 *numMethods);
    223   STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
    224   STDMETHOD(CreateDecoder)(UInt32 index, const GUID *interfaceID, void **coder);
    225   STDMETHOD(CreateEncoder)(UInt32 index, const GUID *interfaceID, void **coder);
    226 
    227   STDMETHOD_(UInt32, GetNumHashers)();
    228   STDMETHOD(GetHasherProp)(UInt32 index, PROPID propID, PROPVARIANT *value);
    229   STDMETHOD(CreateHasher)(UInt32 index, IHasher **hasher);
    230 
    231   #else
    232 
    233   MY_UNKNOWN_IMP
    234 
    235   #endif // EXTERNAL_CODECS
    236 
    237   #ifdef EXTERNAL_CODECS
    238 
    239   int GetCodecLibIndex(UInt32 index);
    240   bool GetCodecEncoderIsAssigned(UInt32 index);
    241   HRESULT GetCodecId(UInt32 index, UInt64 &id);
    242   UString GetCodecName(UInt32 index);
    243 
    244   int GetHasherLibIndex(UInt32 index);
    245   UInt64 GetHasherId(UInt32 index);
    246   UString GetHasherName(UInt32 index);
    247   UInt32 GetHasherDigestSize(UInt32 index);
    248 
    249   #endif
    250 
    251   HRESULT CreateInArchive(unsigned formatIndex, CMyComPtr<IInArchive> &archive) const
    252   {
    253     const CArcInfoEx &ai = Formats[formatIndex];
    254     #ifdef EXTERNAL_CODECS
    255     if (ai.LibIndex < 0)
    256     #endif
    257     {
    258       COM_TRY_BEGIN
    259       archive = ai.CreateInArchive();
    260       return S_OK;
    261       COM_TRY_END
    262     }
    263     #ifdef EXTERNAL_CODECS
    264     return CreateArchiveHandler(ai, (void **)&archive, false);
    265     #endif
    266   }
    267 
    268   #ifndef _SFX
    269 
    270   HRESULT CreateOutArchive(unsigned formatIndex, CMyComPtr<IOutArchive> &archive) const
    271   {
    272     const CArcInfoEx &ai = Formats[formatIndex];
    273     #ifdef EXTERNAL_CODECS
    274     if (ai.LibIndex < 0)
    275     #endif
    276     {
    277       COM_TRY_BEGIN
    278       archive = ai.CreateOutArchive();
    279       return S_OK;
    280       COM_TRY_END
    281     }
    282     #ifdef EXTERNAL_CODECS
    283     return CreateArchiveHandler(ai, (void **)&archive, true);
    284     #endif
    285   }
    286 
    287   int FindOutFormatFromName(const UString &name) const
    288   {
    289     FOR_VECTOR (i, Formats)
    290     {
    291       const CArcInfoEx &arc = Formats[i];
    292       if (!arc.UpdateEnabled)
    293         continue;
    294       if (arc.Name.IsEqualToNoCase(name))
    295         return i;
    296     }
    297     return -1;
    298   }
    299 
    300   #endif // _SFX
    301 };
    302 
    303 #endif
    304