diff --git a/deploy/FortFirewall.iss b/deploy/FortFirewall.iss index 6a377901..0d7a1e3c 100644 --- a/deploy/FortFirewall.iss +++ b/deploy/FortFirewall.iss @@ -17,7 +17,8 @@ ; Do not use the same AppId value in installers for other applications. ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) SetupMutex=Global\{#APP_BASE}Setup -; Don't use AppMutex, and auto-restart the running instances +; Don't use AppMutex +RestartApplications=no AppName={#APP_NAME} AppVersion={#APP_VERSION_STR} VersionInfoVersion={#APP_VERSION_STR} @@ -84,6 +85,7 @@ Name: "{commondesktop}\{#APP_NAME}"; Filename: "{#APP_EXE}"; WorkingDir: "{app}" [Run] ; 1. Uninstall -> 2. Install Driver -> 3. Portable -> 4. Service + Filename: "{#APP_EXE}"; Parameters: "-u most" Filename: "{app}\driver\scripts\reinstall.bat"; Parameters: {code:DriverInstallArgs}; \ @@ -311,12 +313,11 @@ begin Result := True; end; -function StopFortService(var ResultCode: Integer): Boolean; +function StopFortService(): Boolean; var path: String; + ResultCode: Integer; begin - ResultCode := -1; - path := ExpandConstant('{#APP_EXE}'); if not FileExists(path) then @@ -325,7 +326,7 @@ begin Exit; end; - Exec(path, '-s', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) + Exec(path, '-s', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) Result := (ResultCode = 0); end; @@ -446,15 +447,8 @@ begin 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 - begin - if ResultCode <> 0 then StopFortService(ResultCode); - - if ResultCode = 0 then Sleep(100); // Let the service to stop - end; + StopFortService(); Result := ''; end; diff --git a/deploy/out/FortFirewall-Silent.bat b/deploy/out/FortFirewall-Silent.bat index 993ba898..631c3351 100644 --- a/deploy/out/FortFirewall-Silent.bat +++ b/deploy/out/FortFirewall-Silent.bat @@ -1 +1 @@ -@for %%f in (FortFirewall-*.exe) do @call .\%%f /SILENT /LAUNCH +@for %%f in (FortFirewall-*.exe) do @call .\%%f /SILENT diff --git a/src/ui/FortFirewallUI.pro b/src/ui/FortFirewallUI.pro index ffa70451..72690bdf 100644 --- a/src/ui/FortFirewallUI.pro +++ b/src/ui/FortFirewallUI.pro @@ -428,6 +428,7 @@ HEADERS += \ util/osutil.h \ util/processinfo.h \ util/regkey.h \ + util/service/service_types.h \ util/service/servicehandle.h \ util/service/serviceinfo.h \ util/service/servicelistmonitor.h \ diff --git a/src/ui/manager/autoupdatemanager.cpp b/src/ui/manager/autoupdatemanager.cpp index 39c8d997..afcdac4e 100644 --- a/src/ui/manager/autoupdatemanager.cpp +++ b/src/ui/manager/autoupdatemanager.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -80,11 +81,13 @@ void AutoUpdateManager::setupManager() void AutoUpdateManager::setupRestart() { - if (IoC()->isService()) - return; - - if (!OsUtil::registerAppRestart()) { - qCWarning(LC) << "Restart registration error"; + if (IoC()->isService()) { + connect(IoC(), &ServiceManager::stopRestartingRequested, this, + &AutoUpdateManager::restartClients); + } else { + if (!OsUtil::registerAppRestart()) { + qCWarning(LC) << "Restart registration error"; + } } } diff --git a/src/ui/manager/servicemanager.cpp b/src/ui/manager/servicemanager.cpp index c8a79f04..79db121e 100644 --- a/src/ui/manager/servicemanager.cpp +++ b/src/ui/manager/servicemanager.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include namespace { @@ -106,14 +107,14 @@ void ServiceManager::processControl(quint32 code, quint32 eventType) state = SERVICE_RUNNING; } break; case SERVICE_CONTROL_STOP: { - if (!acceptStop()) - break; + state = acceptStop() ? SERVICE_STOP_PENDING : 0; + } break; + case ServiceControlStopRestarting: { + emit stopRestartingRequested(); } Q_FALLTHROUGH(); - case FORT_SERVICE_CONTROL_UNINSTALL: + case ServiceControlStop: case SERVICE_CONTROL_SHUTDOWN: { - OsUtil::quit("service control"); // it's threadsafe - state = SERVICE_STOP_PENDING; } break; case SERVICE_CONTROL_DEVICEEVENT: { @@ -123,6 +124,10 @@ void ServiceManager::processControl(quint32 code, quint32 eventType) } break; } + if (state == SERVICE_STOP_PENDING) { + OsUtil::quit("service control"); // it's threadsafe + } + reportStatus(state); } diff --git a/src/ui/manager/servicemanager.h b/src/ui/manager/servicemanager.h index b7c51a46..c1d921b7 100644 --- a/src/ui/manager/servicemanager.h +++ b/src/ui/manager/servicemanager.h @@ -34,6 +34,7 @@ public: signals: void pauseRequested(); void continueRequested(); + void stopRestartingRequested(); void driveListChanged(); protected: diff --git a/src/ui/util/service/service_types.h b/src/ui/util/service/service_types.h new file mode 100644 index 00000000..d36e154f --- /dev/null +++ b/src/ui/util/service/service_types.h @@ -0,0 +1,9 @@ +#ifndef SERVICE_TYPES_H +#define SERVICE_TYPES_H + +enum ServiceControlCode { + ServiceControlStop = 128, + ServiceControlStopRestarting, +}; + +#endif // SERVICE_TYPES_H diff --git a/src/ui/util/service/servicehandle.cpp b/src/ui/util/service/servicehandle.cpp index ce4c2092..07cebd74 100644 --- a/src/ui/util/service/servicehandle.cpp +++ b/src/ui/util/service/servicehandle.cpp @@ -5,6 +5,7 @@ #define WIN32_LEAN_AND_MEAN #include +#include "service_types.h" #include "servicemanageriface.h" ServiceHandle::ServiceHandle( @@ -32,7 +33,7 @@ bool ServiceHandle::startService() return StartServiceW(SC_HANDLE(m_serviceHandle), 0, nullptr); } -bool ServiceHandle::stopService() +bool ServiceHandle::stopService(bool restarting) { int n = 3; /* count of attempts to stop the service */ do { @@ -41,9 +42,7 @@ bool ServiceHandle::stopService() && status.dwCurrentState == SERVICE_STOPPED) return true; - const DWORD controlCode = (status.dwControlsAccepted & SERVICE_ACCEPT_STOP) != 0 - ? SERVICE_CONTROL_STOP - : FORT_SERVICE_CONTROL_UNINSTALL; + const DWORD controlCode = restarting ? ServiceControlStopRestarting : ServiceControlStop; ControlService(SC_HANDLE(m_serviceHandle), controlCode, &status); diff --git a/src/ui/util/service/servicehandle.h b/src/ui/util/service/servicehandle.h index 2af1eeba..45cc6bca 100644 --- a/src/ui/util/service/servicehandle.h +++ b/src/ui/util/service/servicehandle.h @@ -26,7 +26,7 @@ public: bool queryIsRunning(); bool startService(); - bool stopService(); + bool stopService(bool restarting = false); bool createService(const CreateServiceArg &csa); bool deleteService(); diff --git a/src/ui/util/service/servicemanageriface.h b/src/ui/util/service/servicemanageriface.h index fdf85711..8f495d90 100644 --- a/src/ui/util/service/servicemanageriface.h +++ b/src/ui/util/service/servicemanageriface.h @@ -3,8 +3,6 @@ #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 8a296343..a616256b 100644 --- a/src/ui/util/startuputil.cpp +++ b/src/ui/util/startuputil.cpp @@ -179,7 +179,7 @@ bool StartupUtil::stopService() { ServiceHandle svc(serviceNameStr, SC_MANAGER_ALL_ACCESS, SERVICE_ALL_ACCESS); if (svc.isServiceOpened()) { - return svc.stopService(); + return svc.stopService(/*restarting=*/true); } return false;