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

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

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

mercurial