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
17struct CDllCodecInfo
18{
19  CLSID Encoder;
20  CLSID Decoder;
21  bool EncoderIsAssigned;
22  bool DecoderIsAssigned;
23  int LibIndex;
24  UInt32 CodecIndex;
25};
26
27struct CDllHasherInfo
28{
29  int LibIndex;
30  UInt32 HasherIndex;
31};
32
33#include "../../Archive/IArchive.h"
34
35struct 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
46struct 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
135struct 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
148struct 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
167class CCodecs:
168  #ifdef EXTERNAL_CODECS
169  public ICompressCodecsInfo,
170  public IHashers,
171  #else
172  public IUnknown,
173  #endif
174  public CMyUnknownImp
175{
176public:
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
197public:
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