blob: ac178078a52ad0656f750b8b1cdf1bb768f9283c [file] [log] [blame]
// 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);
}