/usr/share/gocode/src/golang.org/x/sys/windows/svc/mgr/config.go is in golang-golang-x-sys-dev 0.0~git20150612-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | // 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"
"unicode/utf16"
"unsafe"
"golang.org/x/sys/windows"
)
const (
// Service start types.
StartManual = windows.SERVICE_DEMAND_START // the service must be started manually
StartAutomatic = windows.SERVICE_AUTO_START // the service will start by itself whenever the computer reboots
StartDisabled = windows.SERVICE_DISABLED // the service cannot be started
// The severity of the error, and action taken,
// if this service fails to start.
ErrorCritical = windows.SERVICE_ERROR_CRITICAL
ErrorIgnore = windows.SERVICE_ERROR_IGNORE
ErrorNormal = windows.SERVICE_ERROR_NORMAL
ErrorSevere = windows.SERVICE_ERROR_SEVERE
)
// TODO(brainman): Password is not returned by windows.QueryServiceConfig, not sure how to get it.
type Config struct {
ServiceType uint32
StartType uint32
ErrorControl uint32
BinaryPathName string // fully qualified path to the service binary file, can also include arguments for an auto-start service
LoadOrderGroup string
TagId uint32
Dependencies []string
ServiceStartName string // name of the account under which the service should run
DisplayName string
Password string
Description string
}
func toString(p *uint16) string {
if p == nil {
return ""
}
return syscall.UTF16ToString((*[4096]uint16)(unsafe.Pointer(p))[:])
}
func toStringSlice(ps *uint16) []string {
if ps == nil {
return nil
}
r := make([]string, 0)
for from, i, p := 0, 0, (*[1 << 24]uint16)(unsafe.Pointer(ps)); true; i++ {
if p[i] == 0 {
// empty string marks the end
if i <= from {
break
}
r = append(r, string(utf16.Decode(p[from:i])))
from = i + 1
}
}
return r
}
// Config retrieves service s configuration paramteres.
func (s *Service) Config() (Config, error) {
var p *windows.QUERY_SERVICE_CONFIG
n := uint32(1024)
for {
b := make([]byte, n)
p = (*windows.QUERY_SERVICE_CONFIG)(unsafe.Pointer(&b[0]))
err := windows.QueryServiceConfig(s.Handle, p, n, &n)
if err == nil {
break
}
if err.(syscall.Errno) != syscall.ERROR_INSUFFICIENT_BUFFER {
return Config{}, err
}
if n <= uint32(len(b)) {
return Config{}, err
}
}
var p2 *windows.SERVICE_DESCRIPTION
n = uint32(1024)
for {
b := make([]byte, n)
p2 = (*windows.SERVICE_DESCRIPTION)(unsafe.Pointer(&b[0]))
err := windows.QueryServiceConfig2(s.Handle,
windows.SERVICE_CONFIG_DESCRIPTION, &b[0], n, &n)
if err == nil {
break
}
if err.(syscall.Errno) != syscall.ERROR_INSUFFICIENT_BUFFER {
return Config{}, err
}
if n <= uint32(len(b)) {
return Config{}, err
}
}
return Config{
ServiceType: p.ServiceType,
StartType: p.StartType,
ErrorControl: p.ErrorControl,
BinaryPathName: toString(p.BinaryPathName),
LoadOrderGroup: toString(p.LoadOrderGroup),
TagId: p.TagId,
Dependencies: toStringSlice(p.Dependencies),
ServiceStartName: toString(p.ServiceStartName),
DisplayName: toString(p.DisplayName),
Description: toString(p2.Description),
}, nil
}
func updateDescription(handle windows.Handle, desc string) error {
d := windows.SERVICE_DESCRIPTION{toPtr(desc)}
return windows.ChangeServiceConfig2(handle,
windows.SERVICE_CONFIG_DESCRIPTION, (*byte)(unsafe.Pointer(&d)))
}
// UpdateConfig updates service s configuration parameters.
func (s *Service) UpdateConfig(c Config) error {
err := windows.ChangeServiceConfig(s.Handle, c.ServiceType, c.StartType,
c.ErrorControl, toPtr(c.BinaryPathName), toPtr(c.LoadOrderGroup),
nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName),
toPtr(c.Password), toPtr(c.DisplayName))
if err != nil {
return err
}
return updateDescription(s.Handle, c.Description)
}
|