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 
CArcExtInfoCArcExtInfo40   CArcExtInfo() {}
CArcExtInfoCArcExtInfo41   CArcExtInfo(const UString &ext): Ext(ext) {}
CArcExtInfoCArcExtInfo42   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 
Flags_KeepNameCArcInfoEx74   bool Flags_KeepName() const { return (Flags & NArcInfoFlags::kKeepName) != 0; }
Flags_FindSignatureCArcInfoEx75   bool Flags_FindSignature() const { return (Flags & NArcInfoFlags::kFindSignature) != 0; }
76 
Flags_AltStreamsCArcInfoEx77   bool Flags_AltStreams() const { return (Flags & NArcInfoFlags::kAltStreams) != 0; }
Flags_NtSecureCArcInfoEx78   bool Flags_NtSecure() const { return (Flags & NArcInfoFlags::kNtSecure) != 0; }
Flags_SymLinksCArcInfoEx79   bool Flags_SymLinks() const { return (Flags & NArcInfoFlags::kSymLinks) != 0; }
Flags_HardLinksCArcInfoEx80   bool Flags_HardLinks() const { return (Flags & NArcInfoFlags::kHardLinks) != 0; }
81 
Flags_UseGlobalOffsetCArcInfoEx82   bool Flags_UseGlobalOffset() const { return (Flags & NArcInfoFlags::kUseGlobalOffset) != 0; }
Flags_StartOpenCArcInfoEx83   bool Flags_StartOpen() const { return (Flags & NArcInfoFlags::kStartOpen) != 0; }
Flags_BackwardOpenCArcInfoEx84   bool Flags_BackwardOpen() const { return (Flags & NArcInfoFlags::kBackwardOpen) != 0; }
Flags_PreArcCArcInfoEx85   bool Flags_PreArc() const { return (Flags & NArcInfoFlags::kPreArc) != 0; }
Flags_PureStartOpenCArcInfoEx86   bool Flags_PureStartOpen() const { return (Flags & NArcInfoFlags::kPureStartOpen) != 0; }
87 
GetMainExtCArcInfoEx88   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 
IsSplitCArcInfoEx112   bool IsSplit() const { return StringsAreEqualNoCase_Ascii(Name, "Split"); }
113   // bool IsRar() const { return StringsAreEqualNoCase_Ascii(Name, "Rar"); }
114 
CArcInfoExCArcInfoEx115   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
LoadIconsCCodecLib160   void LoadIcons() { CCodecIcons::LoadIcons((HMODULE)Lib); }
161   #endif
162 
CCodecLibCCodecLib163   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 
CreateArchiveHandler(const CArcInfoEx & ai,void ** archive,bool outHandler)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 
CCodecs()202   CCodecs(): CaseSensitiveChange(false), CaseSensitive(false) {}
203 
GetFormatNamePtr(int formatIndex)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 
CreateInArchive(unsigned formatIndex,CMyComPtr<IInArchive> & archive)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 
CreateOutArchive(unsigned formatIndex,CMyComPtr<IOutArchive> & archive)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 
FindOutFormatFromName(const UString & name)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