#include "StdAfx.h"
#include "Options.h"
namespace
{
const auto cszNotificationAreaIconOption = TEXT("tray");
bool showHelp;
bool saveConfig;
bool screensaver;
bool lockWorkStation;
bool asScreensaver;
bool screensaverHelp;
bool screensaverRun;
bool notificationAreaIcon;
CharBuffer<MAX_PATH+16> szNotificationAreaCommandLine;
void ParseOptions();
}
bool Options::AsScreensaver()
{
ParseOptions();
return asScreensaver;
}
bool Options::ScreensaverHelp()
{
ParseOptions();
return screensaverHelp;
}
bool Options::ScreensaverRun()
{
ParseOptions();
return screensaverRun;
}
bool Options::LockWorkStation()
{
ParseOptions();
return lockWorkStation;
}
bool Options::ShowHelp()
{
ParseOptions();
return showHelp;
}
bool Options::SaveConfig()
{
ParseOptions();
return saveConfig;
}
bool Options::Screensaver()
{
ParseOptions();
return screensaver;
}
bool Options::NotificationAreaIcon()
{
ParseOptions();
return notificationAreaIcon;
}
LPCTSTR Options::GetNotificationAreaIconCommandLine()
{
if (szNotificationAreaCommandLine.IsEmpty())
{
CharBuffer<MAX_PATH+16> szExeName;
if (GetModuleFileName(nullptr, szExeName, szExeName))
{
VERIFY_SPRINTF(wnsprintf(szNotificationAreaCommandLine, szNotificationAreaCommandLine, TEXT("\"%s\" /%s"), szExeName.Chars, cszNotificationAreaIconOption));
}
}
return szNotificationAreaCommandLine;
}
namespace
{
#pragma warning(suppress: 26429)
[[nodiscard]] bool IsOptionSign(LPCTSTR szArg) noexcept
{
return *szArg == TEXT('-') || *szArg == TEXT('/');
}
[[nodiscard]] bool IsOption(LPCTSTR szArg, LPCTSTR cszOptName)
{
return IsOptionSign(szArg)
&& StringEqualIgnoreCase(szArg + 1, cszOptName);
}
[[nodiscard]] bool IsOptionStartsWith(LPCTSTR szArg, LPCTSTR cszOpt)
{
return IsOptionSign(szArg)
&& StrStr(szArg + 1, cszOpt) == szArg + 1;
}
[[nodiscard]] bool IsOption(LPCTSTR szArg, LPCTSTR cszOptName, LPCTSTR cszOptNameLong)
{
return IsOption(szArg, cszOptName) || IsOption(szArg, cszOptNameLong);
}
[[nodiscard]] bool RunAsScreensaver()
{
CharBuffer<MAX_PATH> szExeName;
GetModuleFileName(nullptr, szExeName, szExeName);
#pragma warning(suppress: 26462)
const auto szExtDot = PathFindExtension(szExeName);
return szExtDot && StringEqualIgnoreCase(szExtDot + 1, TEXT("scr"));
}
#define TRACE_OPTION(name) TRACE(TEXT(#name) TEXT(" option is %sset"), name ? TEXT("") : TEXT("not "));
void ParseOptions()
{
EXECUTE_ONCE();
asScreensaver = RunAsScreensaver();
const auto standalone = !asScreensaver;
int argc;
auto argv = CommandLineToArgvW(GetCommandLineW(), &argc);
if (!argv)
{
TRACE(TEXT("CommandLineToArgvW failed"));
return;
}
for (auto i = 1; i < argc; i++)
{
LPCTSTR szArg = argv[i];
if (IsOption(szArg, TEXT("l"), TEXT("lock")))
{
lockWorkStation = standalone;
continue;
}
if (IsOption(szArg, TEXT("h"), TEXT("help")) || IsOption(szArg, TEXT("?")))
{
showHelp = true;
continue;
}
if (IsOption(szArg, TEXT("c"), TEXT("config")))
{
saveConfig = standalone;
continue;
}
if (IsOption(szArg, TEXT("s"), TEXT("screen")))
{
screensaver = standalone;
screensaverRun = asScreensaver;
continue;
}
if (IsOption(szArg, TEXT("t"), cszNotificationAreaIconOption))
{
notificationAreaIcon = standalone;
continue;
}
if (IsOptionStartsWith(szArg, TEXT("c")) || IsOptionStartsWith(szArg, TEXT("c ")) || IsOptionStartsWith(szArg, TEXT("c:")))
{
screensaverHelp = asScreensaver;
continue;
}
}
LocalFree(argv);
TRACE_OPTION(showHelp);
TRACE_OPTION(saveConfig);
TRACE_OPTION(lockWorkStation);
TRACE_OPTION(screensaver);
TRACE_OPTION(asScreensaver);
TRACE_OPTION(screensaverHelp);
TRACE_OPTION(screensaverRun);
TRACE_OPTION(notificationAreaIcon);
}
}
#undef TRACE_OPTION