other-licenses/7zstub/src/7zip/UI/Common/ArchiverInfo.cpp

branch
TOR_BUG_9701
changeset 14
925c144e1f1f
equal deleted inserted replaced
-1:000000000000 0:d5ec3cbd5033
1 // ArchiverInfo.cpp
2
3 #include "StdAfx.h"
4
5 #include "ArchiverInfo.h"
6
7 #ifndef EXCLUDE_COM
8
9 #include "Common/StringConvert.h"
10 #include "Windows/FileFind.h"
11 #include "Windows/FileName.h"
12 #include "Windows/DLL.h"
13 #ifdef _WIN32
14 #include "Windows/Registry.h"
15 #endif
16 #include "Windows/PropVariant.h"
17 #include "../../Archive/IArchive.h"
18
19 using namespace NWindows;
20 using namespace NFile;
21
22 #endif
23
24 extern HINSTANCE g_hInstance;
25
26 #ifndef EXCLUDE_COM
27
28 static void SplitString(const UString &srcString, UStringVector &destStrings)
29 {
30 destStrings.Clear();
31 UString string;
32 int len = srcString.Length();
33 if (len == 0)
34 return;
35 for (int i = 0; i < len; i++)
36 {
37 wchar_t c = srcString[i];
38 if (c == L' ')
39 {
40 if (!string.IsEmpty())
41 {
42 destStrings.Add(string);
43 string.Empty();
44 }
45 }
46 else
47 string += c;
48 }
49 if (!string.IsEmpty())
50 destStrings.Add(string);
51 }
52
53 typedef UInt32 (WINAPI * GetHandlerPropertyFunc)(
54 PROPID propID, PROPVARIANT *value);
55
56 static UString GetModuleFolderPrefix()
57 {
58 UString path;
59 NDLL::MyGetModuleFileName(g_hInstance, path);
60 int pos = path.ReverseFind(WCHAR_PATH_SEPARATOR);
61 return path.Left(pos + 1);
62 }
63
64 static wchar_t *kFormatFolderName = L"Formats";
65
66 #ifdef _WIN32
67 static LPCTSTR kRegistryPath = TEXT("Software\\7-zip");
68 static LPCWSTR kProgramPathValue = L"Path";
69 static bool ReadPathFromRegistry(HKEY baseKey, UString &path)
70 {
71 NRegistry::CKey key;
72 if(key.Open(baseKey, kRegistryPath, KEY_READ) == ERROR_SUCCESS)
73 if (key.QueryValue(kProgramPathValue, path) == ERROR_SUCCESS)
74 {
75 NName::NormalizeDirPathPrefix(path);
76 return true;
77 }
78 return false;
79 }
80 #endif
81
82 static UString GetBaseFolderPrefixFromRegistry()
83 {
84 UString moduleFolderPrefix = GetModuleFolderPrefix();
85 NFind::CFileInfoW fileInfo;
86 if (NFind::FindFile(moduleFolderPrefix + kFormatFolderName, fileInfo))
87 if (fileInfo.IsDirectory())
88 return moduleFolderPrefix;
89 UString path;
90 #ifdef _WIN32
91 if(ReadPathFromRegistry(HKEY_CURRENT_USER, path))
92 return path;
93 if(ReadPathFromRegistry(HKEY_LOCAL_MACHINE, path))
94 return path;
95 #endif
96 return moduleFolderPrefix;
97 }
98
99 typedef UInt32 (WINAPI *CreateObjectPointer)(
100 const GUID *clsID,
101 const GUID *interfaceID,
102 void **outObject);
103
104 #endif
105
106 #ifndef _SFX
107 static void SetBuffer(CByteBuffer &bb, const Byte *data, int size)
108 {
109 bb.SetCapacity(size);
110 memmove((Byte *)bb, data, size);
111 }
112 #endif
113
114 void ReadArchiverInfoList(CObjectVector<CArchiverInfo> &archivers)
115 {
116 archivers.Clear();
117
118 #ifdef EXCLUDE_COM
119
120 #ifdef FORMAT_7Z
121 {
122 CArchiverInfo item;
123 item.UpdateEnabled = true;
124 item.Name = L"7z";
125 item.Extensions.Add(CArchiverExtInfo(L"7z"));
126 #ifndef _SFX
127 const unsigned char kSig[] = {'7' , 'z', 0xBC, 0xAF, 0x27, 0x1C};
128 SetBuffer(item.StartSignature, kSig, 6);
129 #endif
130 archivers.Add(item);
131 }
132 #endif
133
134 #ifdef FORMAT_BZIP2
135 {
136 CArchiverInfo item;
137 item.UpdateEnabled = true;
138 item.KeepName = true;
139 item.Name = L"BZip2";
140 item.Extensions.Add(CArchiverExtInfo(L"bz2"));
141 item.Extensions.Add(CArchiverExtInfo(L"tbz2", L".tar"));
142 #ifndef _SFX
143 const unsigned char sig[] = {'B' , 'Z', 'h' };
144 SetBuffer(item.StartSignature, sig, 3);
145 #endif
146 archivers.Add(item);
147 }
148 #endif
149
150 #ifdef FORMAT_GZIP
151 {
152 CArchiverInfo item;
153 item.UpdateEnabled = true;
154 item.Name = L"GZip";
155 item.Extensions.Add(CArchiverExtInfo(L"gz"));
156 item.Extensions.Add(CArchiverExtInfo(L"tgz", L".tar"));
157 #ifndef _SFX
158 const unsigned char sig[] = { 0x1F, 0x8B };
159 SetBuffer(item.StartSignature, sig, 2);
160 #endif
161 archivers.Add(item);
162 }
163 #endif
164
165 #ifdef FORMAT_SPLIT
166 {
167 CArchiverInfo item;
168 item.UpdateEnabled = false;
169 item.KeepName = true;
170 item.Name = L"Split";
171 item.Extensions.Add(CArchiverExtInfo(L"001"));
172 archivers.Add(item);
173 }
174 #endif
175
176 #ifdef FORMAT_TAR
177 {
178 CArchiverInfo item;
179 item.UpdateEnabled = true;
180 item.Name = L"Tar";
181 item.Extensions.Add(CArchiverExtInfo(L"tar"));
182 archivers.Add(item);
183 }
184 #endif
185
186 #ifdef FORMAT_ZIP
187 {
188 CArchiverInfo item;
189 item.UpdateEnabled = true;
190 item.Name = L"Zip";
191 item.Extensions.Add(CArchiverExtInfo(L"zip"));
192 #ifndef _SFX
193 const unsigned char sig[] = { 0x50, 0x4B, 0x03, 0x04 };
194 SetBuffer(item.StartSignature, sig, 4);
195 #endif
196 archivers.Add(item);
197 }
198 #endif
199
200 #ifdef FORMAT_CPIO
201 {
202 CArchiverInfo item;
203 item.Name = L"Cpio";
204 item.Extensions.Add(CArchiverExtInfo(L"cpio"));
205 archivers.Add(item);
206 }
207 #endif
208
209 #ifdef FORMAT_RPM
210 {
211 CArchiverInfo item;
212 item.Name = L"Rpm";
213 item.Extensions.Add(CArchiverExtInfo(L"rpm", L".cpio.gz"));
214 archivers.Add(item);
215 }
216 #endif
217
218 #ifdef FORMAT_ARJ
219 {
220 CArchiverInfo item;
221 item.Name = L"Arj";
222 item.Extensions.Add(CArchiverExtInfo(L"arj"));
223 #ifndef _SFX
224 const unsigned char sig[] = { 0x60, 0xEA };
225 SetBuffer(item.StartSignature, sig, 2);
226 #endif
227 archivers.Add(item);
228 }
229 #endif
230
231 #ifdef FORMAT_Z
232 {
233 CArchiverInfo item;
234 item.Name = L"Z";
235 item.Extensions.Add(CArchiverExtInfo(L"Z"));
236 #ifndef _SFX
237 const unsigned char sig[] = { 0x1F, 0x9D };
238 SetBuffer(item.StartSignature, sig, 2);
239 #endif
240 archivers.Add(item);
241 }
242 #endif
243
244 #else
245
246 UString folderPath = GetBaseFolderPrefixFromRegistry() +
247 (UString)kFormatFolderName + (UString)WSTRING_PATH_SEPARATOR;
248 NFind::CEnumeratorW enumerator(folderPath + L"*");
249 NFind::CFileInfoW fileInfo;
250 while (enumerator.Next(fileInfo))
251 {
252 if (fileInfo.IsDirectory())
253 continue;
254 UString filePath = folderPath + fileInfo.Name;
255 {
256 NDLL::CLibrary library;
257 if (!library.LoadEx(filePath, LOAD_LIBRARY_AS_DATAFILE))
258 continue;
259 }
260
261 NDLL::CLibrary library;
262 if (!library.Load(filePath))
263 continue;
264 GetHandlerPropertyFunc getHandlerProperty = (GetHandlerPropertyFunc)
265 library.GetProcAddress("GetHandlerProperty");
266 if (getHandlerProperty == NULL)
267 continue;
268
269 CArchiverInfo item;
270 item.FilePath = filePath;
271
272 NWindows::NCOM::CPropVariant prop;
273 if (getHandlerProperty(NArchive::kName, &prop) != S_OK)
274 continue;
275 if (prop.vt != VT_BSTR)
276 continue;
277 item.Name = prop.bstrVal;
278 prop.Clear();
279
280 if (getHandlerProperty(NArchive::kClassID, &prop) != S_OK)
281 continue;
282 if (prop.vt != VT_BSTR)
283 continue;
284 item.ClassID = *(const GUID *)prop.bstrVal;
285 prop.Clear();
286
287 if (getHandlerProperty(NArchive::kExtension, &prop) != S_OK)
288 continue;
289 if (prop.vt != VT_BSTR)
290 continue;
291
292 UString ext = prop.bstrVal;
293 UString addExt;
294
295 prop.Clear();
296
297 if (getHandlerProperty(NArchive::kAddExtension, &prop) != S_OK)
298 continue;
299 if (prop.vt == VT_BSTR)
300 {
301 addExt = prop.bstrVal;
302 }
303 else if (prop.vt != VT_EMPTY)
304 continue;
305 prop.Clear();
306
307 UStringVector exts, addExts;
308 SplitString(ext, exts);
309 SplitString(addExt, addExts);
310
311 prop.Clear();
312 for (int i = 0; i < exts.Size(); i++)
313 {
314 CArchiverExtInfo extInfo;
315 extInfo.Ext = exts[i];
316 if (addExts.Size() > 0)
317 extInfo.AddExt = addExts[i];
318 if (extInfo.AddExt == L"*")
319 extInfo.AddExt.Empty();
320 item.Extensions.Add(extInfo);
321 }
322
323 if (getHandlerProperty(NArchive::kUpdate, &prop) == S_OK)
324 if (prop.vt == VT_BOOL)
325 item.UpdateEnabled = VARIANT_BOOLToBool(prop.boolVal);
326 prop.Clear();
327
328 if (item.UpdateEnabled)
329 {
330 if (getHandlerProperty(NArchive::kKeepName, &prop) == S_OK)
331 if (prop.vt == VT_BOOL)
332 item.KeepName = VARIANT_BOOLToBool(prop.boolVal);
333 prop.Clear();
334 }
335
336 if (getHandlerProperty(NArchive::kStartSignature, &prop) == S_OK)
337 {
338 if (prop.vt == VT_BSTR)
339 {
340 UINT len = ::SysStringByteLen(prop.bstrVal);
341 item.StartSignature.SetCapacity(len);
342 memmove(item.StartSignature, prop.bstrVal, len);
343 }
344 }
345 prop.Clear();
346
347 if (getHandlerProperty(NArchive::kAssociate, &prop) == S_OK)
348 if (prop.vt == VT_BOOL)
349 item.Associate = VARIANT_BOOLToBool(prop.boolVal);
350 prop.Clear();
351
352
353 archivers.Add(item);
354 }
355
356 #endif
357 }
358
359

mercurial