Files
easy7zip/CPP/7zip/UI/Common/ZipRegistry.cpp
Igor Pavlov c574fc0f4b 4.46 beta
2016-05-28 00:15:51 +01:00

418 lines
14 KiB
C++
Executable File

// ZipRegistry.cpp
#include "StdAfx.h"
#include "ZipRegistry.h"
#include "Common/IntToString.h"
#include "Common/StringConvert.h"
#include "Windows/Synchronization.h"
#include "Windows/Registry.h"
#include "Windows/FileDir.h"
using namespace NWindows;
using namespace NRegistry;
static const TCHAR *kCUBasePath = TEXT("Software\\7-ZIP");
static NSynchronization::CCriticalSection g_RegistryOperationsCriticalSection;
//////////////////////
// ExtractionInfo
static const TCHAR *kExtractionKeyName = TEXT("Extraction");
static const TCHAR *kExtractionPathHistoryKeyName = TEXT("PathHistory");
static const TCHAR *kExtractionExtractModeValueName = TEXT("ExtarctMode");
static const TCHAR *kExtractionOverwriteModeValueName = TEXT("OverwriteMode");
static const TCHAR *kExtractionShowPasswordValueName = TEXT("ShowPassword");
static CSysString GetKeyPath(const CSysString &path)
{
return CSysString(kCUBasePath) + CSysString('\\') + CSysString(path);
}
void SaveExtractionInfo(const NExtract::CInfo &info)
{
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
CKey extractionKey;
extractionKey.Create(HKEY_CURRENT_USER, GetKeyPath(kExtractionKeyName));
extractionKey.RecurseDeleteKey(kExtractionPathHistoryKeyName);
{
CKey pathHistoryKey;
pathHistoryKey.Create(extractionKey, kExtractionPathHistoryKeyName);
for(int i = 0; i < info.Paths.Size(); i++)
{
wchar_t numberString[16];
ConvertUInt64ToString(i, numberString);
pathHistoryKey.SetValue(numberString, info.Paths[i]);
}
}
extractionKey.SetValue(kExtractionExtractModeValueName, UInt32(info.PathMode));
extractionKey.SetValue(kExtractionOverwriteModeValueName, UInt32(info.OverwriteMode));
extractionKey.SetValue(kExtractionShowPasswordValueName, info.ShowPassword);
}
void ReadExtractionInfo(NExtract::CInfo &info)
{
info.Paths.Clear();
info.PathMode = NExtract::NPathMode::kCurrentPathnames;
info.OverwriteMode = NExtract::NOverwriteMode::kAskBefore;
info.ShowPassword = false;
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
CKey extractionKey;
if(extractionKey.Open(HKEY_CURRENT_USER, GetKeyPath(kExtractionKeyName), KEY_READ) != ERROR_SUCCESS)
return;
{
CKey pathHistoryKey;
if(pathHistoryKey.Open(extractionKey, kExtractionPathHistoryKeyName, KEY_READ) ==
ERROR_SUCCESS)
{
for (;;)
{
wchar_t numberString[16];
ConvertUInt64ToString(info.Paths.Size(), numberString);
UString path;
if (pathHistoryKey.QueryValue(numberString, path) != ERROR_SUCCESS)
break;
info.Paths.Add(path);
}
}
}
UInt32 extractModeIndex;
if (extractionKey.QueryValue(kExtractionExtractModeValueName, extractModeIndex) == ERROR_SUCCESS)
{
switch (extractModeIndex)
{
case NExtract::NPathMode::kFullPathnames:
case NExtract::NPathMode::kCurrentPathnames:
case NExtract::NPathMode::kNoPathnames:
info.PathMode = NExtract::NPathMode::EEnum(extractModeIndex);
break;
}
}
UInt32 overwriteModeIndex;
if (extractionKey.QueryValue(kExtractionOverwriteModeValueName, overwriteModeIndex) == ERROR_SUCCESS)
{
switch (overwriteModeIndex)
{
case NExtract::NOverwriteMode::kAskBefore:
case NExtract::NOverwriteMode::kWithoutPrompt:
case NExtract::NOverwriteMode::kSkipExisting:
case NExtract::NOverwriteMode::kAutoRename:
case NExtract::NOverwriteMode::kAutoRenameExisting:
info.OverwriteMode = NExtract::NOverwriteMode::EEnum(overwriteModeIndex);
break;
}
}
if (extractionKey.QueryValue(kExtractionShowPasswordValueName,
info.ShowPassword) != ERROR_SUCCESS)
info.ShowPassword = false;
}
///////////////////////////////////
// CompressionInfo
static const TCHAR *kCompressionKeyName = TEXT("Compression");
static const TCHAR *kCompressionHistoryArchivesKeyName = TEXT("ArcHistory");
static const TCHAR *kCompressionLevelValueName = TEXT("Level");
static const TCHAR *kCompressionLastFormatValueName = TEXT("Archiver");
static const TCHAR *kCompressionShowPasswordValueName = TEXT("ShowPassword");
static const TCHAR *kCompressionEncryptHeadersValueName = TEXT("EncryptHeaders");
static const TCHAR *kCompressionOptionsKeyName = TEXT("Options");
// static const TCHAR *kSolid = TEXT("Solid");
// static const TCHAR *kMultiThread = TEXT("Multithread");
static const WCHAR *kCompressionOptions = L"Options";
static const TCHAR *kCompressionLevel = TEXT("Level");
static const WCHAR *kCompressionMethod = L"Method";
static const WCHAR *kEncryptionMethod = L"EncryptionMethod";
static const TCHAR *kCompressionDictionary = TEXT("Dictionary");
static const TCHAR *kCompressionOrder = TEXT("Order");
static const TCHAR *kCompressionNumThreads = TEXT("NumThreads");
static const TCHAR *kCompressionBlockSize = TEXT("BlockSize");
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 SaveCompressionInfo(const NCompression::CInfo &info)
{
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
CKey compressionKey;
compressionKey.Create(HKEY_CURRENT_USER, GetKeyPath(kCompressionKeyName));
compressionKey.RecurseDeleteKey(kCompressionHistoryArchivesKeyName);
{
CKey historyArchivesKey;
historyArchivesKey.Create(compressionKey, kCompressionHistoryArchivesKeyName);
for(int i = 0; i < info.HistoryArchives.Size(); i++)
{
wchar_t numberString[16];
ConvertUInt64ToString(i, numberString);
historyArchivesKey.SetValue(numberString, info.HistoryArchives[i]);
}
}
// compressionKey.SetValue(kSolid, info.Solid);
// compressionKey.SetValue(kMultiThread, info.MultiThread);
compressionKey.RecurseDeleteKey(kCompressionOptionsKeyName);
{
CKey optionsKey;
optionsKey.Create(compressionKey, kCompressionOptionsKeyName);
for(int i = 0; i < info.FormatOptionsVector.Size(); i++)
{
const NCompression::CFormatOptions &fo = info.FormatOptionsVector[i];
CKey formatKey;
formatKey.Create(optionsKey, fo.FormatID);
SetRegString(formatKey, kCompressionOptions, fo.Options);
SetRegString(formatKey, kCompressionMethod, fo.Method);
SetRegString(formatKey, kEncryptionMethod, fo.EncryptionMethod);
SetRegUInt32(formatKey, kCompressionLevel, fo.Level);
SetRegUInt32(formatKey, kCompressionDictionary, fo.Dictionary);
SetRegUInt32(formatKey, kCompressionOrder, fo.Order);
SetRegUInt32(formatKey, kCompressionBlockSize, fo.BlockLogSize);
SetRegUInt32(formatKey, kCompressionNumThreads, fo.NumThreads);
}
}
compressionKey.SetValue(kCompressionLevelValueName, UInt32(info.Level));
compressionKey.SetValue(kCompressionLastFormatValueName, GetSystemString(info.ArchiveType));
compressionKey.SetValue(kCompressionShowPasswordValueName, info.ShowPassword);
compressionKey.SetValue(kCompressionEncryptHeadersValueName, info.EncryptHeaders);
// compressionKey.SetValue(kCompressionMaximizeValueName, info.Maximize);
}
void ReadCompressionInfo(NCompression::CInfo &info)
{
info.HistoryArchives.Clear();
// info.Solid = true;
// info.MultiThread = IsMultiProcessor();
info.FormatOptionsVector.Clear();
info.Level = 5;
info.ArchiveType = L"7z";
// definedStatus.Maximize = false;
info.ShowPassword = false;
info.EncryptHeaders = false;
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
CKey compressionKey;
if(compressionKey.Open(HKEY_CURRENT_USER,
GetKeyPath(kCompressionKeyName), KEY_READ) != ERROR_SUCCESS)
return;
{
CKey historyArchivesKey;
if(historyArchivesKey.Open(compressionKey, kCompressionHistoryArchivesKeyName, KEY_READ) ==
ERROR_SUCCESS)
{
for (;;)
{
wchar_t numberString[16];
ConvertUInt64ToString(info.HistoryArchives.Size(), numberString);
UString path;
if (historyArchivesKey.QueryValue(numberString, path) != ERROR_SUCCESS)
break;
info.HistoryArchives.Add(path);
}
}
}
/*
bool solid = false;
if (compressionKey.QueryValue(kSolid, solid) == ERROR_SUCCESS)
info.Solid = solid;
bool multiThread = false;
if (compressionKey.QueryValue(kMultiThread, multiThread) == ERROR_SUCCESS)
info.MultiThread = multiThread;
*/
{
CKey optionsKey;
if(optionsKey.Open(compressionKey, kCompressionOptionsKeyName, KEY_READ) ==
ERROR_SUCCESS)
{
CSysStringVector formatIDs;
optionsKey.EnumKeys(formatIDs);
for(int i = 0; i < formatIDs.Size(); i++)
{
CKey formatKey;
NCompression::CFormatOptions fo;
fo.FormatID = formatIDs[i];
if(formatKey.Open(optionsKey, fo.FormatID, KEY_READ) == ERROR_SUCCESS)
{
GetRegString(formatKey, kCompressionOptions, fo.Options);
GetRegString(formatKey, kCompressionMethod, fo.Method);
GetRegString(formatKey, kEncryptionMethod, fo.EncryptionMethod);
GetRegUInt32(formatKey, kCompressionLevel, fo.Level);
GetRegUInt32(formatKey, kCompressionDictionary, fo.Dictionary);
GetRegUInt32(formatKey, kCompressionOrder, fo.Order);
GetRegUInt32(formatKey, kCompressionBlockSize, fo.BlockLogSize);
GetRegUInt32(formatKey, kCompressionNumThreads, fo.NumThreads);
info.FormatOptionsVector.Add(fo);
}
}
}
}
UInt32 level;
if (compressionKey.QueryValue(kCompressionLevelValueName, level) == ERROR_SUCCESS)
info.Level = level;
CSysString archiveType;
if (compressionKey.QueryValue(kCompressionLastFormatValueName, archiveType) == ERROR_SUCCESS)
info.ArchiveType = GetUnicodeString(archiveType);
if (compressionKey.QueryValue(kCompressionShowPasswordValueName,
info.ShowPassword) != ERROR_SUCCESS)
info.ShowPassword = false;
if (compressionKey.QueryValue(kCompressionEncryptHeadersValueName,
info.EncryptHeaders) != ERROR_SUCCESS)
info.EncryptHeaders = false;
/*
if (compressionKey.QueryValue(kCompressionLevelValueName, info.Maximize) == ERROR_SUCCESS)
definedStatus.Maximize = true;
*/
}
///////////////////////////////////
// WorkDirInfo
static const TCHAR *kOptionsInfoKeyName = TEXT("Options");
static const TCHAR *kWorkDirTypeValueName = TEXT("WorkDirType");
static const WCHAR *kWorkDirPathValueName = L"WorkDirPath";
static const TCHAR *kTempRemovableOnlyValueName = TEXT("TempRemovableOnly");
static const TCHAR *kCascadedMenuValueName = TEXT("CascadedMenu");
static const TCHAR *kContextMenuValueName = TEXT("ContextMenu");
void SaveWorkDirInfo(const NWorkDir::CInfo &info)
{
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
CKey optionsKey;
optionsKey.Create(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName));
optionsKey.SetValue(kWorkDirTypeValueName, UInt32(info.Mode));
optionsKey.SetValue(kWorkDirPathValueName, info.Path);
optionsKey.SetValue(kTempRemovableOnlyValueName, info.ForRemovableOnly);
}
void ReadWorkDirInfo(NWorkDir::CInfo &info)
{
info.SetDefault();
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
CKey optionsKey;
if(optionsKey.Open(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName), KEY_READ) != ERROR_SUCCESS)
return;
UInt32 dirType;
if (optionsKey.QueryValue(kWorkDirTypeValueName, dirType) != ERROR_SUCCESS)
return;
switch (dirType)
{
case NWorkDir::NMode::kSystem:
case NWorkDir::NMode::kCurrent:
case NWorkDir::NMode::kSpecified:
info.Mode = NWorkDir::NMode::EEnum(dirType);
}
UString sysWorkDir;
if (optionsKey.QueryValue(kWorkDirPathValueName, sysWorkDir) != ERROR_SUCCESS)
{
info.Path.Empty();
if (info.Mode == NWorkDir::NMode::kSpecified)
info.Mode = NWorkDir::NMode::kSystem;
}
info.Path = GetUnicodeString(sysWorkDir);
if (optionsKey.QueryValue(kTempRemovableOnlyValueName, info.ForRemovableOnly) != ERROR_SUCCESS)
info.SetForRemovableOnlyDefault();
}
static void SaveOption(const TCHAR *value, bool enabled)
{
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
CKey optionsKey;
optionsKey.Create(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName));
optionsKey.SetValue(value, enabled);
}
static bool ReadOption(const TCHAR *value, bool defaultValue)
{
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
CKey optionsKey;
if(optionsKey.Open(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName), KEY_READ) != ERROR_SUCCESS)
return defaultValue;
bool enabled;
if (optionsKey.QueryValue(value, enabled) != ERROR_SUCCESS)
return defaultValue;
return enabled;
}
void SaveCascadedMenu(bool show)
{ SaveOption(kCascadedMenuValueName, show); }
bool ReadCascadedMenu()
{ return ReadOption(kCascadedMenuValueName, true); }
static void SaveValue(const TCHAR *value, UInt32 valueToWrite)
{
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
CKey optionsKey;
optionsKey.Create(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName));
optionsKey.SetValue(value, valueToWrite);
}
static bool ReadValue(const TCHAR *value, UInt32 &result)
{
NSynchronization::CCriticalSectionLock lock(g_RegistryOperationsCriticalSection);
CKey optionsKey;
if(optionsKey.Open(HKEY_CURRENT_USER, GetKeyPath(kOptionsInfoKeyName), KEY_READ) != ERROR_SUCCESS)
return false;
return (optionsKey.QueryValue(value, result) == ERROR_SUCCESS);
}
void SaveContextMenuStatus(UInt32 value)
{ SaveValue(kContextMenuValueName, value); }
bool ReadContextMenuStatus(UInt32 &value)
{ return ReadValue(kContextMenuValueName, value); }