From db8ea88b2529b0845053ec364584eb8fc3324aa9 Mon Sep 17 00:00:00 2001 From: Lewis Waddicor Date: Mon, 7 Sep 2020 20:07:23 +0100 Subject: [PATCH] windows: support service PreShutdown service control signal This adds support for the PreShutdown signal indicating the system will be shutting down. This allows services which need time to shutdown gracefully to use SERVICE_ACCEPT_PRESHUTDOWN to register for SERVICE_CONTROL_PRESHUTDOWN events. https://docs.microsoft.com/en-us/windows/win32/api/winsvc/nc-winsvc-lphandler_function_ex?redirectedfrom=MSDN --- windows/service.go | 2 ++ windows/svc/service.go | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/windows/service.go b/windows/service.go index 847e00bc..f54ff90a 100644 --- a/windows/service.go +++ b/windows/service.go @@ -65,6 +65,7 @@ const ( SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 32 SERVICE_ACCEPT_POWEREVENT = 64 SERVICE_ACCEPT_SESSIONCHANGE = 128 + SERVICE_ACCEPT_PRESHUTDOWN = 256 SERVICE_CONTROL_STOP = 1 SERVICE_CONTROL_PAUSE = 2 @@ -80,6 +81,7 @@ const ( SERVICE_CONTROL_HARDWAREPROFILECHANGE = 12 SERVICE_CONTROL_POWEREVENT = 13 SERVICE_CONTROL_SESSIONCHANGE = 14 + SERVICE_CONTROL_PRESHUTDOWN = 15 SERVICE_ACTIVE = 1 SERVICE_INACTIVE = 2 diff --git a/windows/svc/service.go b/windows/svc/service.go index bae818dd..f7f4ff5b 100644 --- a/windows/svc/service.go +++ b/windows/svc/service.go @@ -50,6 +50,7 @@ const ( HardwareProfileChange = Cmd(windows.SERVICE_CONTROL_HARDWAREPROFILECHANGE) PowerEvent = Cmd(windows.SERVICE_CONTROL_POWEREVENT) SessionChange = Cmd(windows.SERVICE_CONTROL_SESSIONCHANGE) + PreShutdown = Cmd(windows.SERVICE_CONTROL_PRESHUTDOWN) ) // Accepted is used to describe commands accepted by the service. @@ -65,6 +66,7 @@ const ( AcceptHardwareProfileChange = Accepted(windows.SERVICE_ACCEPT_HARDWAREPROFILECHANGE) AcceptPowerEvent = Accepted(windows.SERVICE_ACCEPT_POWEREVENT) AcceptSessionChange = Accepted(windows.SERVICE_ACCEPT_SESSIONCHANGE) + AcceptPreShutdown = Accepted(windows.SERVICE_ACCEPT_PRESHUTDOWN) ) // Status combines State and Accepted commands to fully describe running service. @@ -202,6 +204,9 @@ func (s *service) updateStatus(status *Status, ec *exitCode) error { if status.Accepts&AcceptSessionChange != 0 { t.ControlsAccepted |= windows.SERVICE_ACCEPT_SESSIONCHANGE } + if status.Accepts&AcceptPreShutdown != 0 { + t.ControlsAccepted |= windows.SERVICE_ACCEPT_PRESHUTDOWN + } if ec.errno == 0 { t.Win32ExitCode = windows.NO_ERROR t.ServiceSpecificExitCode = windows.NO_ERROR