#include "stdafx.h"
#include "Config.h"
#include "Options.h"
#include "SaveConfig.h"
#include "UserMessage.h"
constexpr auto cszGeneralSection = TEXT("General");
constexpr auto cszKeyStartupDelay = TEXT("StartupDelay");
constexpr auto cszKeyLockWorkStationDelay = TEXT("LockWorkStationDelay");
constexpr auto cszKeyAlwaysLockWorkStation = TEXT("AlwaysLockWorkStation");
constexpr auto cszKeyAlwaysLaunchScreensaver = TEXT("AlwaysLaunchScreensaver");
constexpr auto cszKeyAlwaysEnableScreensaver = TEXT("AlwaysEnableScreensaver");
constexpr auto cszKeyTriggerOnLockWorkStation = TEXT("TriggerOnLockWorkStation");
constexpr auto cszYes = TEXT("yes");
constexpr auto cszNo = TEXT("no");
namespace
{
auto dwStartupDelay = Config::DefaultStartupDelay;
auto dwLockWorkStationDelay = Config::DefaultLockWorkStationDelay;
auto alwaysLockWorkStation = Config::DefaultAlwaysLockWorkStation;
auto alwaysLaunchScreensaver = Config::DefaultAlwaysLaunchScreensaver;
auto alwaysEnableScreensaver = Config::DefaultAlwaysEnableScreensaver;
auto triggerOnLockWorkStation = Config::DefaultTriggerOnLockWorkStation;
CharBuffer<MAX_PATH> szIniFileName;
CharBuffer<MAX_PATH> szIni;
void PrepareIniFileName();
}
DWORD Config::StartupDelay()
{
Config::Read();
return dwStartupDelay;
}
DWORD Config::LockWorkStationDelay()
{
Config::Read();
return dwLockWorkStationDelay;
}
bool Config::AlwaysLockWorkStation()
{
Config::Read();
return alwaysLockWorkStation;
}
bool Config::AlwaysLaunchScreensaver()
{
Config::Read();
return alwaysLaunchScreensaver;
}
bool Config::AlwaysEnableScreensaver()
{
Config::Read();
return alwaysEnableScreensaver;
}
bool Config::TriggerOnLockWorkStation()
{
Config::Read();
return triggerOnLockWorkStation;
}
LPCTSTR Config::IniFileName()
{
PrepareIniFileName();
return szIniFileName;
}
void Config::Open()
{
if (!SaveConfig::ToExeDirectoryIfNoConfig())
{
UserMessage::ConfigSaveSucceeded(false);
return;
}
PrepareIniFileName();
#pragma warning(push)
#pragma warning(disable: 4302)
#pragma warning(disable: 4311)
#pragma warning(suppress: 26490)
const auto result = reinterpret_cast<UINT>(ShellExecute(nullptr, nullptr, szIni, nullptr, nullptr, SW_SHOWNORMAL));
#pragma warning(pop)
const auto succeeded = result > 32;
ASSERT(succeeded && "ShellExecute");
TRACE_UINT("ShellExecute", result);
if (!succeeded)
{
UserMessage::ConfigOpenFailed();
}
}
namespace
{
void GetString(LPCTSTR cszKeyName, LPCTSTR cszDefault, LPTSTR szReturnedString, DWORD nSize)
{
VERIFY(GetPrivateProfileString(cszGeneralSection, cszKeyName, cszDefault, szReturnedString, nSize, szIni));
}
UINT GetTimeout(LPCTSTR cszKeyName, INT nDefault)
{
const auto getInt = [=]()
{
return GetPrivateProfileInt(cszGeneralSection, cszKeyName, nDefault, szIni);
};
const auto uVal = getInt();
return uVal >= Config::MinTimeout && uVal <= Config::MaxTimeout ? uVal : nDefault;
}
bool GetStandaloneBool(LPCTSTR cszKeyName, bool defaultValue)
{
constexpr auto strToBool = [](LPCTSTR cszVal, bool defaultValue)
{
static LPCTSTR arrTrue[] { cszYes, TEXT("true"), TEXT("on"), TEXT("1") };
static LPCTSTR arrFalse[] { cszNo, TEXT("false"), TEXT("off"), TEXT("0"), TEXT(""), nullptr };
for (const auto cszTrueVal : arrTrue) if (StringEqualIgnoreCase(cszVal, cszTrueVal)) return true;
for (const auto cszFalseVal : arrFalse) if (StringEqualIgnoreCase(cszVal, cszFalseVal)) return false;
return defaultValue;
};
const auto getBool = [=]()
{
CharBuffer<8> chBuf;
GetString(cszKeyName, defaultValue ? cszYes : cszNo, chBuf, chBuf);
return strToBool(chBuf, defaultValue);
};
return !Options::ScreensaverRun() && getBool();
}
bool WriteString(LPCTSTR cszKeyName, LPCTSTR cszKeyValue)
{
const auto succeeded = WritePrivateProfileString(cszGeneralSection, cszKeyName, cszKeyValue, szIni);
ASSERT(succeeded && "WriteString");
return succeeded;
}
bool WriteBool(LPCTSTR cszKeyName, bool value)
{
constexpr auto toBool = [](bool value) noexcept { return value ? cszYes : cszNo; };
return WriteString(cszKeyName, toBool(value));
}
void WriteBool(LPCTSTR cszKey, bool oldValue, bool newValue)
{
if (oldValue != newValue)
{
[[maybe_unused]] const auto _ = SaveConfig::ToExeDirectoryIfNoConfig();
WriteBool(cszKey, newValue);
}
}
void PrepareIniFileName()
{
EXECUTE_ONCE()
if (!GetModuleFileName(nullptr, szIni, szIni))
{
TRACE(TEXT("GetModuleFileName failed"));
return;
}
if (const auto szDot = StrRChr(szIni, nullptr, TEXT('.')))
{
*(szDot + 1) = TEXT('\0');
}
else
{
VERIFY_STR(StringCchCat(szIni, szIni, TEXT(".")));
}
VERIFY_STR(StringCchCat(szIni, szIni, TEXT("ini")));
#pragma warning(suppress: 26462)
const auto szFileName = StrRChr(szIni, nullptr, TEXT('\\'));
if (szFileName)
{
VERIFY_STR(StringCchCopy(szIniFileName, szIniFileName, szFileName + 1));
}
}
}
void Config::Read(bool force)
{
if (!force)
{
EXECUTE_ONCE()
}
PrepareIniFileName();
dwStartupDelay = GetTimeout( cszKeyStartupDelay, DefaultStartupDelay);
dwLockWorkStationDelay = GetTimeout( cszKeyLockWorkStationDelay, DefaultLockWorkStationDelay);
alwaysLockWorkStation = GetStandaloneBool(cszKeyAlwaysLockWorkStation, DefaultAlwaysLockWorkStation);
alwaysLaunchScreensaver = GetStandaloneBool(cszKeyAlwaysLaunchScreensaver, DefaultAlwaysLaunchScreensaver);
alwaysEnableScreensaver = GetStandaloneBool(cszKeyAlwaysEnableScreensaver, DefaultAlwaysEnableScreensaver);
triggerOnLockWorkStation = GetStandaloneBool(cszKeyTriggerOnLockWorkStation, DefaultTriggerOnLockWorkStation);
TRACE(TEXT("Reading config '%s'..."), szIni.Chars);
TRACE(TEXT("[%s]"), cszGeneralSection);
TRACE_UINT("StartupDelay", dwStartupDelay);
TRACE_UINT("LockWorkStationDelay", dwLockWorkStationDelay);
TRACE_BOOL("AlwaysLockWorkStation", alwaysLockWorkStation);
TRACE_BOOL("AlwaysLaunchScreensaver", alwaysLaunchScreensaver);
TRACE_BOOL("AlwaysEnableScreensaver", alwaysEnableScreensaver);
TRACE_BOOL("TriggerOnLockWorkStation", triggerOnLockWorkStation);
TRACE(TEXT("Config end"));
}
bool Config::Write(
DWORD newStartupDelay,
DWORD newLockWorkStationDelay,
bool newAlwaysLockWorkStation,
bool newAlwaysLaunchScreensaver,
bool newAlwaysEnableScreensaver,
bool newTriggerOnLockWorkStation
)
{
[[maybe_unused]] const auto _ = SaveConfig::ToExeDirectoryIfNoConfig();
constexpr auto formatInt = [](int value) {
CharBuffer<16, ClearBuffer::All> szBuffer;
VERIFY_SPRINTF(wnsprintf(szBuffer, szBuffer, TEXT("%d"), value));
return szBuffer;
};
const auto writeInt = [&](LPCTSTR cszKeyName, int value) { return WriteString(cszKeyName, formatInt(value)); };
return
writeInt (cszKeyStartupDelay, newStartupDelay) &&
writeInt (cszKeyLockWorkStationDelay, newLockWorkStationDelay) &&
WriteBool(cszKeyAlwaysLockWorkStation, newAlwaysLockWorkStation) &&
WriteBool(cszKeyAlwaysLaunchScreensaver, newAlwaysLaunchScreensaver) &&
WriteBool(cszKeyAlwaysEnableScreensaver, newAlwaysEnableScreensaver) &&
WriteBool(cszKeyTriggerOnLockWorkStation, newTriggerOnLockWorkStation);
}
void Config::WriteAlwaysEnableScreensaver(bool newAlwaysEnableScreensaver)
{
WriteBool(cszKeyAlwaysEnableScreensaver, AlwaysEnableScreensaver(), newAlwaysEnableScreensaver);
}
void Config::WriteTriggerOnLockWorkStation(bool newTriggerOnLockWorkStation)
{
WriteBool(cszKeyTriggerOnLockWorkStation, TriggerOnLockWorkStation(), newTriggerOnLockWorkStation);
}