initial commit
[govpp.git] / vendor / golang.org / x / sys / windows / svc / mgr / mgr.go
1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // +build windows
6
7 // Package mgr can be used to manage Windows service programs.
8 // It can be used to install and remove them. It can also start,
9 // stop and pause them. The package can query / change current
10 // service state and config parameters.
11 //
12 package mgr
13
14 import (
15         "syscall"
16         "unicode/utf16"
17
18         "golang.org/x/sys/windows"
19 )
20
21 // Mgr is used to manage Windows service.
22 type Mgr struct {
23         Handle windows.Handle
24 }
25
26 // Connect establishes a connection to the service control manager.
27 func Connect() (*Mgr, error) {
28         return ConnectRemote("")
29 }
30
31 // ConnectRemote establishes a connection to the
32 // service control manager on computer named host.
33 func ConnectRemote(host string) (*Mgr, error) {
34         var s *uint16
35         if host != "" {
36                 s = syscall.StringToUTF16Ptr(host)
37         }
38         h, err := windows.OpenSCManager(s, nil, windows.SC_MANAGER_ALL_ACCESS)
39         if err != nil {
40                 return nil, err
41         }
42         return &Mgr{Handle: h}, nil
43 }
44
45 // Disconnect closes connection to the service control manager m.
46 func (m *Mgr) Disconnect() error {
47         return windows.CloseServiceHandle(m.Handle)
48 }
49
50 func toPtr(s string) *uint16 {
51         if len(s) == 0 {
52                 return nil
53         }
54         return syscall.StringToUTF16Ptr(s)
55 }
56
57 // toStringBlock terminates strings in ss with 0, and then
58 // concatenates them together. It also adds extra 0 at the end.
59 func toStringBlock(ss []string) *uint16 {
60         if len(ss) == 0 {
61                 return nil
62         }
63         t := ""
64         for _, s := range ss {
65                 if s != "" {
66                         t += s + "\x00"
67                 }
68         }
69         if t == "" {
70                 return nil
71         }
72         t += "\x00"
73         return &utf16.Encode([]rune(t))[0]
74 }
75
76 // CreateService installs new service name on the system.
77 // The service will be executed by running exepath binary.
78 // Use config c to specify service parameters.
79 // If service StartType is set to StartAutomatic,
80 // args will be passed to svc.Handle.Execute.
81 func (m *Mgr) CreateService(name, exepath string, c Config, args ...string) (*Service, error) {
82         if c.StartType == 0 {
83                 c.StartType = StartManual
84         }
85         if c.ErrorControl == 0 {
86                 c.ErrorControl = ErrorNormal
87         }
88         if c.ServiceType == 0 {
89                 c.ServiceType = windows.SERVICE_WIN32_OWN_PROCESS
90         }
91         s := syscall.EscapeArg(exepath)
92         for _, v := range args {
93                 s += " " + syscall.EscapeArg(v)
94         }
95         h, err := windows.CreateService(m.Handle, toPtr(name), toPtr(c.DisplayName),
96                 windows.SERVICE_ALL_ACCESS, c.ServiceType,
97                 c.StartType, c.ErrorControl, toPtr(s), toPtr(c.LoadOrderGroup),
98                 nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName), toPtr(c.Password))
99         if err != nil {
100                 return nil, err
101         }
102         if c.Description != "" {
103                 err = updateDescription(h, c.Description)
104                 if err != nil {
105                         return nil, err
106                 }
107         }
108         return &Service{Name: name, Handle: h}, nil
109 }
110
111 // OpenService retrieves access to service name, so it can
112 // be interrogated and controlled.
113 func (m *Mgr) OpenService(name string) (*Service, error) {
114         h, err := windows.OpenService(m.Handle, syscall.StringToUTF16Ptr(name), windows.SERVICE_ALL_ACCESS)
115         if err != nil {
116                 return nil, err
117         }
118         return &Service{Name: name, Handle: h}, nil
119 }