1 // LoadCodecs.h
2 
3 #ifndef __LOADCODECS_H
4 #define __LOADCODECS_H
5 
6 #include "../../../Common/Types.h"
7 #include "../../../Common/MyCom.h"
8 #include "../../../Common/MyString.h"
9 #include "../../../Common/Buffer.h"
10 #include "../../ICoder.h"
11 
12 #ifdef EXTERNAL_CODECS
13 #include "../../../Windows/DLL.h"
14 #endif
15 
16 struct CDllCodecInfo
17 {
18   CLSID Encoder;
19   CLSID Decoder;
20   bool EncoderIsAssigned;
21   bool DecoderIsAssigned;
22   int LibIndex;
23   UInt32 CodecIndex;
24 };
25 
26 #include "../../Archive/IArchive.h"
27 
28 typedef IInArchive * (*CreateInArchiveP)();
29 typedef IOutArchive * (*CreateOutArchiveP)();
30 
31 struct CArcExtInfo
32 {
33   UString Ext;
34   UString AddExt;
CArcExtInfoCArcExtInfo35   CArcExtInfo() {}
CArcExtInfoCArcExtInfo36   CArcExtInfo(const UString &ext): Ext(ext) {}
CArcExtInfoCArcExtInfo37   CArcExtInfo(const UString &ext, const UString &addExt): Ext(ext), AddExt(addExt) {}
38 };
39 
40 
41 struct CArcInfoEx
42 {
43   #ifdef EXTERNAL_CODECS
44   int LibIndex;
45   UInt32 FormatIndex;
46   CLSID ClassID;
47   #endif
48   bool UpdateEnabled;
49   CreateInArchiveP CreateInArchive;
50   CreateOutArchiveP CreateOutArchive;
51   UString Name;
52   CObjectVector<CArcExtInfo> Exts;
53   #ifndef _SFX
54   CByteBuffer StartSignature;
55   // CByteBuffer FinishSignature;
56   #ifdef NEW_FOLDER_INTERFACE
57   UStringVector AssociateExts;
58   #endif
59   #endif
60   bool KeepName;
GetMainExtCArcInfoEx61   UString GetMainExt() const
62   {
63     if (Exts.IsEmpty())
64       return UString();
65     return Exts[0].Ext;
66   }
FindExtensionCArcInfoEx67   int FindExtension(const UString &ext) const
68   {
69     for (int i = 0; i < Exts.Size(); i++)
70       if (ext.CompareNoCase(Exts[i].Ext) == 0)
71         return i;
72     return -1;
73   }
GetAllExtensionsCArcInfoEx74   UString GetAllExtensions() const
75   {
76     UString s;
77     for (int i = 0; i < Exts.Size(); i++)
78     {
79       if (i > 0)
80         s += ' ';
81       s += Exts[i].Ext;
82     }
83     return s;
84   }
85 
86   void AddExts(const wchar_t* ext, const wchar_t* addExt);
87 
CArcInfoExCArcInfoEx88   CArcInfoEx():
89     #ifdef EXTERNAL_CODECS
90     LibIndex(-1),
91     #endif
92     UpdateEnabled(false),
93     CreateInArchive(0), CreateOutArchive(0),
94     KeepName(false)
95     #ifndef _SFX
96     #endif
97   {}
98 };
99 
100 #ifdef EXTERNAL_CODECS
101 typedef UInt32 (WINAPI *GetMethodPropertyFunc)(UInt32 index, PROPID propID, PROPVARIANT *value);
102 typedef UInt32 (WINAPI *CreateObjectFunc)(const GUID *clsID, const GUID *interfaceID, void **outObject);
103 
104 
105 #ifdef NEW_FOLDER_INTERFACE
106 struct CCodecIcons
107 {
108   struct CIconPair
109   {
110     UString Ext;
111     int IconIndex;
112   };
113   CObjectVector<CIconPair> IconPairs;
114   void LoadIcons(HMODULE m);
115   bool FindIconIndex(const UString &ext, int &iconIndex) const;
116 };
117 #endif
118 
119 struct CCodecLib
120 #ifdef NEW_FOLDER_INTERFACE
121 : public CCodecIcons
122 #endif
123 {
124   NWindows::NDLL::CLibrary Lib;
125   GetMethodPropertyFunc GetMethodProperty;
126   CreateObjectFunc CreateObject;
127   #ifdef NEW_FOLDER_INTERFACE
128   CSysString Path;
LoadIconsCCodecLib129   void LoadIcons() { CCodecIcons::LoadIcons((HMODULE)Lib); }
130   #endif
CCodecLibCCodecLib131   CCodecLib(): GetMethodProperty(0) {}
132 };
133 #endif
134 
135 class CCodecs:
136   #ifdef EXTERNAL_CODECS
137   public ICompressCodecsInfo,
138   #else
139   public IUnknown,
140   #endif
141   public CMyUnknownImp
142 {
143 public:
144   #ifdef EXTERNAL_CODECS
145   CObjectVector<CCodecLib> Libs;
146   CObjectVector<CDllCodecInfo> Codecs;
147 
148   #ifdef NEW_FOLDER_INTERFACE
149   CCodecIcons InternalIcons;
150   #endif
151 
152   HRESULT LoadCodecs();
153   HRESULT LoadFormats();
154   HRESULT LoadDll(const CSysString &path, bool needCheckDll);
155   HRESULT LoadDllsFromFolder(const CSysString &folderPrefix);
156 
CreateArchiveHandler(const CArcInfoEx & ai,void ** archive,bool outHandler)157   HRESULT CreateArchiveHandler(const CArcInfoEx &ai, void **archive, bool outHandler) const
158   {
159     return Libs[ai.LibIndex].CreateObject(&ai.ClassID, outHandler ? &IID_IOutArchive : &IID_IInArchive, (void **)archive);
160   }
161   #endif
162 
163 public:
164   CObjectVector<CArcInfoEx> Formats;
165   HRESULT Load();
166 
167   #ifndef _SFX
168   int FindFormatForArchiveName(const UString &arcPath) const;
169   int FindFormatForExtension(const UString &ext) const;
170   int FindFormatForArchiveType(const UString &arcType) const;
171   bool FindFormatForArchiveType(const UString &arcType, CIntVector &formatIndices) const;
172   #endif
173 
174   MY_UNKNOWN_IMP
175 
176   #ifdef EXTERNAL_CODECS
177   STDMETHOD(GetNumberOfMethods)(UInt32 *numMethods);
178   STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
179   STDMETHOD(CreateDecoder)(UInt32 index, const GUID *interfaceID, void **coder);
180   STDMETHOD(CreateEncoder)(UInt32 index, const GUID *interfaceID, void **coder);
181   #endif
182 
183   int GetCodecLibIndex(UInt32 index);
184   bool GetCodecEncoderIsAssigned(UInt32 index);
185   HRESULT GetCodecId(UInt32 index, UInt64 &id);
186   UString GetCodecName(UInt32 index);
187 
CreateInArchive(int formatIndex,CMyComPtr<IInArchive> & archive)188   HRESULT CreateInArchive(int formatIndex, CMyComPtr<IInArchive> &archive) const
189   {
190     const CArcInfoEx &ai = Formats[formatIndex];
191     #ifdef EXTERNAL_CODECS
192     if (ai.LibIndex < 0)
193     #endif
194     {
195       archive = ai.CreateInArchive();
196       return S_OK;
197     }
198     #ifdef EXTERNAL_CODECS
199     return CreateArchiveHandler(ai, (void **)&archive, false);
200     #endif
201   }
CreateOutArchive(int formatIndex,CMyComPtr<IOutArchive> & archive)202   HRESULT CreateOutArchive(int formatIndex, CMyComPtr<IOutArchive> &archive) const
203   {
204     const CArcInfoEx &ai = Formats[formatIndex];
205     #ifdef EXTERNAL_CODECS
206     if (ai.LibIndex < 0)
207     #endif
208     {
209       archive = ai.CreateOutArchive();
210       return S_OK;
211     }
212     #ifdef EXTERNAL_CODECS
213     return CreateArchiveHandler(ai, (void **)&archive, true);
214     #endif
215   }
FindOutFormatFromName(const UString & name)216   int FindOutFormatFromName(const UString &name) const
217   {
218     for (int i = 0; i < Formats.Size(); i++)
219     {
220       const CArcInfoEx &arc = Formats[i];
221       if (!arc.UpdateEnabled)
222         continue;
223       if (arc.Name.CompareNoCase(name) == 0)
224         return i;
225     }
226     return -1;
227   }
228 
229   #ifdef EXTERNAL_CODECS
230   HRESULT CreateCoder(const UString &name, bool encode, CMyComPtr<ICompressCoder> &coder) const;
231   #endif
232 
233 };
234 
235 #endif
236