// ZipRegistry.cpp #include "StdAfx.h" #include "Common/IntToString.h" #include "Common/StringConvert.h" #include "Windows/FileDir.h" #include "Windows/Registry.h" #include "Windows/Synchronization.h" #include "ZipRegistry.h" using namespace NWindows; using namespace NRegistry; static NSynchronization::CCriticalSection g_CS; #define CS_LOCK NSynchronization::CCriticalSectionLock lock(g_CS); static const TCHAR *kCuPrefix = TEXT("Software") TEXT(STRING_PATH_SEPARATOR) TEXT("7-Zip") TEXT(STRING_PATH_SEPARATOR); static CSysString GetKeyPath(const CSysString &path) { return kCuPrefix + path; } static LONG OpenMainKey(CKey &key, LPCTSTR keyName) { return key.Open(HKEY_CURRENT_USER, GetKeyPath(keyName), KEY_READ); } static LONG CreateMainKey(CKey &key, LPCTSTR keyName) { return key.Create(HKEY_CURRENT_USER, GetKeyPath(keyName)); } namespace NExtract { static const TCHAR *kKeyName = TEXT("Extraction"); static const TCHAR *kExtractMode = TEXT("ExtractMode"); static const TCHAR *kOverwriteMode = TEXT("OverwriteMode"); static const TCHAR *kShowPassword = TEXT("ShowPassword"); static const TCHAR *kPathHistory = TEXT("PathHistory"); void CInfo::Save() const { CS_LOCK CKey key; CreateMainKey(key, kKeyName); key.SetValue(kExtractMode, (UInt32)PathMode); key.SetValue(kOverwriteMode, (UInt32)OverwriteMode); key.SetValue(kShowPassword, ShowPassword); key.RecurseDeleteKey(kPathHistory); key.SetValue_Strings(kPathHistory, Paths); } void CInfo::Load() { PathMode = NPathMode::kCurrentPathnames; OverwriteMode = NOverwriteMode::kAskBefore; ShowPassword = false; Paths.Clear(); CS_LOCK CKey key; if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS) return; key.GetValue_Strings(kPathHistory, Paths); UInt32 v; if (key.QueryValue(kExtractMode, v) == ERROR_SUCCESS && v <= NPathMode::kNoPathnames) PathMode = (NPathMode::EEnum)v; if (key.QueryValue(kOverwriteMode, v) == ERROR_SUCCESS && v <= NOverwriteMode::kAutoRenameExisting) OverwriteMode = (NOverwriteMode::EEnum)v; key.GetValue_IfOk(kShowPassword, ShowPassword); } } namespace NCompression { static const TCHAR *kKeyName = TEXT("Compression"); static const TCHAR *kArcHistory = TEXT("ArcHistory"); static const WCHAR *kArchiver = L"Archiver"; static const TCHAR *kShowPassword = TEXT("ShowPassword"); static const TCHAR *kEncryptHeaders = TEXT("EncryptHeaders"); static const TCHAR *kOptionsKeyName = TEXT("Options"); static const TCHAR *kLevel = TEXT("Level"); static const TCHAR *kDictionary = TEXT("Dictionary"); static const TCHAR *kOrder = TEXT("Order"); static const TCHAR *kBlockSize = TEXT("BlockSize"); static const TCHAR *kNumThreads = TEXT("NumThreads"); static const WCHAR *kMethod = L"Method"; static const WCHAR *kOptions = L"Options"; static const WCHAR *kEncryptionMethod = L"EncryptionMethod"; static void SetRegString(CKey &key, const WCHAR *name, const UString &value) { if (value.IsEmpty()) key.DeleteValue(name); else key.SetValue(name, value); } static void SetRegUInt32(CKey &key, const TCHAR *name, UInt32 value) { if (value == (UInt32)-1) key.DeleteValue(name); else key.SetValue(name, value); } static void GetRegString(CKey &key, const WCHAR *name, UString &value) { if (key.QueryValue(name, value) != ERROR_SUCCESS) value.Empty(); } static void GetRegUInt32(CKey &key, const TCHAR *name, UInt32 &value) { if (key.QueryValue(name, value) != ERROR_SUCCESS) value = (UInt32)-1; } void CInfo::Save() const { CS_LOCK CKey key; CreateMainKey(key, kKeyName); key.SetValue(kLevel, (UInt32)Level); key.SetValue(kArchiver, ArcType); key.SetValue(kShowPassword, ShowPassword); key.SetValue(kEncryptHeaders, EncryptHeaders); key.RecurseDeleteKey(kArcHistory); key.SetValue_Strings(kArcHistory, ArcPaths); key.RecurseDeleteKey(kOptionsKeyName); { CKey optionsKey; optionsKey.Create(key, kOptionsKeyName); for (int i = 0; i < Formats.Size(); i++) { const CFormatOptions &fo = Formats[i]; CKey fk; fk.Create(optionsKey, fo.FormatID); SetRegUInt32(fk, kLevel, fo.Level); SetRegUInt32(fk, kDictionary, fo.Dictionary); SetRegUInt32(fk, kOrder, fo.Order); SetRegUInt32(fk, kBlockSize, fo.BlockLogSize); SetRegUInt32(fk, kNumThreads, fo.NumThreads); SetRegString(fk, kMethod, fo.Method); SetRegString(fk, kOptions, fo.Options); SetRegString(fk, kEncryptionMethod, fo.EncryptionMethod); } } } void CInfo::Load() { ArcPaths.Clear(); Formats.Clear(); Level = 5; ArcType = L"7z"; ShowPassword = false; EncryptHeaders = false; CS_LOCK CKey key; if (OpenMainKey(key, kKeyName) != ERROR_SUCCESS) return; key.GetValue_Strings(kArcHistory, ArcPaths); { CKey optionsKey; if (optionsKey.Open(key, kOptionsKeyName, KEY_READ) == ERROR_SUCCESS) { CSysStringVector formatIDs; optionsKey.EnumKeys(formatIDs); for (int i = 0; i < formatIDs.Size(); i++) { CKey fk; CFormatOptions fo; fo.FormatID = formatIDs[i]; if (fk.Open(optionsKey, fo.FormatID, KEY_READ) == ERROR_SUCCESS) { GetRegString(fk, kOptions, fo.Options); GetRegString(fk, kMethod, fo.Method); GetRegString(fk, kEncryptionMethod, fo.EncryptionMethod); GetRegUInt32(fk, kLevel, fo.Level); GetRegUInt32(fk, kDictionary, fo.Dictionary); GetRegUInt32(fk, kOrder, fo.Order); GetRegUInt32(fk, kBlockSize, fo.BlockLogSize); GetRegUInt32(fk, kNumThreads, fo.NumThreads); Formats.Add(fo); } } } } UString a; if (key.QueryValue(kArchiver, a) == ERROR_SUCCESS) ArcType = a; key.GetValue_IfOk(kLevel, Level); key.GetValue_IfOk(kShowPassword, ShowPassword); key.GetValue_IfOk(kEncryptHeaders, EncryptHeaders); } } static const TCHAR *kOptionsInfoKeyName = TEXT("Options"); namespace NWorkDir { static const TCHAR *kWorkDirType = TEXT("WorkDirType"); static const WCHAR *kWorkDirPath = L"WorkDirPath"; static const TCHAR *kTempRemovableOnly = TEXT("TempRemovableOnly"); void CInfo::Save()const { CS_LOCK CKey key; CreateMainKey(key, kOptionsInfoKeyName); key.SetValue(kWorkDirType, (UInt32)Mode); key.SetValue(kWorkDirPath, Path); key.SetValue(kTempRemovableOnly, ForRemovableOnly); } void CInfo::Load() { SetDefault(); CS_LOCK CKey key; if (OpenMainKey(key, kOptionsInfoKeyName) != ERROR_SUCCESS) return; UInt32 dirType; if (key.QueryValue(kWorkDirType, dirType) != ERROR_SUCCESS) return; switch (dirType) { case NMode::kSystem: case NMode::kCurrent: case NMode::kSpecified: Mode = (NMode::EEnum)dirType; } if (key.QueryValue(kWorkDirPath, Path) != ERROR_SUCCESS) { Path.Empty(); if (Mode == NMode::kSpecified) Mode = NMode::kSystem; } key.GetValue_IfOk(kTempRemovableOnly, ForRemovableOnly); } } static const TCHAR *kCascadedMenu = TEXT("CascadedMenu"); static const TCHAR *kContextMenu = TEXT("ContextMenu"); void CContextMenuInfo::Save() const { CS_LOCK CKey key; CreateMainKey(key, kOptionsInfoKeyName); key.SetValue(kCascadedMenu, Cascaded); key.SetValue(kContextMenu, Flags); } void CContextMenuInfo::Load() { Cascaded = true; Flags = (UInt32)-1; CS_LOCK CKey key; if (OpenMainKey(key, kOptionsInfoKeyName) != ERROR_SUCCESS) return; key.GetValue_IfOk(kCascadedMenu, Cascaded); key.GetValue_IfOk(kContextMenu, Flags); }