UI: Options: Separate "Auto-run" and "Run as a Service" options.

This commit is contained in:
Nodir Temirkhodjaev 2021-05-16 11:29:40 +03:00
parent 8713b46a92
commit dafba58c22
6 changed files with 108 additions and 78 deletions

View File

@ -1060,7 +1060,7 @@ void ConfManager::saveExtFlags(const IniOptions &ini)
{
// Windows Explorer integration
if (ini.explorerIntegratedSet()) {
StartupUtil::integrateExplorer(ini.explorerIntegrated());
StartupUtil::setExplorerIntegrated(ini.explorerIntegrated());
}
}

View File

@ -28,33 +28,27 @@ namespace {
struct Startup
{
Startup() : initialized(false), changed(false), wasServiceMode(false), mode(0) { }
void initialize()
{
if (!initialized) {
initialized = true;
mode = StartupUtil::getStartupMode();
}
}
Startup() : initialized(false), isServiceChanged(false), wasService(false), isService(false) { }
quint8 initialized : 1;
quint8 changed : 1;
quint8 wasServiceMode : 1;
quint8 mode : 4;
quint8 isServiceChanged : 1;
quint8 wasService : 1;
quint8 isService : 1;
} g_startup;
}
OptionsPage::OptionsPage(OptionsController *ctrl, QWidget *parent) : BasePage(ctrl, parent)
{
setupStartup();
setupUi();
}
void OptionsPage::onAboutToSave()
{
// Startup Mode
saveStartupMode(m_comboStartMode->currentIndex());
// Startup
saveAutoRunMode(m_comboAutoRun->currentIndex());
saveService(m_cbService->isChecked());
// Password
if (!settings()->hasPassword() && ini()->hasPassword() && ini()->password().isEmpty()) {
@ -62,30 +56,41 @@ void OptionsPage::onAboutToSave()
}
}
void OptionsPage::saveStartupMode(int mode)
void OptionsPage::saveAutoRunMode(int mode)
{
if (g_startup.mode == mode)
if (m_currentAutoRunMode == mode)
return;
if (!g_startup.changed) {
g_startup.changed = true;
g_startup.wasServiceMode = StartupUtil::isServiceMode(g_startup.mode);
m_currentAutoRunMode = mode;
StartupUtil::setAutoRunMode(mode, settings()->defaultLanguage());
}
void OptionsPage::saveService(bool isService)
{
if (g_startup.isService == isService)
return;
g_startup.isService = isService;
if (!g_startup.isServiceChanged) {
g_startup.isServiceChanged = true;
const QString defaultLanguage = settings()->defaultLanguage();
connect(fortManager(), &QObject::destroyed, [defaultLanguage] {
StartupUtil::setStartupMode(g_startup.mode, defaultLanguage);
if (StartupUtil::isServiceMode(g_startup.mode)) {
if (g_startup.wasService == g_startup.isService)
return;
StartupUtil::setServiceInstalled(g_startup.isService, defaultLanguage);
if (g_startup.isService) {
StartupUtil::startService(); // Try to start the (maybe installed) service
}
});
}
g_startup.mode = mode;
if (g_startup.wasServiceMode != StartupUtil::isServiceMode(g_startup.mode)) {
QMetaObject::invokeMethod(
fortManager(), &FortManager::processRestartRequired, Qt::QueuedConnection);
}
QMetaObject::invokeMethod(
fortManager(), &FortManager::processRestartRequired, Qt::QueuedConnection);
}
void OptionsPage::onCancelChanges(IniOptions *oldIni)
@ -112,10 +117,12 @@ void OptionsPage::onRetranslateUi()
m_gbDriver->setTitle(tr("Driver"));
m_gbNewVersion->setTitle(tr("New Version"));
m_labelStartMode->setText(tr("Startup mode:"));
m_labelStartMode->setText(tr("Auto-run:"));
retranslateComboStartMode();
m_cbService->setText(tr("Run Fort Firewall as a Service in background"));
m_cbProvBoot->setText(tr("Stop traffic when Fort Firewall is not running"));
m_cbFilterEnabled->setText(tr("Filter Enabled"));
m_cbFilterLocals->setText(tr("Filter Local Addresses"));
m_cbFilterLocals->setToolTip(
@ -147,30 +154,29 @@ void OptionsPage::onRetranslateUi()
void OptionsPage::retranslateComboStartMode()
{
const QStringList list = { tr("Disabled"), tr("For current user"), tr("For all users"),
tr("For all users in background") };
const QStringList list = { tr("Disabled"), tr("For current user"), tr("For all users") };
int currentIndex = m_comboStartMode->currentIndex();
if (m_comboStartMode->currentIndex() < 0) {
g_startup.initialize();
currentIndex = g_startup.mode;
int currentIndex = m_comboAutoRun->currentIndex();
if (m_comboAutoRun->currentIndex() < 0) {
currentIndex = m_currentAutoRunMode;
}
m_comboStartMode->clear();
m_comboStartMode->addItems(list);
m_comboAutoRun->clear();
m_comboAutoRun->addItems(list);
m_comboStartMode->setCurrentIndex(currentIndex);
m_comboAutoRun->setCurrentIndex(currentIndex);
// Disable some items if user is not an administrator
if (OsUtil::isUserAdmin())
return;
if (StartupUtil::isServiceMode(currentIndex)) {
m_comboStartMode->setEnabled(false);
if (currentIndex >= StartupUtil::StartupAllUsers) {
m_comboAutoRun->setEnabled(false);
m_cbService->setEnabled(false);
return;
}
auto comboModel = qobject_cast<QStandardItemModel *>(m_comboStartMode->model());
auto comboModel = qobject_cast<QStandardItemModel *>(m_comboAutoRun->model());
if (!comboModel)
return;
@ -198,6 +204,17 @@ void OptionsPage::retranslateDriverMessage()
m_labelDriverMessage->setText(text);
}
void OptionsPage::setupStartup()
{
m_currentAutoRunMode = StartupUtil::autoRunMode();
if (g_startup.initialized)
return;
g_startup.initialized = true;
g_startup.wasService = g_startup.isService = settings()->hasService();
}
void OptionsPage::setupUi()
{
// Column #1
@ -246,6 +263,9 @@ void OptionsPage::setupStartupBox()
{
auto startModeLayout = setupStartModeLayout();
m_cbService = ControlUtil::createCheckBox(
g_startup.isService, [&](bool /*checked*/) { ctrl()->emitEdited(); });
m_cbProvBoot = ControlUtil::createCheckBox(conf()->provBoot(), [&](bool checked) {
conf()->setProvBoot(checked);
ctrl()->setFlagsEdited();
@ -253,6 +273,7 @@ void OptionsPage::setupStartupBox()
auto layout = new QVBoxLayout();
layout->addLayout(startModeLayout);
layout->addWidget(m_cbService);
layout->addWidget(m_cbProvBoot);
m_gbStartup = new QGroupBox(this);
@ -263,14 +284,14 @@ QLayout *OptionsPage::setupStartModeLayout()
{
m_labelStartMode = ControlUtil::createLabel();
m_comboStartMode = ControlUtil::createComboBox(QStringList(), [&](int index) {
if (g_startup.mode != index) {
m_comboAutoRun = ControlUtil::createComboBox(QStringList(), [&](int index) {
if (m_currentAutoRunMode != index) {
ctrl()->emitEdited();
}
});
m_comboStartMode->setFixedWidth(200);
m_comboAutoRun->setFixedWidth(200);
return ControlUtil::createRowLayout(m_labelStartMode, m_comboStartMode);
return ControlUtil::createRowLayout(m_labelStartMode, m_comboAutoRun);
}
void OptionsPage::setupTrafficBox()

View File

@ -19,12 +19,15 @@ protected slots:
void onRetranslateUi() override;
private:
void saveStartupMode(int mode);
void saveAutoRunMode(int mode);
void saveService(bool isService);
void retranslateComboStartMode();
void retranslateEditPassword();
void retranslateDriverMessage();
void setupStartup();
void setupUi();
QLayout *setupColumn1();
void setupStartupBox();
@ -44,6 +47,8 @@ private:
void setupNewVersionUpdate();
private:
qint8 m_currentAutoRunMode = 0;
QGroupBox *m_gbStartup = nullptr;
QGroupBox *m_gbTraffic = nullptr;
QGroupBox *m_gbGlobal = nullptr;
@ -51,7 +56,8 @@ private:
QGroupBox *m_gbDriver = nullptr;
QGroupBox *m_gbNewVersion = nullptr;
QLabel *m_labelStartMode = nullptr;
QComboBox *m_comboStartMode = nullptr;
QComboBox *m_comboAutoRun = nullptr;
QCheckBox *m_cbService = nullptr;
QCheckBox *m_cbProvBoot = nullptr;
QCheckBox *m_cbFilterEnabled = nullptr;
QCheckBox *m_cbFilterLocals = nullptr;

View File

@ -39,6 +39,12 @@ QString wrappedAppFilePath()
return QString("\"%1\"").arg(filePath);
}
QString autoRunCommand(const QString &defaultLanguage)
{
return wrappedAppFilePath()
+ (defaultLanguage.isEmpty() ? QString() : " --lang " + defaultLanguage);
}
bool isAutorunForUser(RegKey::Root root, const char *key)
{
const RegKey reg(root, key, RegKey::DefaultReadOnly);
@ -153,6 +159,18 @@ bool StartupUtil::isServiceInstalled()
return res;
}
void StartupUtil::setServiceInstalled(bool install, const QString &defaultLanguage)
{
uninstallService(serviceNameStr);
if (!install)
return;
const QString command = autoRunCommand(defaultLanguage) + " --service";
installService(serviceNameStr, serviceDisplayStr, serviceDescriptionStr, command);
}
bool StartupUtil::startService()
{
bool res = false;
@ -168,15 +186,13 @@ bool StartupUtil::startService()
return res;
}
StartupUtil::StartupMode StartupUtil::getStartupMode()
StartupUtil::AutoRunMode StartupUtil::autoRunMode()
{
const bool isForAllUsers = isAutorunForAllUsers();
return (isForAllUsers || isServiceInstalled())
? (isForAllUsers ? StartupAllUsers : StartupAllUsersBackground)
: (isAutorunForCurrentUser() ? StartupCurrentUser : StartupDisabled);
return isAutorunForCurrentUser() ? StartupCurrentUser
: (isAutorunForAllUsers() ? StartupAllUsers : StartupDisabled);
}
void StartupUtil::setStartupMode(int mode, const QString &defaultLanguage)
void StartupUtil::setAutoRunMode(int mode, const QString &defaultLanguage)
{
// Remove link from Programs -> Startup
// TODO: COMPAT: Remove after v4.1.0 (via v4.0.0)
@ -184,13 +200,11 @@ void StartupUtil::setStartupMode(int mode, const QString &defaultLanguage)
removeAutorunForCurrentUser();
removeAutorunForAllUsers();
uninstallService(serviceNameStr);
if (mode == StartupDisabled)
return;
const QString command = wrappedAppFilePath()
+ (defaultLanguage.isEmpty() ? QString() : " --lang " + defaultLanguage);
const QString command = autoRunCommand(defaultLanguage);
switch (mode) {
case StartupCurrentUser:
@ -198,19 +212,12 @@ void StartupUtil::setStartupMode(int mode, const QString &defaultLanguage)
break;
case StartupAllUsers:
setAutorunForAllUsers(command);
Q_FALLTHROUGH();
case StartupAllUsersBackground:
installService(
serviceNameStr, serviceDisplayStr, serviceDescriptionStr, command + " --service");
break;
default:
Q_UNREACHABLE();
}
}
bool StartupUtil::isServiceMode(int mode)
{
return mode == StartupAllUsers || mode == StartupAllUsersBackground;
}
bool StartupUtil::isExplorerIntegrated()
{
const RegKey regShell(regShellRoot, regShellMenu, RegKey::DefaultReadOnly);
@ -218,7 +225,7 @@ bool StartupUtil::isExplorerIntegrated()
return !reg.isNull();
}
void StartupUtil::integrateExplorer(bool integrate)
void StartupUtil::setExplorerIntegrated(bool integrate)
{
RegKey regShell(regShellRoot, regShellMenu, RegKey::DefaultReadWrite);
if (integrate) {

View File

@ -6,25 +6,20 @@
class StartupUtil
{
public:
enum StartupMode : qint8 {
StartupDisabled = 0,
StartupCurrentUser,
StartupAllUsers,
StartupAllUsersBackground
};
enum AutoRunMode : qint8 { StartupDisabled = 0, StartupCurrentUser, StartupAllUsers };
static const wchar_t *serviceName();
static bool isServiceInstalled();
static void setServiceInstalled(bool install, const QString &defaultLanguage = QString());
static bool startService();
static StartupMode getStartupMode();
static void setStartupMode(int mode, const QString &defaultLanguage = QString());
static bool isServiceMode(int mode);
static AutoRunMode autoRunMode();
static void setAutoRunMode(int mode, const QString &defaultLanguage = QString());
static bool isExplorerIntegrated();
static void integrateExplorer(bool integrate);
static void setExplorerIntegrated(bool integrate);
};
#endif // STARTUPUTIL_H

View File

@ -23,8 +23,9 @@
static void uninstall()
{
StartupUtil::setStartupMode(StartupUtil::StartupDisabled); // Remove auto-run and service
StartupUtil::integrateExplorer(false); // Remove Windows Explorer integration
StartupUtil::setAutoRunMode(StartupUtil::StartupDisabled); // Remove auto-run
StartupUtil::setServiceInstalled(false); // Uninstall service
StartupUtil::setExplorerIntegrated(false); // Remove Windows Explorer integration
DriverCommon::provUnregister(); // Unregister booted provider
}