mirror of
https://github.com/golang/sys.git
synced 2026-02-09 12:16:04 +03:00
The two functions have the same levels of compatibility, but this latter one gives us access to the process ID, which is important for things like WFP whitelisting. The change required is fairly trivial too. Change-Id: Ifb6b3ee3e897202b9cffa1388c53c25cbcfede61 Reviewed-on: https://go-review.googlesource.com/c/sys/+/173666 Run-TryBot: Jason Donenfeld <Jason@zx2c4.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
76 lines
1.9 KiB
Go
76 lines
1.9 KiB
Go
// Copyright 2012 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// +build windows
|
|
|
|
package mgr
|
|
|
|
import (
|
|
"syscall"
|
|
"unsafe"
|
|
|
|
"golang.org/x/sys/windows"
|
|
"golang.org/x/sys/windows/svc"
|
|
)
|
|
|
|
// TODO(brainman): Use EnumDependentServices to enumerate dependent services.
|
|
|
|
// Service is used to access Windows service.
|
|
type Service struct {
|
|
Name string
|
|
Handle windows.Handle
|
|
}
|
|
|
|
// Delete marks service s for deletion from the service control manager database.
|
|
func (s *Service) Delete() error {
|
|
return windows.DeleteService(s.Handle)
|
|
}
|
|
|
|
// Close relinquish access to the service s.
|
|
func (s *Service) Close() error {
|
|
return windows.CloseServiceHandle(s.Handle)
|
|
}
|
|
|
|
// Start starts service s.
|
|
// args will be passed to svc.Handler.Execute.
|
|
func (s *Service) Start(args ...string) error {
|
|
var p **uint16
|
|
if len(args) > 0 {
|
|
vs := make([]*uint16, len(args))
|
|
for i := range vs {
|
|
vs[i] = syscall.StringToUTF16Ptr(args[i])
|
|
}
|
|
p = &vs[0]
|
|
}
|
|
return windows.StartService(s.Handle, uint32(len(args)), p)
|
|
}
|
|
|
|
// Control sends state change request c to the servce s.
|
|
func (s *Service) Control(c svc.Cmd) (svc.Status, error) {
|
|
var t windows.SERVICE_STATUS
|
|
err := windows.ControlService(s.Handle, uint32(c), &t)
|
|
if err != nil {
|
|
return svc.Status{}, err
|
|
}
|
|
return svc.Status{
|
|
State: svc.State(t.CurrentState),
|
|
Accepts: svc.Accepted(t.ControlsAccepted),
|
|
}, nil
|
|
}
|
|
|
|
// Query returns current status of service s.
|
|
func (s *Service) Query() (svc.Status, error) {
|
|
var t windows.SERVICE_STATUS_PROCESS
|
|
var needed uint32
|
|
err := windows.QueryServiceStatusEx(s.Handle, windows.SC_STATUS_PROCESS_INFO, (*byte)(unsafe.Pointer(&t)), uint32(unsafe.Sizeof(t)), &needed)
|
|
if err != nil {
|
|
return svc.Status{}, err
|
|
}
|
|
return svc.Status{
|
|
State: svc.State(t.CurrentState),
|
|
Accepts: svc.Accepted(t.ControlsAccepted),
|
|
ProcessId: t.ProcessId,
|
|
}, nil
|
|
}
|