From dac55059b55cf985b034c77fbd760a2ee50666db Mon Sep 17 00:00:00 2001 From: Nodir Temirkhodjaev Date: Sat, 11 Mar 2023 12:11:27 +0300 Subject: [PATCH] UI: Fix service stopping on uninstall with "Disable Service controls" option --- deploy/FortFirewall.iss | 15 ++++++------ src/ui/manager/servicemanager.cpp | 1 + src/ui/util/service/servicemanageriface.h | 2 ++ src/ui/util/startuputil.cpp | 29 ++++++++++++++++------- 4 files changed, 32 insertions(+), 15 deletions(-) diff --git a/deploy/FortFirewall.iss b/deploy/FortFirewall.iss index 0187a879..32d188a8 100644 --- a/deploy/FortFirewall.iss +++ b/deploy/FortFirewall.iss @@ -174,7 +174,7 @@ begin if Form.ShowModal() = mrOk then begin - Result := GetSHA1OfString(PwdEdit.Text); + Result := PwdEdit.Text; end; finally Form.Free(); @@ -194,7 +194,7 @@ begin Exit; end; - if AskPassword() <> passwordHash then + if GetSHA1OfString(AskPassword()) <> passwordHash then begin SuppressibleMsgBox('Wrong password', mbError, MB_OK, IDOK); @@ -218,16 +218,17 @@ begin Result := CheckPasswordHash(); end; +function InitializeUninstall(): Boolean; +begin + Result := CheckPasswordHash(); +end; + function PrepareToInstall(var NeedsRestart: Boolean): String; var ResultCode: Integer; begin if Exec('sc.exe', ExpandConstant('stop {#APP_SVC_NAME}'), '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then if ResultCode = 0 then Sleep(100); // Let the service to stop + Result := ''; end; - -function InitializeUninstall(): Boolean; -begin - Result := CheckPasswordHash(); -end; diff --git a/src/ui/manager/servicemanager.cpp b/src/ui/manager/servicemanager.cpp index 6dc646d1..40d6ff4e 100644 --- a/src/ui/manager/servicemanager.cpp +++ b/src/ui/manager/servicemanager.cpp @@ -97,6 +97,7 @@ void ServiceManager::processControl(quint32 code) break; Q_FALLTHROUGH(); + case FORT_SERVICE_CONTROL_UNINSTALL: case SERVICE_CONTROL_SHUTDOWN: { qCDebug(LC) << "Quit due service control"; diff --git a/src/ui/util/service/servicemanageriface.h b/src/ui/util/service/servicemanageriface.h index adc2334d..81b35797 100644 --- a/src/ui/util/service/servicemanageriface.h +++ b/src/ui/util/service/servicemanageriface.h @@ -3,6 +3,8 @@ #include +#define FORT_SERVICE_CONTROL_UNINSTALL 128 + class ServiceManagerIface { public: diff --git a/src/ui/util/startuputil.cpp b/src/ui/util/startuputil.cpp index 6f988df2..8ae894f4 100644 --- a/src/ui/util/startuputil.cpp +++ b/src/ui/util/startuputil.cpp @@ -11,6 +11,7 @@ #include "fileutil.h" #include "regkey.h" +#include "service/servicemanageriface.h" namespace { @@ -134,6 +135,24 @@ bool installService(const wchar_t *serviceName, const wchar_t *serviceDisplay, return res; } +void stopService(SC_HANDLE svc) +{ + int n = 3; /* count of attempts to stop the service */ + do { + SERVICE_STATUS status; + if (QueryServiceStatus(svc, &status) && status.dwCurrentState == SERVICE_STOPPED) + break; + + const DWORD controlCode = (status.dwControlsAccepted & SERVICE_ACCEPT_STOP) != 0 + ? SERVICE_CONTROL_STOP + : FORT_SERVICE_CONTROL_UNINSTALL; + + ControlService(svc, controlCode, &status); + + QThread::msleep(n * 100); + } while (--n > 0); +} + bool uninstallService(const wchar_t *serviceName) { bool res = false; @@ -141,14 +160,8 @@ bool uninstallService(const wchar_t *serviceName) if (mngr) { const SC_HANDLE svc = OpenServiceW(mngr, serviceName, SERVICE_ALL_ACCESS | DELETE); if (svc) { - int n = 3; /* count of attempts to stop the service */ - do { - SERVICE_STATUS status; - if (QueryServiceStatus(svc, &status) && status.dwCurrentState == SERVICE_STOPPED) - break; - ControlService(svc, SERVICE_CONTROL_STOP, &status); - QThread::msleep(n * 100); - } while (--n > 0); + stopService(svc); + res = DeleteService(svc); CloseServiceHandle(svc); }