Browse code

Windows: Support running dockerd as a service

This adds support for Windows dockerd to run as a Windows service, managed
by the service control manager. The log is written to the Windows event
log (and can be viewed in the event viewer or in PowerShell). If there is
a Go panic, the stack is written to a file panic.log in the Docker root.

Signed-off-by: John Starks <jostarks@microsoft.com>

John Starks authored on 2016/04/23 09:16:14
Showing 49 changed files
... ...
@@ -1,5 +1,5 @@
1 1
 package main
2 2
 
3 3
 import (
4
-	_ "github.com/docker/docker/autogen/winresources/dockerd"
4
+	_ "github.com/docker/docker/autogen/winresources/docker"
5 5
 )
... ...
@@ -53,6 +53,9 @@ type DaemonCli struct {
53 53
 	*daemon.Config
54 54
 	commonFlags *cli.CommonFlags
55 55
 	configFile  *string
56
+
57
+	api *apiserver.Server
58
+	d   *daemon.Daemon
56 59
 }
57 60
 
58 61
 func presentInHelp(usage string) string { return usage }
... ...
@@ -121,7 +124,10 @@ func migrateKey() (err error) {
121 121
 	return nil
122 122
 }
123 123
 
124
-func (cli *DaemonCli) start() {
124
+func (cli *DaemonCli) start() (err error) {
125
+	stopc := make(chan bool)
126
+	defer close(stopc)
127
+
125 128
 	// warn from uuid package when running the daemon
126 129
 	uuid.Loggerf = logrus.Warnf
127 130
 
... ...
@@ -133,8 +139,7 @@ func (cli *DaemonCli) start() {
133 133
 	}
134 134
 	cliConfig, err := loadDaemonCliConfig(cli.Config, flags, cli.commonFlags, *cli.configFile)
135 135
 	if err != nil {
136
-		fmt.Fprint(os.Stderr, err)
137
-		os.Exit(1)
136
+		return err
138 137
 	}
139 138
 	cli.Config = cliConfig
140 139
 
... ...
@@ -152,24 +157,22 @@ func (cli *DaemonCli) start() {
152 152
 	})
153 153
 
154 154
 	if err := setDefaultUmask(); err != nil {
155
-		logrus.Fatalf("Failed to set umask: %v", err)
155
+		return fmt.Errorf("Failed to set umask: %v", err)
156 156
 	}
157 157
 
158 158
 	if len(cli.LogConfig.Config) > 0 {
159 159
 		if err := logger.ValidateLogOpts(cli.LogConfig.Type, cli.LogConfig.Config); err != nil {
160
-			logrus.Fatalf("Failed to set log opts: %v", err)
160
+			return fmt.Errorf("Failed to set log opts: %v", err)
161 161
 		}
162 162
 	}
163 163
 
164
-	var pfile *pidfile.PIDFile
165 164
 	if cli.Pidfile != "" {
166 165
 		pf, err := pidfile.New(cli.Pidfile)
167 166
 		if err != nil {
168
-			logrus.Fatalf("Error starting daemon: %v", err)
167
+			return fmt.Errorf("Error starting daemon: %v", err)
169 168
 		}
170
-		pfile = pf
171 169
 		defer func() {
172
-			if err := pfile.Remove(); err != nil {
170
+			if err := pf.Remove(); err != nil {
173 171
 				logrus.Error(err)
174 172
 			}
175 173
 		}()
... ...
@@ -196,7 +199,7 @@ func (cli *DaemonCli) start() {
196 196
 		}
197 197
 		tlsConfig, err := tlsconfig.Server(tlsOptions)
198 198
 		if err != nil {
199
-			logrus.Fatal(err)
199
+			return err
200 200
 		}
201 201
 		serverConfig.TLSConfig = tlsConfig
202 202
 	}
... ...
@@ -210,13 +213,13 @@ func (cli *DaemonCli) start() {
210 210
 	for i := 0; i < len(cli.Config.Hosts); i++ {
211 211
 		var err error
212 212
 		if cli.Config.Hosts[i], err = opts.ParseHost(cli.Config.TLS, cli.Config.Hosts[i]); err != nil {
213
-			logrus.Fatalf("error parsing -H %s : %v", cli.Config.Hosts[i], err)
213
+			return fmt.Errorf("error parsing -H %s : %v", cli.Config.Hosts[i], err)
214 214
 		}
215 215
 
216 216
 		protoAddr := cli.Config.Hosts[i]
217 217
 		protoAddrParts := strings.SplitN(protoAddr, "://", 2)
218 218
 		if len(protoAddrParts) != 2 {
219
-			logrus.Fatalf("bad format %s, expected PROTO://ADDR", protoAddr)
219
+			return fmt.Errorf("bad format %s, expected PROTO://ADDR", protoAddr)
220 220
 		}
221 221
 
222 222
 		proto := protoAddrParts[0]
... ...
@@ -228,12 +231,12 @@ func (cli *DaemonCli) start() {
228 228
 		}
229 229
 		l, err := listeners.Init(proto, addr, serverConfig.SocketGroup, serverConfig.TLSConfig)
230 230
 		if err != nil {
231
-			logrus.Fatal(err)
231
+			return err
232 232
 		}
233 233
 		// If we're binding to a TCP port, make sure that a container doesn't try to use it.
234 234
 		if proto == "tcp" {
235 235
 			if err := allocateDaemonPort(addr); err != nil {
236
-				logrus.Fatal(err)
236
+				return err
237 237
 			}
238 238
 		}
239 239
 		logrus.Debugf("Listener created for HTTP on %s (%s)", protoAddrParts[0], protoAddrParts[1])
... ...
@@ -241,24 +244,19 @@ func (cli *DaemonCli) start() {
241 241
 	}
242 242
 
243 243
 	if err := migrateKey(); err != nil {
244
-		logrus.Fatal(err)
244
+		return err
245 245
 	}
246 246
 	cli.TrustKeyPath = cli.commonFlags.TrustKey
247 247
 
248 248
 	registryService := registry.NewService(cli.Config.ServiceOptions)
249 249
 	containerdRemote, err := libcontainerd.New(cli.getLibcontainerdRoot(), cli.getPlatformRemoteOptions()...)
250 250
 	if err != nil {
251
-		logrus.Fatal(err)
251
+		return err
252 252
 	}
253 253
 
254 254
 	d, err := daemon.NewDaemon(cli.Config, registryService, containerdRemote)
255 255
 	if err != nil {
256
-		if pfile != nil {
257
-			if err := pfile.Remove(); err != nil {
258
-				logrus.Error(err)
259
-			}
260
-		}
261
-		logrus.Fatalf("Error starting daemon: %v", err)
256
+		return fmt.Errorf("Error starting daemon: %v", err)
262 257
 	}
263 258
 
264 259
 	logrus.Info("Daemon has completed initialization")
... ...
@@ -272,26 +270,9 @@ func (cli *DaemonCli) start() {
272 272
 	cli.initMiddlewares(api, serverConfig)
273 273
 	initRouter(api, d)
274 274
 
275
-	reload := func(config *daemon.Config) {
276
-		if err := d.Reload(config); err != nil {
277
-			logrus.Errorf("Error reconfiguring the daemon: %v", err)
278
-			return
279
-		}
280
-		if config.IsValueSet("debug") {
281
-			debugEnabled := utils.IsDebugEnabled()
282
-			switch {
283
-			case debugEnabled && !config.Debug: // disable debug
284
-				utils.DisableDebug()
285
-				api.DisableProfiler()
286
-			case config.Debug && !debugEnabled: // enable debug
287
-				utils.EnableDebug()
288
-				api.EnableProfiler()
289
-			}
290
-
291
-		}
292
-	}
293
-
294
-	setupConfigReloadTrap(*cli.configFile, flags, reload)
275
+	cli.d = d
276
+	cli.api = api
277
+	cli.setupConfigReloadTrap()
295 278
 
296 279
 	// The serve API routine never exits unless an error occurs
297 280
 	// We need to start it as a goroutine and wait on it so
... ...
@@ -300,14 +281,8 @@ func (cli *DaemonCli) start() {
300 300
 	go api.Wait(serveAPIWait)
301 301
 
302 302
 	signal.Trap(func() {
303
-		api.Close()
304
-		<-serveAPIWait
305
-		shutdownDaemon(d, 15)
306
-		if pfile != nil {
307
-			if err := pfile.Remove(); err != nil {
308
-				logrus.Error(err)
309
-			}
310
-		}
303
+		cli.stop()
304
+		<-stopc // wait for daemonCli.start() to return
311 305
 	})
312 306
 
313 307
 	// after the daemon is done setting up we can notify systemd api
... ...
@@ -319,13 +294,39 @@ func (cli *DaemonCli) start() {
319 319
 	shutdownDaemon(d, 15)
320 320
 	containerdRemote.Cleanup()
321 321
 	if errAPI != nil {
322
-		if pfile != nil {
323
-			if err := pfile.Remove(); err != nil {
324
-				logrus.Error(err)
322
+		return fmt.Errorf("Shutting down due to ServeAPI error: %v", errAPI)
323
+	}
324
+
325
+	return nil
326
+}
327
+
328
+func (cli *DaemonCli) reloadConfig() {
329
+	reload := func(config *daemon.Config) {
330
+		if err := cli.d.Reload(config); err != nil {
331
+			logrus.Errorf("Error reconfiguring the daemon: %v", err)
332
+			return
333
+		}
334
+		if config.IsValueSet("debug") {
335
+			debugEnabled := utils.IsDebugEnabled()
336
+			switch {
337
+			case debugEnabled && !config.Debug: // disable debug
338
+				utils.DisableDebug()
339
+				cli.api.DisableProfiler()
340
+			case config.Debug && !debugEnabled: // enable debug
341
+				utils.EnableDebug()
342
+				cli.api.EnableProfiler()
325 343
 			}
344
+
326 345
 		}
327
-		logrus.Fatalf("Shutting down due to ServeAPI error: %v", errAPI)
328 346
 	}
347
+
348
+	if err := daemon.ReloadConfiguration(*cli.configFile, flag.CommandLine, reload); err != nil {
349
+		logrus.Error(err)
350
+	}
351
+}
352
+
353
+func (cli *DaemonCli) stop() {
354
+	cli.api.Close()
329 355
 }
330 356
 
331 357
 // shutdownDaemon just wraps daemon.Shutdown() to handle a timeout in case
... ...
@@ -11,10 +11,8 @@ import (
11 11
 	"strconv"
12 12
 	"syscall"
13 13
 
14
-	"github.com/Sirupsen/logrus"
15 14
 	"github.com/docker/docker/daemon"
16 15
 	"github.com/docker/docker/libcontainerd"
17
-	"github.com/docker/docker/pkg/mflag"
18 16
 	"github.com/docker/docker/pkg/system"
19 17
 	"github.com/docker/libnetwork/portallocator"
20 18
 )
... ...
@@ -49,14 +47,12 @@ func getDaemonConfDir() string {
49 49
 }
50 50
 
51 51
 // setupConfigReloadTrap configures the USR2 signal to reload the configuration.
52
-func setupConfigReloadTrap(configFile string, flags *mflag.FlagSet, reload func(*daemon.Config)) {
52
+func (cli *DaemonCli) setupConfigReloadTrap() {
53 53
 	c := make(chan os.Signal, 1)
54 54
 	signal.Notify(c, syscall.SIGHUP)
55 55
 	go func() {
56 56
 		for range c {
57
-			if err := daemon.ReloadConfiguration(configFile, flags, reload); err != nil {
58
-				logrus.Error(err)
59
-			}
57
+			cli.reloadConfig()
60 58
 		}
61 59
 	}()
62 60
 }
... ...
@@ -111,3 +107,7 @@ func allocateDaemonPort(addr string) error {
111 111
 	}
112 112
 	return nil
113 113
 }
114
+
115
+// notifyShutdown is called after the daemon shuts down but before the process exits.
116
+func notifyShutdown(err error) {
117
+}
... ...
@@ -6,9 +6,7 @@ import (
6 6
 	"syscall"
7 7
 
8 8
 	"github.com/Sirupsen/logrus"
9
-	"github.com/docker/docker/daemon"
10 9
 	"github.com/docker/docker/libcontainerd"
11
-	"github.com/docker/docker/pkg/mflag"
12 10
 	"github.com/docker/docker/pkg/system"
13 11
 )
14 12
 
... ...
@@ -31,10 +29,23 @@ func getDaemonConfDir() string {
31 31
 
32 32
 // notifySystem sends a message to the host when the server is ready to be used
33 33
 func notifySystem() {
34
+	if service != nil {
35
+		err := service.started()
36
+		if err != nil {
37
+			logrus.Fatal(err)
38
+		}
39
+	}
40
+}
41
+
42
+// notifyShutdown is called after the daemon shuts down but before the process exits.
43
+func notifyShutdown(err error) {
44
+	if service != nil {
45
+		service.stopped(err)
46
+	}
34 47
 }
35 48
 
36 49
 // setupConfigReloadTrap configures a Win32 event to reload the configuration.
37
-func setupConfigReloadTrap(configFile string, flags *mflag.FlagSet, reload func(*daemon.Config)) {
50
+func (cli *DaemonCli) setupConfigReloadTrap() {
38 51
 	go func() {
39 52
 		sa := syscall.SecurityAttributes{
40 53
 			Length: 0,
... ...
@@ -44,9 +55,7 @@ func setupConfigReloadTrap(configFile string, flags *mflag.FlagSet, reload func(
44 44
 			logrus.Debugf("Config reload - waiting signal at %s", ev)
45 45
 			for {
46 46
 				syscall.WaitForSingleObject(h, syscall.INFINITE)
47
-				if err := daemon.ReloadConfiguration(configFile, flags, reload); err != nil {
48
-					logrus.Error(err)
49
-				}
47
+				cli.reloadConfig()
50 48
 			}
51 49
 		}
52 50
 	}()
... ...
@@ -56,7 +56,21 @@ func main() {
56 56
 		flag.Usage()
57 57
 		return
58 58
 	}
59
-	daemonCli.start()
59
+
60
+	// On Windows, this may be launching as a service or with an option to
61
+	// register the service.
62
+	stop, err := initService()
63
+	if err != nil {
64
+		logrus.Fatal(err)
65
+	}
66
+
67
+	if !stop {
68
+		err = daemonCli.start()
69
+		notifyShutdown(err)
70
+		if err != nil {
71
+			logrus.Fatal(err)
72
+		}
73
+	}
60 74
 }
61 75
 
62 76
 func showVersion() {
... ...
@@ -1,5 +1,5 @@
1 1
 package main
2 2
 
3 3
 import (
4
-	_ "github.com/docker/docker/autogen/winresources/docker"
4
+	_ "github.com/docker/docker/autogen/winresources/dockerd"
5 5
 )
6 6
new file mode 100644
... ...
@@ -0,0 +1,7 @@
0
+// +build !windows
1
+
2
+package main
3
+
4
+func initService() (bool, error) {
5
+	return false, nil
6
+}
0 7
new file mode 100644
... ...
@@ -0,0 +1,369 @@
0
+package main
1
+
2
+import (
3
+	"bytes"
4
+	"errors"
5
+	"fmt"
6
+	"io/ioutil"
7
+	"os"
8
+	"os/exec"
9
+	"path/filepath"
10
+	"syscall"
11
+
12
+	"github.com/Sirupsen/logrus"
13
+	flag "github.com/docker/docker/pkg/mflag"
14
+	"golang.org/x/sys/windows"
15
+	"golang.org/x/sys/windows/svc"
16
+	"golang.org/x/sys/windows/svc/debug"
17
+	"golang.org/x/sys/windows/svc/eventlog"
18
+	"golang.org/x/sys/windows/svc/mgr"
19
+)
20
+
21
+var (
22
+	flServiceName       = flag.String([]string{"-service-name"}, "docker", "Set the Windows service name")
23
+	flRegisterService   = flag.Bool([]string{"-register-service"}, false, "Register the service and exit")
24
+	flUnregisterService = flag.Bool([]string{"-unregister-service"}, false, "Unregister the service and exit")
25
+	flRunService        = flag.Bool([]string{"-run-service"}, false, "")
26
+
27
+	setStdHandle = syscall.NewLazyDLL("kernel32.dll").NewProc("SetStdHandle")
28
+	oldStderr    syscall.Handle
29
+	panicFile    *os.File
30
+
31
+	service *handler
32
+)
33
+
34
+const (
35
+	// These should match the values in event_messages.mc.
36
+	eventInfo  = 1
37
+	eventWarn  = 1
38
+	eventError = 1
39
+	eventDebug = 2
40
+	eventPanic = 3
41
+	eventFatal = 4
42
+
43
+	eventExtraOffset = 10 // Add this to any event to get a string that supports extended data
44
+)
45
+
46
+type handler struct {
47
+	tosvc   chan bool
48
+	fromsvc chan error
49
+}
50
+
51
+type etwHook struct {
52
+	log *eventlog.Log
53
+}
54
+
55
+func (h *etwHook) Levels() []logrus.Level {
56
+	return []logrus.Level{
57
+		logrus.PanicLevel,
58
+		logrus.FatalLevel,
59
+		logrus.ErrorLevel,
60
+		logrus.WarnLevel,
61
+		logrus.InfoLevel,
62
+		logrus.DebugLevel,
63
+	}
64
+}
65
+
66
+func (h *etwHook) Fire(e *logrus.Entry) error {
67
+	var (
68
+		etype uint16
69
+		eid   uint32
70
+	)
71
+
72
+	switch e.Level {
73
+	case logrus.PanicLevel:
74
+		etype = windows.EVENTLOG_ERROR_TYPE
75
+		eid = eventPanic
76
+	case logrus.FatalLevel:
77
+		etype = windows.EVENTLOG_ERROR_TYPE
78
+		eid = eventFatal
79
+	case logrus.ErrorLevel:
80
+		etype = windows.EVENTLOG_ERROR_TYPE
81
+		eid = eventError
82
+	case logrus.WarnLevel:
83
+		etype = windows.EVENTLOG_WARNING_TYPE
84
+		eid = eventWarn
85
+	case logrus.InfoLevel:
86
+		etype = windows.EVENTLOG_INFORMATION_TYPE
87
+		eid = eventInfo
88
+	case logrus.DebugLevel:
89
+		etype = windows.EVENTLOG_INFORMATION_TYPE
90
+		eid = eventDebug
91
+	default:
92
+		return errors.New("unknown level")
93
+	}
94
+
95
+	// If there is additional data, include it as a second string.
96
+	exts := ""
97
+	if len(e.Data) > 0 {
98
+		fs := bytes.Buffer{}
99
+		for k, v := range e.Data {
100
+			fs.WriteString(k)
101
+			fs.WriteByte('=')
102
+			fmt.Fprint(&fs, v)
103
+			fs.WriteByte(' ')
104
+		}
105
+
106
+		exts = fs.String()[:fs.Len()-1]
107
+		eid += eventExtraOffset
108
+	}
109
+
110
+	if h.log == nil {
111
+		fmt.Fprintf(os.Stderr, "%s [%s]\n", e.Message, exts)
112
+		return nil
113
+	}
114
+
115
+	var (
116
+		ss  [2]*uint16
117
+		err error
118
+	)
119
+
120
+	ss[0], err = syscall.UTF16PtrFromString(e.Message)
121
+	if err != nil {
122
+		return err
123
+	}
124
+
125
+	count := uint16(1)
126
+	if exts != "" {
127
+		ss[1], err = syscall.UTF16PtrFromString(exts)
128
+		if err != nil {
129
+			return err
130
+		}
131
+
132
+		count++
133
+	}
134
+
135
+	return windows.ReportEvent(h.log.Handle, etype, 0, eid, 0, count, 0, &ss[0], nil)
136
+}
137
+
138
+func getServicePath() (string, error) {
139
+	p, err := exec.LookPath(os.Args[0])
140
+	if err != nil {
141
+		return "", err
142
+	}
143
+	return filepath.Abs(p)
144
+}
145
+
146
+func registerService() error {
147
+	p, err := getServicePath()
148
+	if err != nil {
149
+		return err
150
+	}
151
+	m, err := mgr.Connect()
152
+	if err != nil {
153
+		return err
154
+	}
155
+	defer m.Disconnect()
156
+	c := mgr.Config{
157
+		ServiceType:  windows.SERVICE_WIN32_OWN_PROCESS,
158
+		StartType:    mgr.StartAutomatic,
159
+		ErrorControl: mgr.ErrorNormal,
160
+		DisplayName:  "Docker Engine",
161
+	}
162
+
163
+	// Configure the service to launch with the arguments that were just passed.
164
+	args := []string{"--run-service"}
165
+	for _, a := range os.Args[1:] {
166
+		if a != "--register-service" && a != "--unregister-service" {
167
+			args = append(args, a)
168
+		}
169
+	}
170
+
171
+	s, err := m.CreateService(*flServiceName, p, c, args...)
172
+	if err != nil {
173
+		return err
174
+	}
175
+	defer s.Close()
176
+	err = eventlog.Install(*flServiceName, p, false, eventlog.Info|eventlog.Warning|eventlog.Error)
177
+	if err != nil {
178
+		return err
179
+	}
180
+
181
+	return nil
182
+}
183
+
184
+func unregisterService() error {
185
+	m, err := mgr.Connect()
186
+	if err != nil {
187
+		return err
188
+	}
189
+	defer m.Disconnect()
190
+
191
+	s, err := m.OpenService(*flServiceName)
192
+	if err != nil {
193
+		return err
194
+	}
195
+	defer s.Close()
196
+
197
+	eventlog.Remove(*flServiceName)
198
+	err = s.Delete()
199
+	if err != nil {
200
+		return err
201
+	}
202
+	return nil
203
+}
204
+
205
+func initService() (bool, error) {
206
+	if *flUnregisterService {
207
+		if *flRegisterService {
208
+			return true, errors.New("--register-service and --unregister-service cannot be used together")
209
+		}
210
+		return true, unregisterService()
211
+	}
212
+
213
+	if *flRegisterService {
214
+		return true, registerService()
215
+	}
216
+
217
+	if !*flRunService {
218
+		return false, nil
219
+	}
220
+
221
+	interactive, err := svc.IsAnInteractiveSession()
222
+	if err != nil {
223
+		return false, err
224
+	}
225
+
226
+	h := &handler{
227
+		tosvc:   make(chan bool),
228
+		fromsvc: make(chan error),
229
+	}
230
+
231
+	var log *eventlog.Log
232
+	if !interactive {
233
+		log, err = eventlog.Open(*flServiceName)
234
+		if err != nil {
235
+			return false, err
236
+		}
237
+	}
238
+
239
+	logrus.AddHook(&etwHook{log})
240
+	logrus.SetOutput(ioutil.Discard)
241
+
242
+	service = h
243
+	go func() {
244
+		if interactive {
245
+			err = debug.Run(*flServiceName, h)
246
+		} else {
247
+			err = svc.Run(*flServiceName, h)
248
+		}
249
+
250
+		h.fromsvc <- err
251
+	}()
252
+
253
+	// Wait for the first signal from the service handler.
254
+	err = <-h.fromsvc
255
+	if err != nil {
256
+		return false, err
257
+	}
258
+	return false, nil
259
+}
260
+
261
+func (h *handler) started() error {
262
+	// This must be delayed until daemonCli initializes Config.Root
263
+	err := initPanicFile(filepath.Join(daemonCli.Config.Root, "panic.log"))
264
+	if err != nil {
265
+		return err
266
+	}
267
+
268
+	h.tosvc <- false
269
+	return nil
270
+}
271
+
272
+func (h *handler) stopped(err error) {
273
+	logrus.Debugf("Stopping service: %v", err)
274
+	h.tosvc <- err != nil
275
+	<-h.fromsvc
276
+}
277
+
278
+func (h *handler) Execute(_ []string, r <-chan svc.ChangeRequest, s chan<- svc.Status) (bool, uint32) {
279
+	s <- svc.Status{State: svc.StartPending, Accepts: 0}
280
+	// Unblock initService()
281
+	h.fromsvc <- nil
282
+
283
+	// Wait for initialization to complete.
284
+	failed := <-h.tosvc
285
+	if failed {
286
+		logrus.Debugf("Aborting service start due to failure during initializtion")
287
+		return true, 1
288
+	}
289
+
290
+	s <- svc.Status{State: svc.Running, Accepts: svc.AcceptStop | svc.AcceptShutdown | svc.Accepted(windows.SERVICE_ACCEPT_PARAMCHANGE)}
291
+	logrus.Debugf("Service running")
292
+Loop:
293
+	for {
294
+		select {
295
+		case failed = <-h.tosvc:
296
+			break Loop
297
+		case c := <-r:
298
+			switch c.Cmd {
299
+			case svc.Cmd(windows.SERVICE_CONTROL_PARAMCHANGE):
300
+				daemonCli.reloadConfig()
301
+			case svc.Interrogate:
302
+				s <- c.CurrentStatus
303
+			case svc.Stop, svc.Shutdown:
304
+				s <- svc.Status{State: svc.StopPending, Accepts: 0}
305
+				daemonCli.stop()
306
+			}
307
+		}
308
+	}
309
+
310
+	removePanicFile()
311
+	if failed {
312
+		return true, 1
313
+	}
314
+	return false, 0
315
+}
316
+
317
+func initPanicFile(path string) error {
318
+	var err error
319
+	panicFile, err = os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0)
320
+	if err != nil {
321
+		return err
322
+	}
323
+
324
+	st, err := panicFile.Stat()
325
+	if err != nil {
326
+		return err
327
+	}
328
+
329
+	// If there are contents in the file already, move the file out of the way
330
+	// and replace it.
331
+	if st.Size() > 0 {
332
+		panicFile.Close()
333
+		os.Rename(path, path+".old")
334
+		panicFile, err = os.Create(path)
335
+		if err != nil {
336
+			return err
337
+		}
338
+	}
339
+
340
+	// Update STD_ERROR_HANDLE to point to the panic file so that Go writes to
341
+	// it when it panics. Remember the old stderr to restore it before removing
342
+	// the panic file.
343
+	sh := syscall.STD_ERROR_HANDLE
344
+	h, err := syscall.GetStdHandle(sh)
345
+	if err != nil {
346
+		return err
347
+	}
348
+
349
+	oldStderr = h
350
+
351
+	r, _, err := setStdHandle.Call(uintptr(sh), uintptr(panicFile.Fd()))
352
+	if r == 0 && err != nil {
353
+		return err
354
+	}
355
+
356
+	return nil
357
+}
358
+
359
+func removePanicFile() {
360
+	if st, err := panicFile.Stat(); err == nil {
361
+		if st.Size() == 0 {
362
+			sh := syscall.STD_ERROR_HANDLE
363
+			setStdHandle.Call(uintptr(sh), uintptr(oldStderr))
364
+			panicFile.Close()
365
+			os.Remove(panicFile.Name())
366
+		}
367
+	}
368
+}
... ...
@@ -27,9 +27,11 @@ if [ "$(go env GOOS)" = "windows" ]; then
27 27
 
28 28
 	if [ "$(go env GOHOSTOS)" == "windows" ]; then
29 29
 		WINDRES=windres
30
+		WINDMC=windmc
30 31
 	else
31 32
 		# Cross compiling
32 33
 		WINDRES=x86_64-w64-mingw32-windres
34
+		WINDMC=x86_64-w64-mingw32-windmc
33 35
 	fi
34 36
 
35 37
 	# Generate a Windows file version of the form major,minor,patch,build (with any part optional)
... ...
@@ -51,6 +53,11 @@ if [ "$(go env GOOS)" = "windows" ]; then
51 51
 			$defs
52 52
 	}
53 53
 
54
+	$WINDMC \
55
+		hack/make/.resources-windows/event_messages.mc \
56
+		-h autogen/winresources/tmp \
57
+		-r autogen/winresources/tmp
58
+
54 59
 	makeres docker.rc pe-x86-64 autogen/winresources/docker/rsrc_amd64.syso
55 60
 	makeres docker.rc pe-i386 autogen/winresources/docker/rsrc_386.syso
56 61
 	makeres dockerd.rc pe-x86-64 autogen/winresources/dockerd/rsrc_amd64.syso
... ...
@@ -1,3 +1,4 @@
1 1
 #define DOCKER_NAME "Docker Engine"
2 2
 
3 3
 #include "common.rc"
4
+#include "event_messages.rc"
4 5
new file mode 100644
... ...
@@ -0,0 +1,39 @@
0
+MessageId=1
1
+Language=English
2
+%1
3
+.
4
+
5
+MessageId=2
6
+Language=English
7
+debug: %1
8
+.
9
+
10
+MessageId=3
11
+Language=English
12
+panic: %1
13
+.
14
+
15
+MessageId=4
16
+Language=English
17
+fatal: %1
18
+.
19
+
20
+MessageId=11
21
+Language=English
22
+%1 [%2]
23
+.
24
+
25
+MessageId=12
26
+Language=English
27
+debug: %1 [%2]
28
+.
29
+
30
+MessageId=13
31
+Language=English
32
+panic: %1 [%2]
33
+.
34
+
35
+MessageId=14
36
+Language=English
37
+fatal: %1 [%2]
38
+.
0 39
new file mode 100644
... ...
@@ -0,0 +1,8 @@
0
+// Copyright 2014 The Go Authors.  All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+#include "textflag.h"
5
+
6
+TEXT ·use(SB),NOSPLIT,$0
7
+	RET
0 8
new file mode 100644
... ...
@@ -0,0 +1,13 @@
0
+// Copyright 2009 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+//
5
+// System calls for 386, Windows are implemented in runtime/syscall_windows.goc
6
+//
7
+
8
+TEXT ·getprocaddress(SB), 7, $0-8
9
+	JMP	syscall·getprocaddress(SB)
10
+
11
+TEXT ·loadlibrary(SB), 7, $0-4
12
+	JMP	syscall·loadlibrary(SB)
0 13
new file mode 100644
... ...
@@ -0,0 +1,13 @@
0
+// Copyright 2009 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+//
5
+// System calls for amd64, Windows are implemented in runtime/syscall_windows.goc
6
+//
7
+
8
+TEXT ·getprocaddress(SB), 7, $0-32
9
+	JMP	syscall·getprocaddress(SB)
10
+
11
+TEXT ·loadlibrary(SB), 7, $0-8
12
+	JMP	syscall·loadlibrary(SB)
0 13
new file mode 100644
... ...
@@ -0,0 +1,275 @@
0
+// Copyright 2011 The Go Authors.  All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+package windows
5
+
6
+import (
7
+	"sync"
8
+	"sync/atomic"
9
+	"syscall"
10
+	"unsafe"
11
+)
12
+
13
+// DLLError describes reasons for DLL load failures.
14
+type DLLError struct {
15
+	Err     error
16
+	ObjName string
17
+	Msg     string
18
+}
19
+
20
+func (e *DLLError) Error() string { return e.Msg }
21
+
22
+// Implemented in runtime/syscall_windows.goc; we provide jumps to them in our assembly file.
23
+func loadlibrary(filename *uint16) (handle uintptr, err syscall.Errno)
24
+func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err syscall.Errno)
25
+
26
+// A DLL implements access to a single DLL.
27
+type DLL struct {
28
+	Name   string
29
+	Handle Handle
30
+}
31
+
32
+// LoadDLL loads DLL file into memory.
33
+func LoadDLL(name string) (dll *DLL, err error) {
34
+	namep, err := UTF16PtrFromString(name)
35
+	if err != nil {
36
+		return nil, err
37
+	}
38
+	h, e := loadlibrary(namep)
39
+	if e != 0 {
40
+		return nil, &DLLError{
41
+			Err:     e,
42
+			ObjName: name,
43
+			Msg:     "Failed to load " + name + ": " + e.Error(),
44
+		}
45
+	}
46
+	d := &DLL{
47
+		Name:   name,
48
+		Handle: Handle(h),
49
+	}
50
+	return d, nil
51
+}
52
+
53
+// MustLoadDLL is like LoadDLL but panics if load operation failes.
54
+func MustLoadDLL(name string) *DLL {
55
+	d, e := LoadDLL(name)
56
+	if e != nil {
57
+		panic(e)
58
+	}
59
+	return d
60
+}
61
+
62
+// FindProc searches DLL d for procedure named name and returns *Proc
63
+// if found. It returns an error if search fails.
64
+func (d *DLL) FindProc(name string) (proc *Proc, err error) {
65
+	namep, err := BytePtrFromString(name)
66
+	if err != nil {
67
+		return nil, err
68
+	}
69
+	a, e := getprocaddress(uintptr(d.Handle), namep)
70
+	if e != 0 {
71
+		return nil, &DLLError{
72
+			Err:     e,
73
+			ObjName: name,
74
+			Msg:     "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(),
75
+		}
76
+	}
77
+	p := &Proc{
78
+		Dll:  d,
79
+		Name: name,
80
+		addr: a,
81
+	}
82
+	return p, nil
83
+}
84
+
85
+// MustFindProc is like FindProc but panics if search fails.
86
+func (d *DLL) MustFindProc(name string) *Proc {
87
+	p, e := d.FindProc(name)
88
+	if e != nil {
89
+		panic(e)
90
+	}
91
+	return p
92
+}
93
+
94
+// Release unloads DLL d from memory.
95
+func (d *DLL) Release() (err error) {
96
+	return FreeLibrary(d.Handle)
97
+}
98
+
99
+// A Proc implements access to a procedure inside a DLL.
100
+type Proc struct {
101
+	Dll  *DLL
102
+	Name string
103
+	addr uintptr
104
+}
105
+
106
+// Addr returns the address of the procedure represented by p.
107
+// The return value can be passed to Syscall to run the procedure.
108
+func (p *Proc) Addr() uintptr {
109
+	return p.addr
110
+}
111
+
112
+// Call executes procedure p with arguments a. It will panic, if more then 15 arguments
113
+// are supplied.
114
+//
115
+// The returned error is always non-nil, constructed from the result of GetLastError.
116
+// Callers must inspect the primary return value to decide whether an error occurred
117
+// (according to the semantics of the specific function being called) before consulting
118
+// the error. The error will be guaranteed to contain windows.Errno.
119
+func (p *Proc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
120
+	switch len(a) {
121
+	case 0:
122
+		return syscall.Syscall(p.Addr(), uintptr(len(a)), 0, 0, 0)
123
+	case 1:
124
+		return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], 0, 0)
125
+	case 2:
126
+		return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], 0)
127
+	case 3:
128
+		return syscall.Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], a[2])
129
+	case 4:
130
+		return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], 0, 0)
131
+	case 5:
132
+		return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], 0)
133
+	case 6:
134
+		return syscall.Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5])
135
+	case 7:
136
+		return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], 0, 0)
137
+	case 8:
138
+		return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], 0)
139
+	case 9:
140
+		return syscall.Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8])
141
+	case 10:
142
+		return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], 0, 0)
143
+	case 11:
144
+		return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], 0)
145
+	case 12:
146
+		return syscall.Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11])
147
+	case 13:
148
+		return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], 0, 0)
149
+	case 14:
150
+		return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], 0)
151
+	case 15:
152
+		return syscall.Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14])
153
+	default:
154
+		panic("Call " + p.Name + " with too many arguments " + itoa(len(a)) + ".")
155
+	}
156
+	return
157
+}
158
+
159
+// A LazyDLL implements access to a single DLL.
160
+// It will delay the load of the DLL until the first
161
+// call to its Handle method or to one of its
162
+// LazyProc's Addr method.
163
+type LazyDLL struct {
164
+	mu   sync.Mutex
165
+	dll  *DLL // non nil once DLL is loaded
166
+	Name string
167
+}
168
+
169
+// Load loads DLL file d.Name into memory. It returns an error if fails.
170
+// Load will not try to load DLL, if it is already loaded into memory.
171
+func (d *LazyDLL) Load() error {
172
+	// Non-racy version of:
173
+	// if d.dll == nil {
174
+	if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll))) == nil {
175
+		d.mu.Lock()
176
+		defer d.mu.Unlock()
177
+		if d.dll == nil {
178
+			dll, e := LoadDLL(d.Name)
179
+			if e != nil {
180
+				return e
181
+			}
182
+			// Non-racy version of:
183
+			// d.dll = dll
184
+			atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll)), unsafe.Pointer(dll))
185
+		}
186
+	}
187
+	return nil
188
+}
189
+
190
+// mustLoad is like Load but panics if search fails.
191
+func (d *LazyDLL) mustLoad() {
192
+	e := d.Load()
193
+	if e != nil {
194
+		panic(e)
195
+	}
196
+}
197
+
198
+// Handle returns d's module handle.
199
+func (d *LazyDLL) Handle() uintptr {
200
+	d.mustLoad()
201
+	return uintptr(d.dll.Handle)
202
+}
203
+
204
+// NewProc returns a LazyProc for accessing the named procedure in the DLL d.
205
+func (d *LazyDLL) NewProc(name string) *LazyProc {
206
+	return &LazyProc{l: d, Name: name}
207
+}
208
+
209
+// NewLazyDLL creates new LazyDLL associated with DLL file.
210
+func NewLazyDLL(name string) *LazyDLL {
211
+	return &LazyDLL{Name: name}
212
+}
213
+
214
+// A LazyProc implements access to a procedure inside a LazyDLL.
215
+// It delays the lookup until the Addr method is called.
216
+type LazyProc struct {
217
+	mu   sync.Mutex
218
+	Name string
219
+	l    *LazyDLL
220
+	proc *Proc
221
+}
222
+
223
+// Find searches DLL for procedure named p.Name. It returns
224
+// an error if search fails. Find will not search procedure,
225
+// if it is already found and loaded into memory.
226
+func (p *LazyProc) Find() error {
227
+	// Non-racy version of:
228
+	// if p.proc == nil {
229
+	if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc))) == nil {
230
+		p.mu.Lock()
231
+		defer p.mu.Unlock()
232
+		if p.proc == nil {
233
+			e := p.l.Load()
234
+			if e != nil {
235
+				return e
236
+			}
237
+			proc, e := p.l.dll.FindProc(p.Name)
238
+			if e != nil {
239
+				return e
240
+			}
241
+			// Non-racy version of:
242
+			// p.proc = proc
243
+			atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc)), unsafe.Pointer(proc))
244
+		}
245
+	}
246
+	return nil
247
+}
248
+
249
+// mustFind is like Find but panics if search fails.
250
+func (p *LazyProc) mustFind() {
251
+	e := p.Find()
252
+	if e != nil {
253
+		panic(e)
254
+	}
255
+}
256
+
257
+// Addr returns the address of the procedure represented by p.
258
+// The return value can be passed to Syscall to run the procedure.
259
+func (p *LazyProc) Addr() uintptr {
260
+	p.mustFind()
261
+	return p.proc.Addr()
262
+}
263
+
264
+// Call executes procedure p with arguments a. It will panic, if more then 15 arguments
265
+// are supplied.
266
+//
267
+// The returned error is always non-nil, constructed from the result of GetLastError.
268
+// Callers must inspect the primary return value to decide whether an error occurred
269
+// (according to the semantics of the specific function being called) before consulting
270
+// the error. The error will be guaranteed to contain windows.Errno.
271
+func (p *LazyProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
272
+	p.mustFind()
273
+	return p.proc.Call(a...)
274
+}
0 275
new file mode 100644
... ...
@@ -0,0 +1,14 @@
0
+// Copyright 2014 The Go Authors.  All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build go1.4
5
+
6
+package windows
7
+
8
+import "syscall"
9
+
10
+func Unsetenv(key string) error {
11
+	// This was added in Go 1.4.
12
+	return syscall.Unsetenv(key)
13
+}
0 14
new file mode 100644
... ...
@@ -0,0 +1,25 @@
0
+// Copyright 2010 The Go Authors.  All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// Windows environment variables.
5
+
6
+package windows
7
+
8
+import "syscall"
9
+
10
+func Getenv(key string) (value string, found bool) {
11
+	return syscall.Getenv(key)
12
+}
13
+
14
+func Setenv(key, value string) error {
15
+	return syscall.Setenv(key, value)
16
+}
17
+
18
+func Clearenv() {
19
+	syscall.Clearenv()
20
+}
21
+
22
+func Environ() []string {
23
+	return syscall.Environ()
24
+}
0 25
new file mode 100644
... ...
@@ -0,0 +1,20 @@
0
+// Copyright 2012 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+package windows
7
+
8
+const (
9
+	EVENTLOG_SUCCESS          = 0
10
+	EVENTLOG_ERROR_TYPE       = 1
11
+	EVENTLOG_WARNING_TYPE     = 2
12
+	EVENTLOG_INFORMATION_TYPE = 4
13
+	EVENTLOG_AUDIT_SUCCESS    = 8
14
+	EVENTLOG_AUDIT_FAILURE    = 16
15
+)
16
+
17
+//sys	RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) [failretval==0] = advapi32.RegisterEventSourceW
18
+//sys	DeregisterEventSource(handle Handle) (err error) = advapi32.DeregisterEventSource
19
+//sys	ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) = advapi32.ReportEventW
0 20
new file mode 100644
... ...
@@ -0,0 +1,97 @@
0
+// Copyright 2009 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// Fork, exec, wait, etc.
5
+
6
+package windows
7
+
8
+// EscapeArg rewrites command line argument s as prescribed
9
+// in http://msdn.microsoft.com/en-us/library/ms880421.
10
+// This function returns "" (2 double quotes) if s is empty.
11
+// Alternatively, these transformations are done:
12
+// - every back slash (\) is doubled, but only if immediately
13
+//   followed by double quote (");
14
+// - every double quote (") is escaped by back slash (\);
15
+// - finally, s is wrapped with double quotes (arg -> "arg"),
16
+//   but only if there is space or tab inside s.
17
+func EscapeArg(s string) string {
18
+	if len(s) == 0 {
19
+		return "\"\""
20
+	}
21
+	n := len(s)
22
+	hasSpace := false
23
+	for i := 0; i < len(s); i++ {
24
+		switch s[i] {
25
+		case '"', '\\':
26
+			n++
27
+		case ' ', '\t':
28
+			hasSpace = true
29
+		}
30
+	}
31
+	if hasSpace {
32
+		n += 2
33
+	}
34
+	if n == len(s) {
35
+		return s
36
+	}
37
+
38
+	qs := make([]byte, n)
39
+	j := 0
40
+	if hasSpace {
41
+		qs[j] = '"'
42
+		j++
43
+	}
44
+	slashes := 0
45
+	for i := 0; i < len(s); i++ {
46
+		switch s[i] {
47
+		default:
48
+			slashes = 0
49
+			qs[j] = s[i]
50
+		case '\\':
51
+			slashes++
52
+			qs[j] = s[i]
53
+		case '"':
54
+			for ; slashes > 0; slashes-- {
55
+				qs[j] = '\\'
56
+				j++
57
+			}
58
+			qs[j] = '\\'
59
+			j++
60
+			qs[j] = s[i]
61
+		}
62
+		j++
63
+	}
64
+	if hasSpace {
65
+		for ; slashes > 0; slashes-- {
66
+			qs[j] = '\\'
67
+			j++
68
+		}
69
+		qs[j] = '"'
70
+		j++
71
+	}
72
+	return string(qs[:j])
73
+}
74
+
75
+func CloseOnExec(fd Handle) {
76
+	SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0)
77
+}
78
+
79
+// FullPath retrieves the full path of the specified file.
80
+func FullPath(name string) (path string, err error) {
81
+	p, err := UTF16PtrFromString(name)
82
+	if err != nil {
83
+		return "", err
84
+	}
85
+	n := uint32(100)
86
+	for {
87
+		buf := make([]uint16, n)
88
+		n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
89
+		if err != nil {
90
+			return "", err
91
+		}
92
+		if n <= uint32(len(buf)) {
93
+			return UTF16ToString(buf[:n]), nil
94
+		}
95
+	}
96
+}
0 97
new file mode 100644
... ...
@@ -0,0 +1,30 @@
0
+// Copyright 2012 The Go Authors.  All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows,race
5
+
6
+package windows
7
+
8
+import (
9
+	"runtime"
10
+	"unsafe"
11
+)
12
+
13
+const raceenabled = true
14
+
15
+func raceAcquire(addr unsafe.Pointer) {
16
+	runtime.RaceAcquire(addr)
17
+}
18
+
19
+func raceReleaseMerge(addr unsafe.Pointer) {
20
+	runtime.RaceReleaseMerge(addr)
21
+}
22
+
23
+func raceReadRange(addr unsafe.Pointer, len int) {
24
+	runtime.RaceReadRange(addr, len)
25
+}
26
+
27
+func raceWriteRange(addr unsafe.Pointer, len int) {
28
+	runtime.RaceWriteRange(addr, len)
29
+}
0 30
new file mode 100644
... ...
@@ -0,0 +1,25 @@
0
+// Copyright 2012 The Go Authors.  All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows,!race
5
+
6
+package windows
7
+
8
+import (
9
+	"unsafe"
10
+)
11
+
12
+const raceenabled = false
13
+
14
+func raceAcquire(addr unsafe.Pointer) {
15
+}
16
+
17
+func raceReleaseMerge(addr unsafe.Pointer) {
18
+}
19
+
20
+func raceReadRange(addr unsafe.Pointer, len int) {
21
+}
22
+
23
+func raceWriteRange(addr unsafe.Pointer, len int) {
24
+}
0 25
new file mode 100644
... ...
@@ -0,0 +1,178 @@
0
+// Copyright 2015 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+// Package registry provides access to the Windows registry.
7
+//
8
+// Here is a simple example, opening a registry key and reading a string value from it.
9
+//
10
+//	k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
11
+//	if err != nil {
12
+//		log.Fatal(err)
13
+//	}
14
+//	defer k.Close()
15
+//
16
+//	s, _, err := k.GetStringValue("SystemRoot")
17
+//	if err != nil {
18
+//		log.Fatal(err)
19
+//	}
20
+//	fmt.Printf("Windows system root is %q\n", s)
21
+//
22
+package registry
23
+
24
+import (
25
+	"io"
26
+	"syscall"
27
+	"time"
28
+)
29
+
30
+const (
31
+	// Registry key security and access rights.
32
+	// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms724878.aspx
33
+	// for details.
34
+	ALL_ACCESS         = 0xf003f
35
+	CREATE_LINK        = 0x00020
36
+	CREATE_SUB_KEY     = 0x00004
37
+	ENUMERATE_SUB_KEYS = 0x00008
38
+	EXECUTE            = 0x20019
39
+	NOTIFY             = 0x00010
40
+	QUERY_VALUE        = 0x00001
41
+	READ               = 0x20019
42
+	SET_VALUE          = 0x00002
43
+	WOW64_32KEY        = 0x00200
44
+	WOW64_64KEY        = 0x00100
45
+	WRITE              = 0x20006
46
+)
47
+
48
+// Key is a handle to an open Windows registry key.
49
+// Keys can be obtained by calling OpenKey; there are
50
+// also some predefined root keys such as CURRENT_USER.
51
+// Keys can be used directly in the Windows API.
52
+type Key syscall.Handle
53
+
54
+const (
55
+	// Windows defines some predefined root keys that are always open.
56
+	// An application can use these keys as entry points to the registry.
57
+	// Normally these keys are used in OpenKey to open new keys,
58
+	// but they can also be used anywhere a Key is required.
59
+	CLASSES_ROOT   = Key(syscall.HKEY_CLASSES_ROOT)
60
+	CURRENT_USER   = Key(syscall.HKEY_CURRENT_USER)
61
+	LOCAL_MACHINE  = Key(syscall.HKEY_LOCAL_MACHINE)
62
+	USERS          = Key(syscall.HKEY_USERS)
63
+	CURRENT_CONFIG = Key(syscall.HKEY_CURRENT_CONFIG)
64
+)
65
+
66
+// Close closes open key k.
67
+func (k Key) Close() error {
68
+	return syscall.RegCloseKey(syscall.Handle(k))
69
+}
70
+
71
+// OpenKey opens a new key with path name relative to key k.
72
+// It accepts any open key, including CURRENT_USER and others,
73
+// and returns the new key and an error.
74
+// The access parameter specifies desired access rights to the
75
+// key to be opened.
76
+func OpenKey(k Key, path string, access uint32) (Key, error) {
77
+	p, err := syscall.UTF16PtrFromString(path)
78
+	if err != nil {
79
+		return 0, err
80
+	}
81
+	var subkey syscall.Handle
82
+	err = syscall.RegOpenKeyEx(syscall.Handle(k), p, 0, access, &subkey)
83
+	if err != nil {
84
+		return 0, err
85
+	}
86
+	return Key(subkey), nil
87
+}
88
+
89
+// ReadSubKeyNames returns the names of subkeys of key k.
90
+// The parameter n controls the number of returned names,
91
+// analogous to the way os.File.Readdirnames works.
92
+func (k Key) ReadSubKeyNames(n int) ([]string, error) {
93
+	ki, err := k.Stat()
94
+	if err != nil {
95
+		return nil, err
96
+	}
97
+	names := make([]string, 0, ki.SubKeyCount)
98
+	buf := make([]uint16, ki.MaxSubKeyLen+1) // extra room for terminating zero byte
99
+loopItems:
100
+	for i := uint32(0); ; i++ {
101
+		if n > 0 {
102
+			if len(names) == n {
103
+				return names, nil
104
+			}
105
+		}
106
+		l := uint32(len(buf))
107
+		for {
108
+			err := syscall.RegEnumKeyEx(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil)
109
+			if err == nil {
110
+				break
111
+			}
112
+			if err == syscall.ERROR_MORE_DATA {
113
+				// Double buffer size and try again.
114
+				l = uint32(2 * len(buf))
115
+				buf = make([]uint16, l)
116
+				continue
117
+			}
118
+			if err == _ERROR_NO_MORE_ITEMS {
119
+				break loopItems
120
+			}
121
+			return names, err
122
+		}
123
+		names = append(names, syscall.UTF16ToString(buf[:l]))
124
+	}
125
+	if n > len(names) {
126
+		return names, io.EOF
127
+	}
128
+	return names, nil
129
+}
130
+
131
+// CreateKey creates a key named path under open key k.
132
+// CreateKey returns the new key and a boolean flag that reports
133
+// whether the key already existed.
134
+// The access parameter specifies the access rights for the key
135
+// to be created.
136
+func CreateKey(k Key, path string, access uint32) (newk Key, openedExisting bool, err error) {
137
+	var h syscall.Handle
138
+	var d uint32
139
+	err = regCreateKeyEx(syscall.Handle(k), syscall.StringToUTF16Ptr(path),
140
+		0, nil, _REG_OPTION_NON_VOLATILE, access, nil, &h, &d)
141
+	if err != nil {
142
+		return 0, false, err
143
+	}
144
+	return Key(h), d == _REG_OPENED_EXISTING_KEY, nil
145
+}
146
+
147
+// DeleteKey deletes the subkey path of key k and its values.
148
+func DeleteKey(k Key, path string) error {
149
+	return regDeleteKey(syscall.Handle(k), syscall.StringToUTF16Ptr(path))
150
+}
151
+
152
+// A KeyInfo describes the statistics of a key. It is returned by Stat.
153
+type KeyInfo struct {
154
+	SubKeyCount     uint32
155
+	MaxSubKeyLen    uint32 // size of the key's subkey with the longest name, in Unicode characters, not including the terminating zero byte
156
+	ValueCount      uint32
157
+	MaxValueNameLen uint32 // size of the key's longest value name, in Unicode characters, not including the terminating zero byte
158
+	MaxValueLen     uint32 // longest data component among the key's values, in bytes
159
+	lastWriteTime   syscall.Filetime
160
+}
161
+
162
+// ModTime returns the key's last write time.
163
+func (ki *KeyInfo) ModTime() time.Time {
164
+	return time.Unix(0, ki.lastWriteTime.Nanoseconds())
165
+}
166
+
167
+// Stat retrieves information about the open key k.
168
+func (k Key) Stat() (*KeyInfo, error) {
169
+	var ki KeyInfo
170
+	err := syscall.RegQueryInfoKey(syscall.Handle(k), nil, nil, nil,
171
+		&ki.SubKeyCount, &ki.MaxSubKeyLen, nil, &ki.ValueCount,
172
+		&ki.MaxValueNameLen, &ki.MaxValueLen, nil, &ki.lastWriteTime)
173
+	if err != nil {
174
+		return nil, err
175
+	}
176
+	return &ki, nil
177
+}
0 178
new file mode 100644
... ...
@@ -0,0 +1,33 @@
0
+// Copyright 2015 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+package registry
7
+
8
+import "syscall"
9
+
10
+//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall.go
11
+
12
+const (
13
+	_REG_OPTION_NON_VOLATILE = 0
14
+
15
+	_REG_CREATED_NEW_KEY     = 1
16
+	_REG_OPENED_EXISTING_KEY = 2
17
+
18
+	_ERROR_NO_MORE_ITEMS syscall.Errno = 259
19
+)
20
+
21
+func LoadRegLoadMUIString() error {
22
+	return procRegLoadMUIStringW.Find()
23
+}
24
+
25
+//sys	regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) = advapi32.RegCreateKeyExW
26
+//sys	regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) = advapi32.RegDeleteKeyW
27
+//sys	regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) = advapi32.RegSetValueExW
28
+//sys	regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegEnumValueW
29
+//sys	regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) = advapi32.RegDeleteValueW
30
+//sys   regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) = advapi32.RegLoadMUIStringW
31
+
32
+//sys	expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) = kernel32.ExpandEnvironmentStringsW
0 33
new file mode 100644
... ...
@@ -0,0 +1,384 @@
0
+// Copyright 2015 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+package registry
7
+
8
+import (
9
+	"errors"
10
+	"io"
11
+	"syscall"
12
+	"unicode/utf16"
13
+	"unsafe"
14
+)
15
+
16
+const (
17
+	// Registry value types.
18
+	NONE                       = 0
19
+	SZ                         = 1
20
+	EXPAND_SZ                  = 2
21
+	BINARY                     = 3
22
+	DWORD                      = 4
23
+	DWORD_BIG_ENDIAN           = 5
24
+	LINK                       = 6
25
+	MULTI_SZ                   = 7
26
+	RESOURCE_LIST              = 8
27
+	FULL_RESOURCE_DESCRIPTOR   = 9
28
+	RESOURCE_REQUIREMENTS_LIST = 10
29
+	QWORD                      = 11
30
+)
31
+
32
+var (
33
+	// ErrShortBuffer is returned when the buffer was too short for the operation.
34
+	ErrShortBuffer = syscall.ERROR_MORE_DATA
35
+
36
+	// ErrNotExist is returned when a registry key or value does not exist.
37
+	ErrNotExist = syscall.ERROR_FILE_NOT_FOUND
38
+
39
+	// ErrUnexpectedType is returned by Get*Value when the value's type was unexpected.
40
+	ErrUnexpectedType = errors.New("unexpected key value type")
41
+)
42
+
43
+// GetValue retrieves the type and data for the specified value associated
44
+// with an open key k. It fills up buffer buf and returns the retrieved
45
+// byte count n. If buf is too small to fit the stored value it returns
46
+// ErrShortBuffer error along with the required buffer size n.
47
+// If no buffer is provided, it returns true and actual buffer size n.
48
+// If no buffer is provided, GetValue returns the value's type only.
49
+// If the value does not exist, the error returned is ErrNotExist.
50
+//
51
+// GetValue is a low level function. If value's type is known, use the appropriate
52
+// Get*Value function instead.
53
+func (k Key) GetValue(name string, buf []byte) (n int, valtype uint32, err error) {
54
+	pname, err := syscall.UTF16PtrFromString(name)
55
+	if err != nil {
56
+		return 0, 0, err
57
+	}
58
+	var pbuf *byte
59
+	if len(buf) > 0 {
60
+		pbuf = (*byte)(unsafe.Pointer(&buf[0]))
61
+	}
62
+	l := uint32(len(buf))
63
+	err = syscall.RegQueryValueEx(syscall.Handle(k), pname, nil, &valtype, pbuf, &l)
64
+	if err != nil {
65
+		return int(l), valtype, err
66
+	}
67
+	return int(l), valtype, nil
68
+}
69
+
70
+func (k Key) getValue(name string, buf []byte) (date []byte, valtype uint32, err error) {
71
+	p, err := syscall.UTF16PtrFromString(name)
72
+	if err != nil {
73
+		return nil, 0, err
74
+	}
75
+	var t uint32
76
+	n := uint32(len(buf))
77
+	for {
78
+		err = syscall.RegQueryValueEx(syscall.Handle(k), p, nil, &t, (*byte)(unsafe.Pointer(&buf[0])), &n)
79
+		if err == nil {
80
+			return buf[:n], t, nil
81
+		}
82
+		if err != syscall.ERROR_MORE_DATA {
83
+			return nil, 0, err
84
+		}
85
+		if n <= uint32(len(buf)) {
86
+			return nil, 0, err
87
+		}
88
+		buf = make([]byte, n)
89
+	}
90
+}
91
+
92
+// GetStringValue retrieves the string value for the specified
93
+// value name associated with an open key k. It also returns the value's type.
94
+// If value does not exist, GetStringValue returns ErrNotExist.
95
+// If value is not SZ or EXPAND_SZ, it will return the correct value
96
+// type and ErrUnexpectedType.
97
+func (k Key) GetStringValue(name string) (val string, valtype uint32, err error) {
98
+	data, typ, err2 := k.getValue(name, make([]byte, 64))
99
+	if err2 != nil {
100
+		return "", typ, err2
101
+	}
102
+	switch typ {
103
+	case SZ, EXPAND_SZ:
104
+	default:
105
+		return "", typ, ErrUnexpectedType
106
+	}
107
+	if len(data) == 0 {
108
+		return "", typ, nil
109
+	}
110
+	u := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[:]
111
+	return syscall.UTF16ToString(u), typ, nil
112
+}
113
+
114
+// GetMUIStringValue retrieves the localized string value for
115
+// the specified value name associated with an open key k.
116
+// If the value name doesn't exist or the localized string value
117
+// can't be resolved, GetMUIStringValue returns ErrNotExist.
118
+// GetMUIStringValue panics if the system doesn't support
119
+// regLoadMUIString; use LoadRegLoadMUIString to check if
120
+// regLoadMUIString is supported before calling this function.
121
+func (k Key) GetMUIStringValue(name string) (string, error) {
122
+	pname, err := syscall.UTF16PtrFromString(name)
123
+	if err != nil {
124
+		return "", err
125
+	}
126
+
127
+	buf := make([]uint16, 1024)
128
+	var buflen uint32
129
+	var pdir *uint16
130
+
131
+	err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
132
+	if err == syscall.ERROR_FILE_NOT_FOUND { // Try fallback path
133
+
134
+		// Try to resolve the string value using the system directory as
135
+		// a DLL search path; this assumes the string value is of the form
136
+		// @[path]\dllname,-strID but with no path given, e.g. @tzres.dll,-320.
137
+
138
+		// This approach works with tzres.dll but may have to be revised
139
+		// in the future to allow callers to provide custom search paths.
140
+
141
+		var s string
142
+		s, err = ExpandString("%SystemRoot%\\system32\\")
143
+		if err != nil {
144
+			return "", err
145
+		}
146
+		pdir, err = syscall.UTF16PtrFromString(s)
147
+		if err != nil {
148
+			return "", err
149
+		}
150
+
151
+		err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
152
+	}
153
+
154
+	for err == syscall.ERROR_MORE_DATA { // Grow buffer if needed
155
+		if buflen <= uint32(len(buf)) {
156
+			break // Buffer not growing, assume race; break
157
+		}
158
+		buf = make([]uint16, buflen)
159
+		err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
160
+	}
161
+
162
+	if err != nil {
163
+		return "", err
164
+	}
165
+
166
+	return syscall.UTF16ToString(buf), nil
167
+}
168
+
169
+// ExpandString expands environment-variable strings and replaces
170
+// them with the values defined for the current user.
171
+// Use ExpandString to expand EXPAND_SZ strings.
172
+func ExpandString(value string) (string, error) {
173
+	if value == "" {
174
+		return "", nil
175
+	}
176
+	p, err := syscall.UTF16PtrFromString(value)
177
+	if err != nil {
178
+		return "", err
179
+	}
180
+	r := make([]uint16, 100)
181
+	for {
182
+		n, err := expandEnvironmentStrings(p, &r[0], uint32(len(r)))
183
+		if err != nil {
184
+			return "", err
185
+		}
186
+		if n <= uint32(len(r)) {
187
+			u := (*[1 << 29]uint16)(unsafe.Pointer(&r[0]))[:]
188
+			return syscall.UTF16ToString(u), nil
189
+		}
190
+		r = make([]uint16, n)
191
+	}
192
+}
193
+
194
+// GetStringsValue retrieves the []string value for the specified
195
+// value name associated with an open key k. It also returns the value's type.
196
+// If value does not exist, GetStringsValue returns ErrNotExist.
197
+// If value is not MULTI_SZ, it will return the correct value
198
+// type and ErrUnexpectedType.
199
+func (k Key) GetStringsValue(name string) (val []string, valtype uint32, err error) {
200
+	data, typ, err2 := k.getValue(name, make([]byte, 64))
201
+	if err2 != nil {
202
+		return nil, typ, err2
203
+	}
204
+	if typ != MULTI_SZ {
205
+		return nil, typ, ErrUnexpectedType
206
+	}
207
+	if len(data) == 0 {
208
+		return nil, typ, nil
209
+	}
210
+	p := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[:len(data)/2]
211
+	if len(p) == 0 {
212
+		return nil, typ, nil
213
+	}
214
+	if p[len(p)-1] == 0 {
215
+		p = p[:len(p)-1] // remove terminating null
216
+	}
217
+	val = make([]string, 0, 5)
218
+	from := 0
219
+	for i, c := range p {
220
+		if c == 0 {
221
+			val = append(val, string(utf16.Decode(p[from:i])))
222
+			from = i + 1
223
+		}
224
+	}
225
+	return val, typ, nil
226
+}
227
+
228
+// GetIntegerValue retrieves the integer value for the specified
229
+// value name associated with an open key k. It also returns the value's type.
230
+// If value does not exist, GetIntegerValue returns ErrNotExist.
231
+// If value is not DWORD or QWORD, it will return the correct value
232
+// type and ErrUnexpectedType.
233
+func (k Key) GetIntegerValue(name string) (val uint64, valtype uint32, err error) {
234
+	data, typ, err2 := k.getValue(name, make([]byte, 8))
235
+	if err2 != nil {
236
+		return 0, typ, err2
237
+	}
238
+	switch typ {
239
+	case DWORD:
240
+		if len(data) != 4 {
241
+			return 0, typ, errors.New("DWORD value is not 4 bytes long")
242
+		}
243
+		return uint64(*(*uint32)(unsafe.Pointer(&data[0]))), DWORD, nil
244
+	case QWORD:
245
+		if len(data) != 8 {
246
+			return 0, typ, errors.New("QWORD value is not 8 bytes long")
247
+		}
248
+		return uint64(*(*uint64)(unsafe.Pointer(&data[0]))), QWORD, nil
249
+	default:
250
+		return 0, typ, ErrUnexpectedType
251
+	}
252
+}
253
+
254
+// GetBinaryValue retrieves the binary value for the specified
255
+// value name associated with an open key k. It also returns the value's type.
256
+// If value does not exist, GetBinaryValue returns ErrNotExist.
257
+// If value is not BINARY, it will return the correct value
258
+// type and ErrUnexpectedType.
259
+func (k Key) GetBinaryValue(name string) (val []byte, valtype uint32, err error) {
260
+	data, typ, err2 := k.getValue(name, make([]byte, 64))
261
+	if err2 != nil {
262
+		return nil, typ, err2
263
+	}
264
+	if typ != BINARY {
265
+		return nil, typ, ErrUnexpectedType
266
+	}
267
+	return data, typ, nil
268
+}
269
+
270
+func (k Key) setValue(name string, valtype uint32, data []byte) error {
271
+	p, err := syscall.UTF16PtrFromString(name)
272
+	if err != nil {
273
+		return err
274
+	}
275
+	if len(data) == 0 {
276
+		return regSetValueEx(syscall.Handle(k), p, 0, valtype, nil, 0)
277
+	}
278
+	return regSetValueEx(syscall.Handle(k), p, 0, valtype, &data[0], uint32(len(data)))
279
+}
280
+
281
+// SetDWordValue sets the data and type of a name value
282
+// under key k to value and DWORD.
283
+func (k Key) SetDWordValue(name string, value uint32) error {
284
+	return k.setValue(name, DWORD, (*[4]byte)(unsafe.Pointer(&value))[:])
285
+}
286
+
287
+// SetQWordValue sets the data and type of a name value
288
+// under key k to value and QWORD.
289
+func (k Key) SetQWordValue(name string, value uint64) error {
290
+	return k.setValue(name, QWORD, (*[8]byte)(unsafe.Pointer(&value))[:])
291
+}
292
+
293
+func (k Key) setStringValue(name string, valtype uint32, value string) error {
294
+	v, err := syscall.UTF16FromString(value)
295
+	if err != nil {
296
+		return err
297
+	}
298
+	buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[:len(v)*2]
299
+	return k.setValue(name, valtype, buf)
300
+}
301
+
302
+// SetStringValue sets the data and type of a name value
303
+// under key k to value and SZ. The value must not contain a zero byte.
304
+func (k Key) SetStringValue(name, value string) error {
305
+	return k.setStringValue(name, SZ, value)
306
+}
307
+
308
+// SetExpandStringValue sets the data and type of a name value
309
+// under key k to value and EXPAND_SZ. The value must not contain a zero byte.
310
+func (k Key) SetExpandStringValue(name, value string) error {
311
+	return k.setStringValue(name, EXPAND_SZ, value)
312
+}
313
+
314
+// SetStringsValue sets the data and type of a name value
315
+// under key k to value and MULTI_SZ. The value strings
316
+// must not contain a zero byte.
317
+func (k Key) SetStringsValue(name string, value []string) error {
318
+	ss := ""
319
+	for _, s := range value {
320
+		for i := 0; i < len(s); i++ {
321
+			if s[i] == 0 {
322
+				return errors.New("string cannot have 0 inside")
323
+			}
324
+		}
325
+		ss += s + "\x00"
326
+	}
327
+	v := utf16.Encode([]rune(ss + "\x00"))
328
+	buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[:len(v)*2]
329
+	return k.setValue(name, MULTI_SZ, buf)
330
+}
331
+
332
+// SetBinaryValue sets the data and type of a name value
333
+// under key k to value and BINARY.
334
+func (k Key) SetBinaryValue(name string, value []byte) error {
335
+	return k.setValue(name, BINARY, value)
336
+}
337
+
338
+// DeleteValue removes a named value from the key k.
339
+func (k Key) DeleteValue(name string) error {
340
+	return regDeleteValue(syscall.Handle(k), syscall.StringToUTF16Ptr(name))
341
+}
342
+
343
+// ReadValueNames returns the value names of key k.
344
+// The parameter n controls the number of returned names,
345
+// analogous to the way os.File.Readdirnames works.
346
+func (k Key) ReadValueNames(n int) ([]string, error) {
347
+	ki, err := k.Stat()
348
+	if err != nil {
349
+		return nil, err
350
+	}
351
+	names := make([]string, 0, ki.ValueCount)
352
+	buf := make([]uint16, ki.MaxValueNameLen+1) // extra room for terminating null character
353
+loopItems:
354
+	for i := uint32(0); ; i++ {
355
+		if n > 0 {
356
+			if len(names) == n {
357
+				return names, nil
358
+			}
359
+		}
360
+		l := uint32(len(buf))
361
+		for {
362
+			err := regEnumValue(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil)
363
+			if err == nil {
364
+				break
365
+			}
366
+			if err == syscall.ERROR_MORE_DATA {
367
+				// Double buffer size and try again.
368
+				l = uint32(2 * len(buf))
369
+				buf = make([]uint16, l)
370
+				continue
371
+			}
372
+			if err == _ERROR_NO_MORE_ITEMS {
373
+				break loopItems
374
+			}
375
+			return names, err
376
+		}
377
+		names = append(names, syscall.UTF16ToString(buf[:l]))
378
+	}
379
+	if n > len(names) {
380
+		return names, io.EOF
381
+	}
382
+	return names, nil
383
+}
0 384
new file mode 100644
... ...
@@ -0,0 +1,82 @@
0
+// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
1
+
2
+package registry
3
+
4
+import "unsafe"
5
+import "syscall"
6
+
7
+var _ unsafe.Pointer
8
+
9
+var (
10
+	modadvapi32 = syscall.NewLazyDLL("advapi32.dll")
11
+	modkernel32 = syscall.NewLazyDLL("kernel32.dll")
12
+
13
+	procRegCreateKeyExW           = modadvapi32.NewProc("RegCreateKeyExW")
14
+	procRegDeleteKeyW             = modadvapi32.NewProc("RegDeleteKeyW")
15
+	procRegSetValueExW            = modadvapi32.NewProc("RegSetValueExW")
16
+	procRegEnumValueW             = modadvapi32.NewProc("RegEnumValueW")
17
+	procRegDeleteValueW           = modadvapi32.NewProc("RegDeleteValueW")
18
+	procRegLoadMUIStringW         = modadvapi32.NewProc("RegLoadMUIStringW")
19
+	procExpandEnvironmentStringsW = modkernel32.NewProc("ExpandEnvironmentStringsW")
20
+)
21
+
22
+func regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) {
23
+	r0, _, _ := syscall.Syscall9(procRegCreateKeyExW.Addr(), 9, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(reserved), uintptr(unsafe.Pointer(class)), uintptr(options), uintptr(desired), uintptr(unsafe.Pointer(sa)), uintptr(unsafe.Pointer(result)), uintptr(unsafe.Pointer(disposition)))
24
+	if r0 != 0 {
25
+		regerrno = syscall.Errno(r0)
26
+	}
27
+	return
28
+}
29
+
30
+func regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) {
31
+	r0, _, _ := syscall.Syscall(procRegDeleteKeyW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(subkey)), 0)
32
+	if r0 != 0 {
33
+		regerrno = syscall.Errno(r0)
34
+	}
35
+	return
36
+}
37
+
38
+func regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) {
39
+	r0, _, _ := syscall.Syscall6(procRegSetValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(valueName)), uintptr(reserved), uintptr(vtype), uintptr(unsafe.Pointer(buf)), uintptr(bufsize))
40
+	if r0 != 0 {
41
+		regerrno = syscall.Errno(r0)
42
+	}
43
+	return
44
+}
45
+
46
+func regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) {
47
+	r0, _, _ := syscall.Syscall9(procRegEnumValueW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen)), 0)
48
+	if r0 != 0 {
49
+		regerrno = syscall.Errno(r0)
50
+	}
51
+	return
52
+}
53
+
54
+func regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) {
55
+	r0, _, _ := syscall.Syscall(procRegDeleteValueW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(name)), 0)
56
+	if r0 != 0 {
57
+		regerrno = syscall.Errno(r0)
58
+	}
59
+	return
60
+}
61
+
62
+func regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) {
63
+	r0, _, _ := syscall.Syscall9(procRegLoadMUIStringW.Addr(), 7, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(unsafe.Pointer(buflenCopied)), uintptr(flags), uintptr(unsafe.Pointer(dir)), 0, 0)
64
+	if r0 != 0 {
65
+		regerrno = syscall.Errno(r0)
66
+	}
67
+	return
68
+}
69
+
70
+func expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) {
71
+	r0, _, e1 := syscall.Syscall(procExpandEnvironmentStringsW.Addr(), 3, uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(size))
72
+	n = uint32(r0)
73
+	if n == 0 {
74
+		if e1 != 0 {
75
+			err = error(e1)
76
+		} else {
77
+			err = syscall.EINVAL
78
+		}
79
+	}
80
+	return
81
+}
0 82
new file mode 100644
... ...
@@ -0,0 +1,435 @@
0
+// Copyright 2012 The Go Authors.  All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+package windows
5
+
6
+import (
7
+	"syscall"
8
+	"unsafe"
9
+)
10
+
11
+const (
12
+	STANDARD_RIGHTS_REQUIRED = 0xf0000
13
+	STANDARD_RIGHTS_READ     = 0x20000
14
+	STANDARD_RIGHTS_WRITE    = 0x20000
15
+	STANDARD_RIGHTS_EXECUTE  = 0x20000
16
+	STANDARD_RIGHTS_ALL      = 0x1F0000
17
+)
18
+
19
+const (
20
+	NameUnknown          = 0
21
+	NameFullyQualifiedDN = 1
22
+	NameSamCompatible    = 2
23
+	NameDisplay          = 3
24
+	NameUniqueId         = 6
25
+	NameCanonical        = 7
26
+	NameUserPrincipal    = 8
27
+	NameCanonicalEx      = 9
28
+	NameServicePrincipal = 10
29
+	NameDnsDomain        = 12
30
+)
31
+
32
+// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
33
+// http://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx
34
+//sys	TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW
35
+//sys	GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW
36
+
37
+// TranslateAccountName converts a directory service
38
+// object name from one format to another.
39
+func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
40
+	u, e := UTF16PtrFromString(username)
41
+	if e != nil {
42
+		return "", e
43
+	}
44
+	n := uint32(50)
45
+	for {
46
+		b := make([]uint16, n)
47
+		e = TranslateName(u, from, to, &b[0], &n)
48
+		if e == nil {
49
+			return UTF16ToString(b[:n]), nil
50
+		}
51
+		if e != ERROR_INSUFFICIENT_BUFFER {
52
+			return "", e
53
+		}
54
+		if n <= uint32(len(b)) {
55
+			return "", e
56
+		}
57
+	}
58
+}
59
+
60
+const (
61
+	// do not reorder
62
+	NetSetupUnknownStatus = iota
63
+	NetSetupUnjoined
64
+	NetSetupWorkgroupName
65
+	NetSetupDomainName
66
+)
67
+
68
+type UserInfo10 struct {
69
+	Name       *uint16
70
+	Comment    *uint16
71
+	UsrComment *uint16
72
+	FullName   *uint16
73
+}
74
+
75
+//sys	NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
76
+//sys	NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
77
+//sys	NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
78
+
79
+const (
80
+	// do not reorder
81
+	SidTypeUser = 1 + iota
82
+	SidTypeGroup
83
+	SidTypeDomain
84
+	SidTypeAlias
85
+	SidTypeWellKnownGroup
86
+	SidTypeDeletedAccount
87
+	SidTypeInvalid
88
+	SidTypeUnknown
89
+	SidTypeComputer
90
+	SidTypeLabel
91
+)
92
+
93
+type SidIdentifierAuthority struct {
94
+	Value [6]byte
95
+}
96
+
97
+var (
98
+	SECURITY_NULL_SID_AUTHORITY        = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 0}}
99
+	SECURITY_WORLD_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 1}}
100
+	SECURITY_LOCAL_SID_AUTHORITY       = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 2}}
101
+	SECURITY_CREATOR_SID_AUTHORITY     = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 3}}
102
+	SECURITY_NON_UNIQUE_AUTHORITY      = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 4}}
103
+	SECURITY_NT_AUTHORITY              = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 5}}
104
+	SECURITY_MANDATORY_LABEL_AUTHORITY = SidIdentifierAuthority{[6]byte{0, 0, 0, 0, 0, 16}}
105
+)
106
+
107
+const (
108
+	SECURITY_NULL_RID                   = 0
109
+	SECURITY_WORLD_RID                  = 0
110
+	SECURITY_LOCAL_RID                  = 0
111
+	SECURITY_CREATOR_OWNER_RID          = 0
112
+	SECURITY_CREATOR_GROUP_RID          = 1
113
+	SECURITY_DIALUP_RID                 = 1
114
+	SECURITY_NETWORK_RID                = 2
115
+	SECURITY_BATCH_RID                  = 3
116
+	SECURITY_INTERACTIVE_RID            = 4
117
+	SECURITY_LOGON_IDS_RID              = 5
118
+	SECURITY_SERVICE_RID                = 6
119
+	SECURITY_LOCAL_SYSTEM_RID           = 18
120
+	SECURITY_BUILTIN_DOMAIN_RID         = 32
121
+	SECURITY_PRINCIPAL_SELF_RID         = 10
122
+	SECURITY_CREATOR_OWNER_SERVER_RID   = 0x2
123
+	SECURITY_CREATOR_GROUP_SERVER_RID   = 0x3
124
+	SECURITY_LOGON_IDS_RID_COUNT        = 0x3
125
+	SECURITY_ANONYMOUS_LOGON_RID        = 0x7
126
+	SECURITY_PROXY_RID                  = 0x8
127
+	SECURITY_ENTERPRISE_CONTROLLERS_RID = 0x9
128
+	SECURITY_SERVER_LOGON_RID           = SECURITY_ENTERPRISE_CONTROLLERS_RID
129
+	SECURITY_AUTHENTICATED_USER_RID     = 0xb
130
+	SECURITY_RESTRICTED_CODE_RID        = 0xc
131
+	SECURITY_NT_NON_UNIQUE_RID          = 0x15
132
+)
133
+
134
+//sys	LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
135
+//sys	LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
136
+//sys	ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
137
+//sys	ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
138
+//sys	GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
139
+//sys	CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
140
+//sys	AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) = advapi32.AllocateAndInitializeSid
141
+//sys	FreeSid(sid *SID) (err error) [failretval!=0] = advapi32.FreeSid
142
+//sys	EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) = advapi32.EqualSid
143
+
144
+// The security identifier (SID) structure is a variable-length
145
+// structure used to uniquely identify users or groups.
146
+type SID struct{}
147
+
148
+// StringToSid converts a string-format security identifier
149
+// sid into a valid, functional sid.
150
+func StringToSid(s string) (*SID, error) {
151
+	var sid *SID
152
+	p, e := UTF16PtrFromString(s)
153
+	if e != nil {
154
+		return nil, e
155
+	}
156
+	e = ConvertStringSidToSid(p, &sid)
157
+	if e != nil {
158
+		return nil, e
159
+	}
160
+	defer LocalFree((Handle)(unsafe.Pointer(sid)))
161
+	return sid.Copy()
162
+}
163
+
164
+// LookupSID retrieves a security identifier sid for the account
165
+// and the name of the domain on which the account was found.
166
+// System specify target computer to search.
167
+func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
168
+	if len(account) == 0 {
169
+		return nil, "", 0, syscall.EINVAL
170
+	}
171
+	acc, e := UTF16PtrFromString(account)
172
+	if e != nil {
173
+		return nil, "", 0, e
174
+	}
175
+	var sys *uint16
176
+	if len(system) > 0 {
177
+		sys, e = UTF16PtrFromString(system)
178
+		if e != nil {
179
+			return nil, "", 0, e
180
+		}
181
+	}
182
+	n := uint32(50)
183
+	dn := uint32(50)
184
+	for {
185
+		b := make([]byte, n)
186
+		db := make([]uint16, dn)
187
+		sid = (*SID)(unsafe.Pointer(&b[0]))
188
+		e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
189
+		if e == nil {
190
+			return sid, UTF16ToString(db), accType, nil
191
+		}
192
+		if e != ERROR_INSUFFICIENT_BUFFER {
193
+			return nil, "", 0, e
194
+		}
195
+		if n <= uint32(len(b)) {
196
+			return nil, "", 0, e
197
+		}
198
+	}
199
+}
200
+
201
+// String converts sid to a string format
202
+// suitable for display, storage, or transmission.
203
+func (sid *SID) String() (string, error) {
204
+	var s *uint16
205
+	e := ConvertSidToStringSid(sid, &s)
206
+	if e != nil {
207
+		return "", e
208
+	}
209
+	defer LocalFree((Handle)(unsafe.Pointer(s)))
210
+	return UTF16ToString((*[256]uint16)(unsafe.Pointer(s))[:]), nil
211
+}
212
+
213
+// Len returns the length, in bytes, of a valid security identifier sid.
214
+func (sid *SID) Len() int {
215
+	return int(GetLengthSid(sid))
216
+}
217
+
218
+// Copy creates a duplicate of security identifier sid.
219
+func (sid *SID) Copy() (*SID, error) {
220
+	b := make([]byte, sid.Len())
221
+	sid2 := (*SID)(unsafe.Pointer(&b[0]))
222
+	e := CopySid(uint32(len(b)), sid2, sid)
223
+	if e != nil {
224
+		return nil, e
225
+	}
226
+	return sid2, nil
227
+}
228
+
229
+// LookupAccount retrieves the name of the account for this sid
230
+// and the name of the first domain on which this sid is found.
231
+// System specify target computer to search for.
232
+func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
233
+	var sys *uint16
234
+	if len(system) > 0 {
235
+		sys, err = UTF16PtrFromString(system)
236
+		if err != nil {
237
+			return "", "", 0, err
238
+		}
239
+	}
240
+	n := uint32(50)
241
+	dn := uint32(50)
242
+	for {
243
+		b := make([]uint16, n)
244
+		db := make([]uint16, dn)
245
+		e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
246
+		if e == nil {
247
+			return UTF16ToString(b), UTF16ToString(db), accType, nil
248
+		}
249
+		if e != ERROR_INSUFFICIENT_BUFFER {
250
+			return "", "", 0, e
251
+		}
252
+		if n <= uint32(len(b)) {
253
+			return "", "", 0, e
254
+		}
255
+	}
256
+}
257
+
258
+const (
259
+	// do not reorder
260
+	TOKEN_ASSIGN_PRIMARY = 1 << iota
261
+	TOKEN_DUPLICATE
262
+	TOKEN_IMPERSONATE
263
+	TOKEN_QUERY
264
+	TOKEN_QUERY_SOURCE
265
+	TOKEN_ADJUST_PRIVILEGES
266
+	TOKEN_ADJUST_GROUPS
267
+	TOKEN_ADJUST_DEFAULT
268
+
269
+	TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
270
+		TOKEN_ASSIGN_PRIMARY |
271
+		TOKEN_DUPLICATE |
272
+		TOKEN_IMPERSONATE |
273
+		TOKEN_QUERY |
274
+		TOKEN_QUERY_SOURCE |
275
+		TOKEN_ADJUST_PRIVILEGES |
276
+		TOKEN_ADJUST_GROUPS |
277
+		TOKEN_ADJUST_DEFAULT
278
+	TOKEN_READ  = STANDARD_RIGHTS_READ | TOKEN_QUERY
279
+	TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
280
+		TOKEN_ADJUST_PRIVILEGES |
281
+		TOKEN_ADJUST_GROUPS |
282
+		TOKEN_ADJUST_DEFAULT
283
+	TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
284
+)
285
+
286
+const (
287
+	// do not reorder
288
+	TokenUser = 1 + iota
289
+	TokenGroups
290
+	TokenPrivileges
291
+	TokenOwner
292
+	TokenPrimaryGroup
293
+	TokenDefaultDacl
294
+	TokenSource
295
+	TokenType
296
+	TokenImpersonationLevel
297
+	TokenStatistics
298
+	TokenRestrictedSids
299
+	TokenSessionId
300
+	TokenGroupsAndPrivileges
301
+	TokenSessionReference
302
+	TokenSandBoxInert
303
+	TokenAuditPolicy
304
+	TokenOrigin
305
+	TokenElevationType
306
+	TokenLinkedToken
307
+	TokenElevation
308
+	TokenHasRestrictions
309
+	TokenAccessInformation
310
+	TokenVirtualizationAllowed
311
+	TokenVirtualizationEnabled
312
+	TokenIntegrityLevel
313
+	TokenUIAccess
314
+	TokenMandatoryPolicy
315
+	TokenLogonSid
316
+	MaxTokenInfoClass
317
+)
318
+
319
+type SIDAndAttributes struct {
320
+	Sid        *SID
321
+	Attributes uint32
322
+}
323
+
324
+type Tokenuser struct {
325
+	User SIDAndAttributes
326
+}
327
+
328
+type Tokenprimarygroup struct {
329
+	PrimaryGroup *SID
330
+}
331
+
332
+type Tokengroups struct {
333
+	GroupCount uint32
334
+	Groups     [1]SIDAndAttributes
335
+}
336
+
337
+//sys	OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
338
+//sys	GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
339
+//sys	GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
340
+
341
+// An access token contains the security information for a logon session.
342
+// The system creates an access token when a user logs on, and every
343
+// process executed on behalf of the user has a copy of the token.
344
+// The token identifies the user, the user's groups, and the user's
345
+// privileges. The system uses the token to control access to securable
346
+// objects and to control the ability of the user to perform various
347
+// system-related operations on the local computer.
348
+type Token Handle
349
+
350
+// OpenCurrentProcessToken opens the access token
351
+// associated with current process.
352
+func OpenCurrentProcessToken() (Token, error) {
353
+	p, e := GetCurrentProcess()
354
+	if e != nil {
355
+		return 0, e
356
+	}
357
+	var t Token
358
+	e = OpenProcessToken(p, TOKEN_QUERY, &t)
359
+	if e != nil {
360
+		return 0, e
361
+	}
362
+	return t, nil
363
+}
364
+
365
+// Close releases access to access token.
366
+func (t Token) Close() error {
367
+	return CloseHandle(Handle(t))
368
+}
369
+
370
+// getInfo retrieves a specified type of information about an access token.
371
+func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
372
+	n := uint32(initSize)
373
+	for {
374
+		b := make([]byte, n)
375
+		e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
376
+		if e == nil {
377
+			return unsafe.Pointer(&b[0]), nil
378
+		}
379
+		if e != ERROR_INSUFFICIENT_BUFFER {
380
+			return nil, e
381
+		}
382
+		if n <= uint32(len(b)) {
383
+			return nil, e
384
+		}
385
+	}
386
+}
387
+
388
+// GetTokenUser retrieves access token t user account information.
389
+func (t Token) GetTokenUser() (*Tokenuser, error) {
390
+	i, e := t.getInfo(TokenUser, 50)
391
+	if e != nil {
392
+		return nil, e
393
+	}
394
+	return (*Tokenuser)(i), nil
395
+}
396
+
397
+// GetTokenGroups retrieves group accounts associated with access token t.
398
+func (t Token) GetTokenGroups() (*Tokengroups, error) {
399
+	i, e := t.getInfo(TokenGroups, 50)
400
+	if e != nil {
401
+		return nil, e
402
+	}
403
+	return (*Tokengroups)(i), nil
404
+}
405
+
406
+// GetTokenPrimaryGroup retrieves access token t primary group information.
407
+// A pointer to a SID structure representing a group that will become
408
+// the primary group of any objects created by a process using this access token.
409
+func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
410
+	i, e := t.getInfo(TokenPrimaryGroup, 50)
411
+	if e != nil {
412
+		return nil, e
413
+	}
414
+	return (*Tokenprimarygroup)(i), nil
415
+}
416
+
417
+// GetUserProfileDirectory retrieves path to the
418
+// root directory of the access token t user's profile.
419
+func (t Token) GetUserProfileDirectory() (string, error) {
420
+	n := uint32(100)
421
+	for {
422
+		b := make([]uint16, n)
423
+		e := GetUserProfileDirectory(t, &b[0], &n)
424
+		if e == nil {
425
+			return UTF16ToString(b), nil
426
+		}
427
+		if e != ERROR_INSUFFICIENT_BUFFER {
428
+			return "", e
429
+		}
430
+		if n <= uint32(len(b)) {
431
+			return "", e
432
+		}
433
+	}
434
+}
0 435
new file mode 100644
... ...
@@ -0,0 +1,143 @@
0
+// Copyright 2012 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+package windows
7
+
8
+const (
9
+	SC_MANAGER_CONNECT            = 1
10
+	SC_MANAGER_CREATE_SERVICE     = 2
11
+	SC_MANAGER_ENUMERATE_SERVICE  = 4
12
+	SC_MANAGER_LOCK               = 8
13
+	SC_MANAGER_QUERY_LOCK_STATUS  = 16
14
+	SC_MANAGER_MODIFY_BOOT_CONFIG = 32
15
+	SC_MANAGER_ALL_ACCESS         = 0xf003f
16
+)
17
+
18
+//sys	OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenSCManagerW
19
+
20
+const (
21
+	SERVICE_KERNEL_DRIVER       = 1
22
+	SERVICE_FILE_SYSTEM_DRIVER  = 2
23
+	SERVICE_ADAPTER             = 4
24
+	SERVICE_RECOGNIZER_DRIVER   = 8
25
+	SERVICE_WIN32_OWN_PROCESS   = 16
26
+	SERVICE_WIN32_SHARE_PROCESS = 32
27
+	SERVICE_WIN32               = SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS
28
+	SERVICE_INTERACTIVE_PROCESS = 256
29
+	SERVICE_DRIVER              = SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER
30
+	SERVICE_TYPE_ALL            = SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS
31
+
32
+	SERVICE_BOOT_START   = 0
33
+	SERVICE_SYSTEM_START = 1
34
+	SERVICE_AUTO_START   = 2
35
+	SERVICE_DEMAND_START = 3
36
+	SERVICE_DISABLED     = 4
37
+
38
+	SERVICE_ERROR_IGNORE   = 0
39
+	SERVICE_ERROR_NORMAL   = 1
40
+	SERVICE_ERROR_SEVERE   = 2
41
+	SERVICE_ERROR_CRITICAL = 3
42
+
43
+	SC_STATUS_PROCESS_INFO = 0
44
+
45
+	SERVICE_STOPPED          = 1
46
+	SERVICE_START_PENDING    = 2
47
+	SERVICE_STOP_PENDING     = 3
48
+	SERVICE_RUNNING          = 4
49
+	SERVICE_CONTINUE_PENDING = 5
50
+	SERVICE_PAUSE_PENDING    = 6
51
+	SERVICE_PAUSED           = 7
52
+	SERVICE_NO_CHANGE        = 0xffffffff
53
+
54
+	SERVICE_ACCEPT_STOP                  = 1
55
+	SERVICE_ACCEPT_PAUSE_CONTINUE        = 2
56
+	SERVICE_ACCEPT_SHUTDOWN              = 4
57
+	SERVICE_ACCEPT_PARAMCHANGE           = 8
58
+	SERVICE_ACCEPT_NETBINDCHANGE         = 16
59
+	SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 32
60
+	SERVICE_ACCEPT_POWEREVENT            = 64
61
+	SERVICE_ACCEPT_SESSIONCHANGE         = 128
62
+
63
+	SERVICE_CONTROL_STOP                  = 1
64
+	SERVICE_CONTROL_PAUSE                 = 2
65
+	SERVICE_CONTROL_CONTINUE              = 3
66
+	SERVICE_CONTROL_INTERROGATE           = 4
67
+	SERVICE_CONTROL_SHUTDOWN              = 5
68
+	SERVICE_CONTROL_PARAMCHANGE           = 6
69
+	SERVICE_CONTROL_NETBINDADD            = 7
70
+	SERVICE_CONTROL_NETBINDREMOVE         = 8
71
+	SERVICE_CONTROL_NETBINDENABLE         = 9
72
+	SERVICE_CONTROL_NETBINDDISABLE        = 10
73
+	SERVICE_CONTROL_DEVICEEVENT           = 11
74
+	SERVICE_CONTROL_HARDWAREPROFILECHANGE = 12
75
+	SERVICE_CONTROL_POWEREVENT            = 13
76
+	SERVICE_CONTROL_SESSIONCHANGE         = 14
77
+
78
+	SERVICE_ACTIVE    = 1
79
+	SERVICE_INACTIVE  = 2
80
+	SERVICE_STATE_ALL = 3
81
+
82
+	SERVICE_QUERY_CONFIG           = 1
83
+	SERVICE_CHANGE_CONFIG          = 2
84
+	SERVICE_QUERY_STATUS           = 4
85
+	SERVICE_ENUMERATE_DEPENDENTS   = 8
86
+	SERVICE_START                  = 16
87
+	SERVICE_STOP                   = 32
88
+	SERVICE_PAUSE_CONTINUE         = 64
89
+	SERVICE_INTERROGATE            = 128
90
+	SERVICE_USER_DEFINED_CONTROL   = 256
91
+	SERVICE_ALL_ACCESS             = STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP | SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL
92
+	SERVICE_RUNS_IN_SYSTEM_PROCESS = 1
93
+	SERVICE_CONFIG_DESCRIPTION     = 1
94
+	SERVICE_CONFIG_FAILURE_ACTIONS = 2
95
+
96
+	NO_ERROR = 0
97
+)
98
+
99
+type SERVICE_STATUS struct {
100
+	ServiceType             uint32
101
+	CurrentState            uint32
102
+	ControlsAccepted        uint32
103
+	Win32ExitCode           uint32
104
+	ServiceSpecificExitCode uint32
105
+	CheckPoint              uint32
106
+	WaitHint                uint32
107
+}
108
+
109
+type SERVICE_TABLE_ENTRY struct {
110
+	ServiceName *uint16
111
+	ServiceProc uintptr
112
+}
113
+
114
+type QUERY_SERVICE_CONFIG struct {
115
+	ServiceType      uint32
116
+	StartType        uint32
117
+	ErrorControl     uint32
118
+	BinaryPathName   *uint16
119
+	LoadOrderGroup   *uint16
120
+	TagId            uint32
121
+	Dependencies     *uint16
122
+	ServiceStartName *uint16
123
+	DisplayName      *uint16
124
+}
125
+
126
+type SERVICE_DESCRIPTION struct {
127
+	Description *uint16
128
+}
129
+
130
+//sys	CloseServiceHandle(handle Handle) (err error) = advapi32.CloseServiceHandle
131
+//sys	CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) [failretval==0] = advapi32.CreateServiceW
132
+//sys	OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenServiceW
133
+//sys	DeleteService(service Handle) (err error) = advapi32.DeleteService
134
+//sys	StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) = advapi32.StartServiceW
135
+//sys	QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) = advapi32.QueryServiceStatus
136
+//sys	ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) = advapi32.ControlService
137
+//sys	StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) = advapi32.StartServiceCtrlDispatcherW
138
+//sys	SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) = advapi32.SetServiceStatus
139
+//sys	ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) = advapi32.ChangeServiceConfigW
140
+//sys	QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfigW
141
+//sys	ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) = advapi32.ChangeServiceConfig2W
142
+//sys	QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfig2W
0 143
new file mode 100644
... ...
@@ -0,0 +1,22 @@
0
+// Copyright 2009 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+package windows
7
+
8
+func itoa(val int) string { // do it here rather than with fmt to avoid dependency
9
+	if val < 0 {
10
+		return "-" + itoa(-val)
11
+	}
12
+	var buf [32]byte // big enough for int64
13
+	i := len(buf) - 1
14
+	for val >= 10 {
15
+		buf[i] = byte(val%10 + '0')
16
+		i--
17
+		val /= 10
18
+	}
19
+	buf[i] = byte(val + '0')
20
+	return string(buf[i:])
21
+}
0 22
new file mode 100644
... ...
@@ -0,0 +1,56 @@
0
+// Copyright 2012 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+package debug
7
+
8
+import (
9
+	"os"
10
+	"strconv"
11
+)
12
+
13
+// Log interface allows different log implementations to be used.
14
+type Log interface {
15
+	Close() error
16
+	Info(eid uint32, msg string) error
17
+	Warning(eid uint32, msg string) error
18
+	Error(eid uint32, msg string) error
19
+}
20
+
21
+// ConsoleLog provides access to the console.
22
+type ConsoleLog struct {
23
+	Name string
24
+}
25
+
26
+// New creates new ConsoleLog.
27
+func New(source string) *ConsoleLog {
28
+	return &ConsoleLog{Name: source}
29
+}
30
+
31
+// Close closes console log l.
32
+func (l *ConsoleLog) Close() error {
33
+	return nil
34
+}
35
+
36
+func (l *ConsoleLog) report(kind string, eid uint32, msg string) error {
37
+	s := l.Name + "." + kind + "(" + strconv.Itoa(int(eid)) + "): " + msg + "\n"
38
+	_, err := os.Stdout.Write([]byte(s))
39
+	return err
40
+}
41
+
42
+// Info writes an information event msg with event id eid to the console l.
43
+func (l *ConsoleLog) Info(eid uint32, msg string) error {
44
+	return l.report("info", eid, msg)
45
+}
46
+
47
+// Warning writes an warning event msg with event id eid to the console l.
48
+func (l *ConsoleLog) Warning(eid uint32, msg string) error {
49
+	return l.report("warn", eid, msg)
50
+}
51
+
52
+// Error writes an error event msg with event id eid to the console l.
53
+func (l *ConsoleLog) Error(eid uint32, msg string) error {
54
+	return l.report("error", eid, msg)
55
+}
0 56
new file mode 100644
... ...
@@ -0,0 +1,45 @@
0
+// Copyright 2012 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+// Package debug provides facilities to execute svc.Handler on console.
7
+//
8
+package debug
9
+
10
+import (
11
+	"os"
12
+	"os/signal"
13
+	"syscall"
14
+
15
+	"golang.org/x/sys/windows/svc"
16
+)
17
+
18
+// Run executes service name by calling appropriate handler function.
19
+// The process is running on console, unlike real service. Use Ctrl+C to
20
+// send "Stop" command to your service.
21
+func Run(name string, handler svc.Handler) error {
22
+	cmds := make(chan svc.ChangeRequest)
23
+	changes := make(chan svc.Status)
24
+
25
+	sig := make(chan os.Signal)
26
+	signal.Notify(sig)
27
+
28
+	go func() {
29
+		status := svc.Status{State: svc.Stopped}
30
+		for {
31
+			select {
32
+			case <-sig:
33
+				cmds <- svc.ChangeRequest{svc.Stop, status}
34
+			case status = <-changes:
35
+			}
36
+		}
37
+	}()
38
+
39
+	_, errno := handler.Execute([]string{name}, cmds, changes)
40
+	if errno != 0 {
41
+		return syscall.Errno(errno)
42
+	}
43
+	return nil
44
+}
0 45
new file mode 100644
... ...
@@ -0,0 +1,48 @@
0
+// Copyright 2012 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+package svc
7
+
8
+import (
9
+	"errors"
10
+
11
+	"golang.org/x/sys/windows"
12
+)
13
+
14
+// event represents auto-reset, initially non-signaled Windows event.
15
+// It is used to communicate between go and asm parts of this package.
16
+type event struct {
17
+	h windows.Handle
18
+}
19
+
20
+func newEvent() (*event, error) {
21
+	h, err := windows.CreateEvent(nil, 0, 0, nil)
22
+	if err != nil {
23
+		return nil, err
24
+	}
25
+	return &event{h: h}, nil
26
+}
27
+
28
+func (e *event) Close() error {
29
+	return windows.CloseHandle(e.h)
30
+}
31
+
32
+func (e *event) Set() error {
33
+	return windows.SetEvent(e.h)
34
+}
35
+
36
+func (e *event) Wait() error {
37
+	s, err := windows.WaitForSingleObject(e.h, windows.INFINITE)
38
+	switch s {
39
+	case windows.WAIT_OBJECT_0:
40
+		break
41
+	case windows.WAIT_FAILED:
42
+		return err
43
+	default:
44
+		return errors.New("unexpected result from WaitForSingleObject")
45
+	}
46
+	return nil
47
+}
0 48
new file mode 100644
... ...
@@ -0,0 +1,80 @@
0
+// Copyright 2012 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+package eventlog
7
+
8
+import (
9
+	"errors"
10
+
11
+	"golang.org/x/sys/windows"
12
+	"golang.org/x/sys/windows/registry"
13
+)
14
+
15
+const (
16
+	// Log levels.
17
+	Info    = windows.EVENTLOG_INFORMATION_TYPE
18
+	Warning = windows.EVENTLOG_WARNING_TYPE
19
+	Error   = windows.EVENTLOG_ERROR_TYPE
20
+)
21
+
22
+const addKeyName = `SYSTEM\CurrentControlSet\Services\EventLog\Application`
23
+
24
+// Install modifies PC registry to allow logging with an event source src.
25
+// It adds all required keys and values to the event log registry key.
26
+// Install uses msgFile as the event message file. If useExpandKey is true,
27
+// the event message file is installed as REG_EXPAND_SZ value,
28
+// otherwise as REG_SZ. Use bitwise of log.Error, log.Warning and
29
+// log.Info to specify events supported by the new event source.
30
+func Install(src, msgFile string, useExpandKey bool, eventsSupported uint32) error {
31
+	appkey, err := registry.OpenKey(registry.LOCAL_MACHINE, addKeyName, registry.CREATE_SUB_KEY)
32
+	if err != nil {
33
+		return err
34
+	}
35
+	defer appkey.Close()
36
+
37
+	sk, alreadyExist, err := registry.CreateKey(appkey, src, registry.SET_VALUE)
38
+	if err != nil {
39
+		return err
40
+	}
41
+	defer sk.Close()
42
+	if alreadyExist {
43
+		return errors.New(addKeyName + `\` + src + " registry key already exists")
44
+	}
45
+
46
+	err = sk.SetDWordValue("CustomSource", 1)
47
+	if err != nil {
48
+		return err
49
+	}
50
+	if useExpandKey {
51
+		err = sk.SetExpandStringValue("EventMessageFile", msgFile)
52
+	} else {
53
+		err = sk.SetStringValue("EventMessageFile", msgFile)
54
+	}
55
+	if err != nil {
56
+		return err
57
+	}
58
+	err = sk.SetDWordValue("TypesSupported", eventsSupported)
59
+	if err != nil {
60
+		return err
61
+	}
62
+	return nil
63
+}
64
+
65
+// InstallAsEventCreate is the same as Install, but uses
66
+// %SystemRoot%\System32\EventCreate.exe as the event message file.
67
+func InstallAsEventCreate(src string, eventsSupported uint32) error {
68
+	return Install(src, "%SystemRoot%\\System32\\EventCreate.exe", true, eventsSupported)
69
+}
70
+
71
+// Remove deletes all registry elements installed by the correspondent Install.
72
+func Remove(src string) error {
73
+	appkey, err := registry.OpenKey(registry.LOCAL_MACHINE, addKeyName, registry.SET_VALUE)
74
+	if err != nil {
75
+		return err
76
+	}
77
+	defer appkey.Close()
78
+	return registry.DeleteKey(appkey, src)
79
+}
0 80
new file mode 100644
... ...
@@ -0,0 +1,70 @@
0
+// Copyright 2012 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+// Package eventlog implements access to Windows event log.
7
+//
8
+package eventlog
9
+
10
+import (
11
+	"errors"
12
+	"syscall"
13
+
14
+	"golang.org/x/sys/windows"
15
+)
16
+
17
+// Log provides access to the system log.
18
+type Log struct {
19
+	Handle windows.Handle
20
+}
21
+
22
+// Open retrieves a handle to the specified event log.
23
+func Open(source string) (*Log, error) {
24
+	return OpenRemote("", source)
25
+}
26
+
27
+// OpenRemote does the same as Open, but on different computer host.
28
+func OpenRemote(host, source string) (*Log, error) {
29
+	if source == "" {
30
+		return nil, errors.New("Specify event log source")
31
+	}
32
+	var s *uint16
33
+	if host != "" {
34
+		s = syscall.StringToUTF16Ptr(host)
35
+	}
36
+	h, err := windows.RegisterEventSource(s, syscall.StringToUTF16Ptr(source))
37
+	if err != nil {
38
+		return nil, err
39
+	}
40
+	return &Log{Handle: h}, nil
41
+}
42
+
43
+// Close closes event log l.
44
+func (l *Log) Close() error {
45
+	return windows.DeregisterEventSource(l.Handle)
46
+}
47
+
48
+func (l *Log) report(etype uint16, eid uint32, msg string) error {
49
+	ss := []*uint16{syscall.StringToUTF16Ptr(msg)}
50
+	return windows.ReportEvent(l.Handle, etype, 0, eid, 0, 1, 0, &ss[0], nil)
51
+}
52
+
53
+// Info writes an information event msg with event id eid to the end of event log l.
54
+// When EventCreate.exe is used, eid must be between 1 and 1000.
55
+func (l *Log) Info(eid uint32, msg string) error {
56
+	return l.report(windows.EVENTLOG_INFORMATION_TYPE, eid, msg)
57
+}
58
+
59
+// Warning writes an warning event msg with event id eid to the end of event log l.
60
+// When EventCreate.exe is used, eid must be between 1 and 1000.
61
+func (l *Log) Warning(eid uint32, msg string) error {
62
+	return l.report(windows.EVENTLOG_WARNING_TYPE, eid, msg)
63
+}
64
+
65
+// Error writes an error event msg with event id eid to the end of event log l.
66
+// When EventCreate.exe is used, eid must be between 1 and 1000.
67
+func (l *Log) Error(eid uint32, msg string) error {
68
+	return l.report(windows.EVENTLOG_ERROR_TYPE, eid, msg)
69
+}
0 70
new file mode 100644
... ...
@@ -0,0 +1,24 @@
0
+// Copyright 2012 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+// +build !go1.3
6
+
7
+// copied from pkg/runtime
8
+typedef	unsigned int	uint32;
9
+typedef	unsigned long long int	uint64;
10
+#ifdef _64BIT
11
+typedef	uint64		uintptr;
12
+#else
13
+typedef	uint32		uintptr;
14
+#endif
15
+
16
+// from sys_386.s or sys_amd64.s
17
+void ·servicemain(void);
18
+
19
+void
20
+·getServiceMain(uintptr *r)
21
+{
22
+	*r = (uintptr)·servicemain;
23
+}
0 24
new file mode 100644
... ...
@@ -0,0 +1,11 @@
0
+// Copyright 2014 The Go Authors.  All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+// +build !go1.3
6
+
7
+package svc
8
+
9
+// from go12.c
10
+func getServiceMain(r *uintptr)
0 11
new file mode 100644
... ...
@@ -0,0 +1,31 @@
0
+// Copyright 2014 The Go Authors.  All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+// +build go1.3
6
+
7
+package svc
8
+
9
+import "unsafe"
10
+
11
+const ptrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const
12
+
13
+// Should be a built-in for unsafe.Pointer?
14
+func add(p unsafe.Pointer, x uintptr) unsafe.Pointer {
15
+	return unsafe.Pointer(uintptr(p) + x)
16
+}
17
+
18
+// funcPC returns the entry PC of the function f.
19
+// It assumes that f is a func value. Otherwise the behavior is undefined.
20
+func funcPC(f interface{}) uintptr {
21
+	return **(**uintptr)(add(unsafe.Pointer(&f), ptrSize))
22
+}
23
+
24
+// from sys_386.s and sys_amd64.s
25
+func servicectlhandler(ctl uint32) uintptr
26
+func servicemain(argc uint32, argv **uint16)
27
+
28
+func getServiceMain(r *uintptr) {
29
+	*r = funcPC(servicemain)
30
+}
0 31
new file mode 100644
... ...
@@ -0,0 +1,139 @@
0
+// Copyright 2012 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+package mgr
7
+
8
+import (
9
+	"syscall"
10
+	"unicode/utf16"
11
+	"unsafe"
12
+
13
+	"golang.org/x/sys/windows"
14
+)
15
+
16
+const (
17
+	// Service start types.
18
+	StartManual    = windows.SERVICE_DEMAND_START // the service must be started manually
19
+	StartAutomatic = windows.SERVICE_AUTO_START   // the service will start by itself whenever the computer reboots
20
+	StartDisabled  = windows.SERVICE_DISABLED     // the service cannot be started
21
+
22
+	// The severity of the error, and action taken,
23
+	// if this service fails to start.
24
+	ErrorCritical = windows.SERVICE_ERROR_CRITICAL
25
+	ErrorIgnore   = windows.SERVICE_ERROR_IGNORE
26
+	ErrorNormal   = windows.SERVICE_ERROR_NORMAL
27
+	ErrorSevere   = windows.SERVICE_ERROR_SEVERE
28
+)
29
+
30
+// TODO(brainman): Password is not returned by windows.QueryServiceConfig, not sure how to get it.
31
+
32
+type Config struct {
33
+	ServiceType      uint32
34
+	StartType        uint32
35
+	ErrorControl     uint32
36
+	BinaryPathName   string // fully qualified path to the service binary file, can also include arguments for an auto-start service
37
+	LoadOrderGroup   string
38
+	TagId            uint32
39
+	Dependencies     []string
40
+	ServiceStartName string // name of the account under which the service should run
41
+	DisplayName      string
42
+	Password         string
43
+	Description      string
44
+}
45
+
46
+func toString(p *uint16) string {
47
+	if p == nil {
48
+		return ""
49
+	}
50
+	return syscall.UTF16ToString((*[4096]uint16)(unsafe.Pointer(p))[:])
51
+}
52
+
53
+func toStringSlice(ps *uint16) []string {
54
+	if ps == nil {
55
+		return nil
56
+	}
57
+	r := make([]string, 0)
58
+	for from, i, p := 0, 0, (*[1 << 24]uint16)(unsafe.Pointer(ps)); true; i++ {
59
+		if p[i] == 0 {
60
+			// empty string marks the end
61
+			if i <= from {
62
+				break
63
+			}
64
+			r = append(r, string(utf16.Decode(p[from:i])))
65
+			from = i + 1
66
+		}
67
+	}
68
+	return r
69
+}
70
+
71
+// Config retrieves service s configuration paramteres.
72
+func (s *Service) Config() (Config, error) {
73
+	var p *windows.QUERY_SERVICE_CONFIG
74
+	n := uint32(1024)
75
+	for {
76
+		b := make([]byte, n)
77
+		p = (*windows.QUERY_SERVICE_CONFIG)(unsafe.Pointer(&b[0]))
78
+		err := windows.QueryServiceConfig(s.Handle, p, n, &n)
79
+		if err == nil {
80
+			break
81
+		}
82
+		if err.(syscall.Errno) != syscall.ERROR_INSUFFICIENT_BUFFER {
83
+			return Config{}, err
84
+		}
85
+		if n <= uint32(len(b)) {
86
+			return Config{}, err
87
+		}
88
+	}
89
+
90
+	var p2 *windows.SERVICE_DESCRIPTION
91
+	n = uint32(1024)
92
+	for {
93
+		b := make([]byte, n)
94
+		p2 = (*windows.SERVICE_DESCRIPTION)(unsafe.Pointer(&b[0]))
95
+		err := windows.QueryServiceConfig2(s.Handle,
96
+			windows.SERVICE_CONFIG_DESCRIPTION, &b[0], n, &n)
97
+		if err == nil {
98
+			break
99
+		}
100
+		if err.(syscall.Errno) != syscall.ERROR_INSUFFICIENT_BUFFER {
101
+			return Config{}, err
102
+		}
103
+		if n <= uint32(len(b)) {
104
+			return Config{}, err
105
+		}
106
+	}
107
+
108
+	return Config{
109
+		ServiceType:      p.ServiceType,
110
+		StartType:        p.StartType,
111
+		ErrorControl:     p.ErrorControl,
112
+		BinaryPathName:   toString(p.BinaryPathName),
113
+		LoadOrderGroup:   toString(p.LoadOrderGroup),
114
+		TagId:            p.TagId,
115
+		Dependencies:     toStringSlice(p.Dependencies),
116
+		ServiceStartName: toString(p.ServiceStartName),
117
+		DisplayName:      toString(p.DisplayName),
118
+		Description:      toString(p2.Description),
119
+	}, nil
120
+}
121
+
122
+func updateDescription(handle windows.Handle, desc string) error {
123
+	d := windows.SERVICE_DESCRIPTION{toPtr(desc)}
124
+	return windows.ChangeServiceConfig2(handle,
125
+		windows.SERVICE_CONFIG_DESCRIPTION, (*byte)(unsafe.Pointer(&d)))
126
+}
127
+
128
+// UpdateConfig updates service s configuration parameters.
129
+func (s *Service) UpdateConfig(c Config) error {
130
+	err := windows.ChangeServiceConfig(s.Handle, c.ServiceType, c.StartType,
131
+		c.ErrorControl, toPtr(c.BinaryPathName), toPtr(c.LoadOrderGroup),
132
+		nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName),
133
+		toPtr(c.Password), toPtr(c.DisplayName))
134
+	if err != nil {
135
+		return err
136
+	}
137
+	return updateDescription(s.Handle, c.Description)
138
+}
0 139
new file mode 100644
... ...
@@ -0,0 +1,119 @@
0
+// Copyright 2012 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+// Package mgr can be used to manage Windows service programs.
7
+// It can be used to install and remove them. It can also start,
8
+// stop and pause them. The package can query / change current
9
+// service state and config parameters.
10
+//
11
+package mgr
12
+
13
+import (
14
+	"syscall"
15
+	"unicode/utf16"
16
+
17
+	"golang.org/x/sys/windows"
18
+)
19
+
20
+// Mgr is used to manage Windows service.
21
+type Mgr struct {
22
+	Handle windows.Handle
23
+}
24
+
25
+// Connect establishes a connection to the service control manager.
26
+func Connect() (*Mgr, error) {
27
+	return ConnectRemote("")
28
+}
29
+
30
+// ConnectRemote establishes a connection to the
31
+// service control manager on computer named host.
32
+func ConnectRemote(host string) (*Mgr, error) {
33
+	var s *uint16
34
+	if host != "" {
35
+		s = syscall.StringToUTF16Ptr(host)
36
+	}
37
+	h, err := windows.OpenSCManager(s, nil, windows.SC_MANAGER_ALL_ACCESS)
38
+	if err != nil {
39
+		return nil, err
40
+	}
41
+	return &Mgr{Handle: h}, nil
42
+}
43
+
44
+// Disconnect closes connection to the service control manager m.
45
+func (m *Mgr) Disconnect() error {
46
+	return windows.CloseServiceHandle(m.Handle)
47
+}
48
+
49
+func toPtr(s string) *uint16 {
50
+	if len(s) == 0 {
51
+		return nil
52
+	}
53
+	return syscall.StringToUTF16Ptr(s)
54
+}
55
+
56
+// toStringBlock terminates strings in ss with 0, and then
57
+// concatenates them together. It also adds extra 0 at the end.
58
+func toStringBlock(ss []string) *uint16 {
59
+	if len(ss) == 0 {
60
+		return nil
61
+	}
62
+	t := ""
63
+	for _, s := range ss {
64
+		if s != "" {
65
+			t += s + "\x00"
66
+		}
67
+	}
68
+	if t == "" {
69
+		return nil
70
+	}
71
+	t += "\x00"
72
+	return &utf16.Encode([]rune(t))[0]
73
+}
74
+
75
+// CreateService installs new service name on the system.
76
+// The service will be executed by running exepath binary.
77
+// Use config c to specify service parameters.
78
+// If service StartType is set to StartAutomatic,
79
+// args will be passed to svc.Handle.Execute.
80
+func (m *Mgr) CreateService(name, exepath string, c Config, args ...string) (*Service, error) {
81
+	if c.StartType == 0 {
82
+		c.StartType = StartManual
83
+	}
84
+	if c.ErrorControl == 0 {
85
+		c.ErrorControl = ErrorNormal
86
+	}
87
+	if c.ServiceType == 0 {
88
+		c.ServiceType = windows.SERVICE_WIN32_OWN_PROCESS
89
+	}
90
+	s := syscall.EscapeArg(exepath)
91
+	for _, v := range args {
92
+		s += " " + syscall.EscapeArg(v)
93
+	}
94
+	h, err := windows.CreateService(m.Handle, toPtr(name), toPtr(c.DisplayName),
95
+		windows.SERVICE_ALL_ACCESS, c.ServiceType,
96
+		c.StartType, c.ErrorControl, toPtr(s), toPtr(c.LoadOrderGroup),
97
+		nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName), toPtr(c.Password))
98
+	if err != nil {
99
+		return nil, err
100
+	}
101
+	if c.Description != "" {
102
+		err = updateDescription(h, c.Description)
103
+		if err != nil {
104
+			return nil, err
105
+		}
106
+	}
107
+	return &Service{Name: name, Handle: h}, nil
108
+}
109
+
110
+// OpenService retrieves access to service name, so it can
111
+// be interrogated and controlled.
112
+func (m *Mgr) OpenService(name string) (*Service, error) {
113
+	h, err := windows.OpenService(m.Handle, syscall.StringToUTF16Ptr(name), windows.SERVICE_ALL_ACCESS)
114
+	if err != nil {
115
+		return nil, err
116
+	}
117
+	return &Service{Name: name, Handle: h}, nil
118
+}
0 119
new file mode 100644
... ...
@@ -0,0 +1,74 @@
0
+// Copyright 2012 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+package mgr
7
+
8
+import (
9
+	"syscall"
10
+
11
+	"golang.org/x/sys/windows"
12
+	"golang.org/x/sys/windows/svc"
13
+)
14
+
15
+// TODO(brainman): Use EnumDependentServices to enumerate dependent services.
16
+
17
+// TODO(brainman): Use EnumServicesStatus to enumerate services in the specified service control manager database.
18
+
19
+// Service is used to access Windows service.
20
+type Service struct {
21
+	Name   string
22
+	Handle windows.Handle
23
+}
24
+
25
+// Delete marks service s for deletion from the service control manager database.
26
+func (s *Service) Delete() error {
27
+	return windows.DeleteService(s.Handle)
28
+}
29
+
30
+// Close relinquish access to the service s.
31
+func (s *Service) Close() error {
32
+	return windows.CloseServiceHandle(s.Handle)
33
+}
34
+
35
+// Start starts service s.
36
+// args will be passed to svc.Handler.Execute.
37
+func (s *Service) Start(args ...string) error {
38
+	var p **uint16
39
+	if len(args) > 0 {
40
+		vs := make([]*uint16, len(args))
41
+		for i, _ := range vs {
42
+			vs[i] = syscall.StringToUTF16Ptr(args[i])
43
+		}
44
+		p = &vs[0]
45
+	}
46
+	return windows.StartService(s.Handle, uint32(len(args)), p)
47
+}
48
+
49
+// Control sends state change request c to the servce s.
50
+func (s *Service) Control(c svc.Cmd) (svc.Status, error) {
51
+	var t windows.SERVICE_STATUS
52
+	err := windows.ControlService(s.Handle, uint32(c), &t)
53
+	if err != nil {
54
+		return svc.Status{}, err
55
+	}
56
+	return svc.Status{
57
+		State:   svc.State(t.CurrentState),
58
+		Accepts: svc.Accepted(t.ControlsAccepted),
59
+	}, nil
60
+}
61
+
62
+// Query returns current status of service s.
63
+func (s *Service) Query() (svc.Status, error) {
64
+	var t windows.SERVICE_STATUS
65
+	err := windows.QueryServiceStatus(s.Handle, &t)
66
+	if err != nil {
67
+		return svc.Status{}, err
68
+	}
69
+	return svc.Status{
70
+		State:   svc.State(t.CurrentState),
71
+		Accepts: svc.Accepted(t.ControlsAccepted),
72
+	}, nil
73
+}
0 74
new file mode 100644
... ...
@@ -0,0 +1,62 @@
0
+// Copyright 2012 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+package svc
7
+
8
+import (
9
+	"unsafe"
10
+
11
+	"golang.org/x/sys/windows"
12
+)
13
+
14
+func allocSid(subAuth0 uint32) (*windows.SID, error) {
15
+	var sid *windows.SID
16
+	err := windows.AllocateAndInitializeSid(&windows.SECURITY_NT_AUTHORITY,
17
+		1, subAuth0, 0, 0, 0, 0, 0, 0, 0, &sid)
18
+	if err != nil {
19
+		return nil, err
20
+	}
21
+	return sid, nil
22
+}
23
+
24
+// IsAnInteractiveSession determines if calling process is running interactively.
25
+// It queries the process token for membership in the Interactive group.
26
+// http://stackoverflow.com/questions/2668851/how-do-i-detect-that-my-application-is-running-as-service-or-in-an-interactive-s
27
+func IsAnInteractiveSession() (bool, error) {
28
+	interSid, err := allocSid(windows.SECURITY_INTERACTIVE_RID)
29
+	if err != nil {
30
+		return false, err
31
+	}
32
+	defer windows.FreeSid(interSid)
33
+
34
+	serviceSid, err := allocSid(windows.SECURITY_SERVICE_RID)
35
+	if err != nil {
36
+		return false, err
37
+	}
38
+	defer windows.FreeSid(serviceSid)
39
+
40
+	t, err := windows.OpenCurrentProcessToken()
41
+	if err != nil {
42
+		return false, err
43
+	}
44
+	defer t.Close()
45
+
46
+	gs, err := t.GetTokenGroups()
47
+	if err != nil {
48
+		return false, err
49
+	}
50
+	p := unsafe.Pointer(&gs.Groups[0])
51
+	groups := (*[2 << 20]windows.SIDAndAttributes)(p)[:gs.GroupCount]
52
+	for _, g := range groups {
53
+		if windows.EqualSid(g.Sid, interSid) {
54
+			return true, nil
55
+		}
56
+		if windows.EqualSid(g.Sid, serviceSid) {
57
+			return false, nil
58
+		}
59
+	}
60
+	return false, nil
61
+}
0 62
new file mode 100644
... ...
@@ -0,0 +1,316 @@
0
+// Copyright 2012 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+// Package svc provides everything required to build Windows service.
7
+//
8
+package svc
9
+
10
+import (
11
+	"errors"
12
+	"runtime"
13
+	"syscall"
14
+	"unsafe"
15
+
16
+	"golang.org/x/sys/windows"
17
+)
18
+
19
+// State describes service execution state (Stopped, Running and so on).
20
+type State uint32
21
+
22
+const (
23
+	Stopped         = State(windows.SERVICE_STOPPED)
24
+	StartPending    = State(windows.SERVICE_START_PENDING)
25
+	StopPending     = State(windows.SERVICE_STOP_PENDING)
26
+	Running         = State(windows.SERVICE_RUNNING)
27
+	ContinuePending = State(windows.SERVICE_CONTINUE_PENDING)
28
+	PausePending    = State(windows.SERVICE_PAUSE_PENDING)
29
+	Paused          = State(windows.SERVICE_PAUSED)
30
+)
31
+
32
+// Cmd represents service state change request. It is sent to a service
33
+// by the service manager, and should be actioned upon by the service.
34
+type Cmd uint32
35
+
36
+const (
37
+	Stop        = Cmd(windows.SERVICE_CONTROL_STOP)
38
+	Pause       = Cmd(windows.SERVICE_CONTROL_PAUSE)
39
+	Continue    = Cmd(windows.SERVICE_CONTROL_CONTINUE)
40
+	Interrogate = Cmd(windows.SERVICE_CONTROL_INTERROGATE)
41
+	Shutdown    = Cmd(windows.SERVICE_CONTROL_SHUTDOWN)
42
+)
43
+
44
+// Accepted is used to describe commands accepted by the service.
45
+// Note that Interrogate is always accepted.
46
+type Accepted uint32
47
+
48
+const (
49
+	AcceptStop             = Accepted(windows.SERVICE_ACCEPT_STOP)
50
+	AcceptShutdown         = Accepted(windows.SERVICE_ACCEPT_SHUTDOWN)
51
+	AcceptPauseAndContinue = Accepted(windows.SERVICE_ACCEPT_PAUSE_CONTINUE)
52
+)
53
+
54
+// Status combines State and Accepted commands to fully describe running service.
55
+type Status struct {
56
+	State      State
57
+	Accepts    Accepted
58
+	CheckPoint uint32 // used to report progress during a lengthy operation
59
+	WaitHint   uint32 // estimated time required for a pending operation, in milliseconds
60
+}
61
+
62
+// ChangeRequest is sent to the service Handler to request service status change.
63
+type ChangeRequest struct {
64
+	Cmd           Cmd
65
+	CurrentStatus Status
66
+}
67
+
68
+// Handler is the interface that must be implemented to build Windows service.
69
+type Handler interface {
70
+
71
+	// Execute will be called by the package code at the start of
72
+	// the service, and the service will exit once Execute completes.
73
+	// Inside Execute you must read service change requests from r and
74
+	// act accordingly. You must keep service control manager up to date
75
+	// about state of your service by writing into s as required.
76
+	// args contains service name followed by argument strings passed
77
+	// to the service.
78
+	// You can provide service exit code in exitCode return parameter,
79
+	// with 0 being "no error". You can also indicate if exit code,
80
+	// if any, is service specific or not by using svcSpecificEC
81
+	// parameter.
82
+	Execute(args []string, r <-chan ChangeRequest, s chan<- Status) (svcSpecificEC bool, exitCode uint32)
83
+}
84
+
85
+var (
86
+	// These are used by asm code.
87
+	goWaitsH                     uintptr
88
+	cWaitsH                      uintptr
89
+	ssHandle                     uintptr
90
+	sName                        *uint16
91
+	sArgc                        uintptr
92
+	sArgv                        **uint16
93
+	ctlHandlerProc               uintptr
94
+	cSetEvent                    uintptr
95
+	cWaitForSingleObject         uintptr
96
+	cRegisterServiceCtrlHandlerW uintptr
97
+)
98
+
99
+func init() {
100
+	k := syscall.MustLoadDLL("kernel32.dll")
101
+	cSetEvent = k.MustFindProc("SetEvent").Addr()
102
+	cWaitForSingleObject = k.MustFindProc("WaitForSingleObject").Addr()
103
+	a := syscall.MustLoadDLL("advapi32.dll")
104
+	cRegisterServiceCtrlHandlerW = a.MustFindProc("RegisterServiceCtrlHandlerW").Addr()
105
+}
106
+
107
+type ctlEvent struct {
108
+	cmd   Cmd
109
+	errno uint32
110
+}
111
+
112
+// service provides access to windows service api.
113
+type service struct {
114
+	name    string
115
+	h       windows.Handle
116
+	cWaits  *event
117
+	goWaits *event
118
+	c       chan ctlEvent
119
+	handler Handler
120
+}
121
+
122
+func newService(name string, handler Handler) (*service, error) {
123
+	var s service
124
+	var err error
125
+	s.name = name
126
+	s.c = make(chan ctlEvent)
127
+	s.handler = handler
128
+	s.cWaits, err = newEvent()
129
+	if err != nil {
130
+		return nil, err
131
+	}
132
+	s.goWaits, err = newEvent()
133
+	if err != nil {
134
+		s.cWaits.Close()
135
+		return nil, err
136
+	}
137
+	return &s, nil
138
+}
139
+
140
+func (s *service) close() error {
141
+	s.cWaits.Close()
142
+	s.goWaits.Close()
143
+	return nil
144
+}
145
+
146
+type exitCode struct {
147
+	isSvcSpecific bool
148
+	errno         uint32
149
+}
150
+
151
+func (s *service) updateStatus(status *Status, ec *exitCode) error {
152
+	if s.h == 0 {
153
+		return errors.New("updateStatus with no service status handle")
154
+	}
155
+	var t windows.SERVICE_STATUS
156
+	t.ServiceType = windows.SERVICE_WIN32_OWN_PROCESS
157
+	t.CurrentState = uint32(status.State)
158
+	if status.Accepts&AcceptStop != 0 {
159
+		t.ControlsAccepted |= windows.SERVICE_ACCEPT_STOP
160
+	}
161
+	if status.Accepts&AcceptShutdown != 0 {
162
+		t.ControlsAccepted |= windows.SERVICE_ACCEPT_SHUTDOWN
163
+	}
164
+	if status.Accepts&AcceptPauseAndContinue != 0 {
165
+		t.ControlsAccepted |= windows.SERVICE_ACCEPT_PAUSE_CONTINUE
166
+	}
167
+	if ec.errno == 0 {
168
+		t.Win32ExitCode = windows.NO_ERROR
169
+		t.ServiceSpecificExitCode = windows.NO_ERROR
170
+	} else if ec.isSvcSpecific {
171
+		t.Win32ExitCode = uint32(windows.ERROR_SERVICE_SPECIFIC_ERROR)
172
+		t.ServiceSpecificExitCode = ec.errno
173
+	} else {
174
+		t.Win32ExitCode = ec.errno
175
+		t.ServiceSpecificExitCode = windows.NO_ERROR
176
+	}
177
+	t.CheckPoint = status.CheckPoint
178
+	t.WaitHint = status.WaitHint
179
+	return windows.SetServiceStatus(s.h, &t)
180
+}
181
+
182
+const (
183
+	sysErrSetServiceStatusFailed = uint32(syscall.APPLICATION_ERROR) + iota
184
+	sysErrNewThreadInCallback
185
+)
186
+
187
+func (s *service) run() {
188
+	s.goWaits.Wait()
189
+	s.h = windows.Handle(ssHandle)
190
+	argv := (*[100]*int16)(unsafe.Pointer(sArgv))[:sArgc]
191
+	args := make([]string, len(argv))
192
+	for i, a := range argv {
193
+		args[i] = syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(a))[:])
194
+	}
195
+
196
+	cmdsToHandler := make(chan ChangeRequest)
197
+	changesFromHandler := make(chan Status)
198
+	exitFromHandler := make(chan exitCode)
199
+
200
+	go func() {
201
+		ss, errno := s.handler.Execute(args, cmdsToHandler, changesFromHandler)
202
+		exitFromHandler <- exitCode{ss, errno}
203
+	}()
204
+
205
+	status := Status{State: Stopped}
206
+	ec := exitCode{isSvcSpecific: true, errno: 0}
207
+	var outch chan ChangeRequest
208
+	inch := s.c
209
+	var cmd Cmd
210
+loop:
211
+	for {
212
+		select {
213
+		case r := <-inch:
214
+			if r.errno != 0 {
215
+				ec.errno = r.errno
216
+				break loop
217
+			}
218
+			inch = nil
219
+			outch = cmdsToHandler
220
+			cmd = r.cmd
221
+		case outch <- ChangeRequest{cmd, status}:
222
+			inch = s.c
223
+			outch = nil
224
+		case c := <-changesFromHandler:
225
+			err := s.updateStatus(&c, &ec)
226
+			if err != nil {
227
+				// best suitable error number
228
+				ec.errno = sysErrSetServiceStatusFailed
229
+				if err2, ok := err.(syscall.Errno); ok {
230
+					ec.errno = uint32(err2)
231
+				}
232
+				break loop
233
+			}
234
+			status = c
235
+		case ec = <-exitFromHandler:
236
+			break loop
237
+		}
238
+	}
239
+
240
+	s.updateStatus(&Status{State: Stopped}, &ec)
241
+	s.cWaits.Set()
242
+}
243
+
244
+func newCallback(fn interface{}) (cb uintptr, err error) {
245
+	defer func() {
246
+		r := recover()
247
+		if r == nil {
248
+			return
249
+		}
250
+		cb = 0
251
+		switch v := r.(type) {
252
+		case string:
253
+			err = errors.New(v)
254
+		case error:
255
+			err = v
256
+		default:
257
+			err = errors.New("unexpected panic in syscall.NewCallback")
258
+		}
259
+	}()
260
+	return syscall.NewCallback(fn), nil
261
+}
262
+
263
+// BUG(brainman): There is no mechanism to run multiple services
264
+// inside one single executable. Perhaps, it can be overcome by
265
+// using RegisterServiceCtrlHandlerEx Windows api.
266
+
267
+// Run executes service name by calling appropriate handler function.
268
+func Run(name string, handler Handler) error {
269
+	runtime.LockOSThread()
270
+
271
+	tid := windows.GetCurrentThreadId()
272
+
273
+	s, err := newService(name, handler)
274
+	if err != nil {
275
+		return err
276
+	}
277
+
278
+	ctlHandler := func(ctl uint32) uintptr {
279
+		e := ctlEvent{cmd: Cmd(ctl)}
280
+		// We assume that this callback function is running on
281
+		// the same thread as Run. Nowhere in MS documentation
282
+		// I could find statement to guarantee that. So putting
283
+		// check here to verify, otherwise things will go bad
284
+		// quickly, if ignored.
285
+		i := windows.GetCurrentThreadId()
286
+		if i != tid {
287
+			e.errno = sysErrNewThreadInCallback
288
+		}
289
+		s.c <- e
290
+		return 0
291
+	}
292
+
293
+	var svcmain uintptr
294
+	getServiceMain(&svcmain)
295
+	t := []windows.SERVICE_TABLE_ENTRY{
296
+		{syscall.StringToUTF16Ptr(s.name), svcmain},
297
+		{nil, 0},
298
+	}
299
+
300
+	goWaitsH = uintptr(s.goWaits.h)
301
+	cWaitsH = uintptr(s.cWaits.h)
302
+	sName = t[0].ServiceName
303
+	ctlHandlerProc, err = newCallback(ctlHandler)
304
+	if err != nil {
305
+		return err
306
+	}
307
+
308
+	go s.run()
309
+
310
+	err = windows.StartServiceCtrlDispatcher(&t[0])
311
+	if err != nil {
312
+		return err
313
+	}
314
+	return nil
315
+}
0 316
new file mode 100644
... ...
@@ -0,0 +1,67 @@
0
+// Copyright 2012 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+// func servicemain(argc uint32, argv **uint16)
7
+TEXT ·servicemain(SB),7,$0
8
+	MOVL	argc+0(FP), AX
9
+	MOVL	AX, ·sArgc(SB)
10
+	MOVL	argv+4(FP), AX
11
+	MOVL	AX, ·sArgv(SB)
12
+
13
+	PUSHL	BP
14
+	PUSHL	BX
15
+	PUSHL	SI
16
+	PUSHL	DI
17
+
18
+	SUBL	$12, SP
19
+
20
+	MOVL	·sName(SB), AX
21
+	MOVL	AX, (SP)
22
+	MOVL	$·servicectlhandler(SB), AX
23
+	MOVL	AX, 4(SP)
24
+	MOVL	·cRegisterServiceCtrlHandlerW(SB), AX
25
+	MOVL	SP, BP
26
+	CALL	AX
27
+	MOVL	BP, SP
28
+	CMPL	AX, $0
29
+	JE	exit
30
+	MOVL	AX, ·ssHandle(SB)
31
+
32
+	MOVL	·goWaitsH(SB), AX
33
+	MOVL	AX, (SP)
34
+	MOVL	·cSetEvent(SB), AX
35
+	MOVL	SP, BP
36
+	CALL	AX
37
+	MOVL	BP, SP
38
+
39
+	MOVL	·cWaitsH(SB), AX
40
+	MOVL	AX, (SP)
41
+	MOVL	$-1, AX
42
+	MOVL	AX, 4(SP)
43
+	MOVL	·cWaitForSingleObject(SB), AX
44
+	MOVL	SP, BP
45
+	CALL	AX
46
+	MOVL	BP, SP
47
+
48
+exit:
49
+	ADDL	$12, SP
50
+
51
+	POPL	DI
52
+	POPL	SI
53
+	POPL	BX
54
+	POPL	BP
55
+
56
+	MOVL	0(SP), CX
57
+	ADDL	$12, SP
58
+	JMP	CX
59
+
60
+// I do not know why, but this seems to be the only way to call
61
+// ctlHandlerProc on Windows 7.
62
+
63
+// func servicectlhandler(ctl uint32) uintptr
64
+TEXT ·servicectlhandler(SB),7,$0
65
+	MOVL	·ctlHandlerProc(SB), CX
66
+	JMP	CX
0 67
new file mode 100644
... ...
@@ -0,0 +1,41 @@
0
+// Copyright 2012 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+// func servicemain(argc uint32, argv **uint16)
7
+TEXT ·servicemain(SB),7,$0
8
+	MOVL	CX, ·sArgc(SB)
9
+	MOVL	DX, ·sArgv(SB)
10
+
11
+	SUBQ	$32, SP		// stack for the first 4 syscall params
12
+
13
+	MOVQ	·sName(SB), CX
14
+	MOVQ	$·servicectlhandler(SB), DX
15
+	MOVQ	·cRegisterServiceCtrlHandlerW(SB), AX
16
+	CALL	AX
17
+	CMPQ	AX, $0
18
+	JE	exit
19
+	MOVQ	AX, ·ssHandle(SB)
20
+
21
+	MOVQ	·goWaitsH(SB), CX
22
+	MOVQ	·cSetEvent(SB), AX
23
+	CALL	AX
24
+
25
+	MOVQ	·cWaitsH(SB), CX
26
+	MOVQ	$4294967295, DX
27
+	MOVQ	·cWaitForSingleObject(SB), AX
28
+	CALL	AX
29
+
30
+exit:
31
+	ADDQ	$32, SP
32
+	RET
33
+
34
+// I do not know why, but this seems to be the only way to call
35
+// ctlHandlerProc on Windows 7.
36
+
37
+// func servicectlhandler(ctl uint32) uintptr
38
+TEXT ·servicectlhandler(SB),7,$0
39
+	MOVQ	·ctlHandlerProc(SB), AX
40
+	JMP	AX
0 41
new file mode 100644
... ...
@@ -0,0 +1,77 @@
0
+// Copyright 2009 The Go Authors. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// +build windows
5
+
6
+// Package windows contains an interface to the low-level operating system
7
+// primitives.  OS details vary depending on the underlying system, and
8
+// by default, godoc will display the OS-specific documentation for the current
9
+// system.  If you want godoc to display syscall documentation for another
10
+// system, set $GOOS and $GOARCH to the desired system.  For example, if
11
+// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS
12
+// to freebsd and $GOARCH to arm.
13
+// The primary use of this package is inside other packages that provide a more
14
+// portable interface to the system, such as "os", "time" and "net".  Use
15
+// those packages rather than this one if you can.
16
+// For details of the functions and data types in this package consult
17
+// the manuals for the appropriate operating system.
18
+// These calls return err == nil to indicate success; otherwise
19
+// err represents an operating system error describing the failure and
20
+// holds a value of type syscall.Errno.
21
+package windows // import "golang.org/x/sys/windows"
22
+
23
+import (
24
+	"syscall"
25
+	"unsafe"
26
+)
27
+
28
+// ByteSliceFromString returns a NUL-terminated slice of bytes
29
+// containing the text of s. If s contains a NUL byte at any
30
+// location, it returns (nil, syscall.EINVAL).
31
+func ByteSliceFromString(s string) ([]byte, error) {
32
+	for i := 0; i < len(s); i++ {
33
+		if s[i] == 0 {
34
+			return nil, syscall.EINVAL
35
+		}
36
+	}
37
+	a := make([]byte, len(s)+1)
38
+	copy(a, s)
39
+	return a, nil
40
+}
41
+
42
+// BytePtrFromString returns a pointer to a NUL-terminated array of
43
+// bytes containing the text of s. If s contains a NUL byte at any
44
+// location, it returns (nil, syscall.EINVAL).
45
+func BytePtrFromString(s string) (*byte, error) {
46
+	a, err := ByteSliceFromString(s)
47
+	if err != nil {
48
+		return nil, err
49
+	}
50
+	return &a[0], nil
51
+}
52
+
53
+// Single-word zero for use when we need a valid pointer to 0 bytes.
54
+// See mksyscall.pl.
55
+var _zero uintptr
56
+
57
+func (ts *Timespec) Unix() (sec int64, nsec int64) {
58
+	return int64(ts.Sec), int64(ts.Nsec)
59
+}
60
+
61
+func (tv *Timeval) Unix() (sec int64, nsec int64) {
62
+	return int64(tv.Sec), int64(tv.Usec) * 1000
63
+}
64
+
65
+func (ts *Timespec) Nano() int64 {
66
+	return int64(ts.Sec)*1e9 + int64(ts.Nsec)
67
+}
68
+
69
+func (tv *Timeval) Nano() int64 {
70
+	return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000
71
+}
72
+
73
+// use is a no-op, but the compiler cannot see that it is.
74
+// Calling use(p) ensures that p is kept live until that point.
75
+//go:noescape
76
+func use(p unsafe.Pointer)
0 77
new file mode 100644
... ...
@@ -0,0 +1,990 @@
0
+// Copyright 2009 The Go Authors.  All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+// Windows system calls.
5
+
6
+package windows
7
+
8
+import (
9
+	errorspkg "errors"
10
+	"sync"
11
+	"syscall"
12
+	"unicode/utf16"
13
+	"unsafe"
14
+)
15
+
16
+//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go eventlog.go service.go syscall_windows.go security_windows.go
17
+
18
+type Handle uintptr
19
+
20
+const InvalidHandle = ^Handle(0)
21
+
22
+// StringToUTF16 is deprecated. Use UTF16FromString instead.
23
+// If s contains a NUL byte this function panics instead of
24
+// returning an error.
25
+func StringToUTF16(s string) []uint16 {
26
+	a, err := UTF16FromString(s)
27
+	if err != nil {
28
+		panic("windows: string with NUL passed to StringToUTF16")
29
+	}
30
+	return a
31
+}
32
+
33
+// UTF16FromString returns the UTF-16 encoding of the UTF-8 string
34
+// s, with a terminating NUL added. If s contains a NUL byte at any
35
+// location, it returns (nil, syscall.EINVAL).
36
+func UTF16FromString(s string) ([]uint16, error) {
37
+	for i := 0; i < len(s); i++ {
38
+		if s[i] == 0 {
39
+			return nil, syscall.EINVAL
40
+		}
41
+	}
42
+	return utf16.Encode([]rune(s + "\x00")), nil
43
+}
44
+
45
+// UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s,
46
+// with a terminating NUL removed.
47
+func UTF16ToString(s []uint16) string {
48
+	for i, v := range s {
49
+		if v == 0 {
50
+			s = s[0:i]
51
+			break
52
+		}
53
+	}
54
+	return string(utf16.Decode(s))
55
+}
56
+
57
+// StringToUTF16Ptr is deprecated. Use UTF16PtrFromString instead.
58
+// If s contains a NUL byte this function panics instead of
59
+// returning an error.
60
+func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] }
61
+
62
+// UTF16PtrFromString returns pointer to the UTF-16 encoding of
63
+// the UTF-8 string s, with a terminating NUL added. If s
64
+// contains a NUL byte at any location, it returns (nil, syscall.EINVAL).
65
+func UTF16PtrFromString(s string) (*uint16, error) {
66
+	a, err := UTF16FromString(s)
67
+	if err != nil {
68
+		return nil, err
69
+	}
70
+	return &a[0], nil
71
+}
72
+
73
+func Getpagesize() int { return 4096 }
74
+
75
+// Converts a Go function to a function pointer conforming
76
+// to the stdcall or cdecl calling convention.  This is useful when
77
+// interoperating with Windows code requiring callbacks.
78
+// Implemented in runtime/syscall_windows.goc
79
+func NewCallback(fn interface{}) uintptr
80
+func NewCallbackCDecl(fn interface{}) uintptr
81
+
82
+// windows api calls
83
+
84
+//sys	GetLastError() (lasterr error)
85
+//sys	LoadLibrary(libname string) (handle Handle, err error) = LoadLibraryW
86
+//sys	FreeLibrary(handle Handle) (err error)
87
+//sys	GetProcAddress(module Handle, procname string) (proc uintptr, err error)
88
+//sys	GetVersion() (ver uint32, err error)
89
+//sys	FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
90
+//sys	ExitProcess(exitcode uint32)
91
+//sys	CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
92
+//sys	ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error)
93
+//sys	WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error)
94
+//sys	SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) [failretval==0xffffffff]
95
+//sys	CloseHandle(handle Handle) (err error)
96
+//sys	GetStdHandle(stdhandle int) (handle Handle, err error) [failretval==InvalidHandle]
97
+//sys	findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstFileW
98
+//sys	findNextFile1(handle Handle, data *win32finddata1) (err error) = FindNextFileW
99
+//sys	FindClose(handle Handle) (err error)
100
+//sys	GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error)
101
+//sys	GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) = GetCurrentDirectoryW
102
+//sys	SetCurrentDirectory(path *uint16) (err error) = SetCurrentDirectoryW
103
+//sys	CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) = CreateDirectoryW
104
+//sys	RemoveDirectory(path *uint16) (err error) = RemoveDirectoryW
105
+//sys	DeleteFile(path *uint16) (err error) = DeleteFileW
106
+//sys	MoveFile(from *uint16, to *uint16) (err error) = MoveFileW
107
+//sys	MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW
108
+//sys	GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW
109
+//sys	GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW
110
+//sys	SetEndOfFile(handle Handle) (err error)
111
+//sys	GetSystemTimeAsFileTime(time *Filetime)
112
+//sys	GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff]
113
+//sys	CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error)
114
+//sys	GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error)
115
+//sys	PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error)
116
+//sys	CancelIo(s Handle) (err error)
117
+//sys	CancelIoEx(s Handle, o *Overlapped) (err error)
118
+//sys	CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW
119
+//sys	OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error)
120
+//sys	TerminateProcess(handle Handle, exitcode uint32) (err error)
121
+//sys	GetExitCodeProcess(handle Handle, exitcode *uint32) (err error)
122
+//sys	GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW
123
+//sys	GetCurrentProcess() (pseudoHandle Handle, err error)
124
+//sys	GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error)
125
+//sys	DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error)
126
+//sys	WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff]
127
+//sys	GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPathW
128
+//sys	CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error)
129
+//sys	GetFileType(filehandle Handle) (n uint32, err error)
130
+//sys	CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) = advapi32.CryptAcquireContextW
131
+//sys	CryptReleaseContext(provhandle Handle, flags uint32) (err error) = advapi32.CryptReleaseContext
132
+//sys	CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) = advapi32.CryptGenRandom
133
+//sys	GetEnvironmentStrings() (envs *uint16, err error) [failretval==nil] = kernel32.GetEnvironmentStringsW
134
+//sys	FreeEnvironmentStrings(envs *uint16) (err error) = kernel32.FreeEnvironmentStringsW
135
+//sys	GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) = kernel32.GetEnvironmentVariableW
136
+//sys	SetEnvironmentVariable(name *uint16, value *uint16) (err error) = kernel32.SetEnvironmentVariableW
137
+//sys	SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error)
138
+//sys	GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW
139
+//sys	SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW
140
+//sys	GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) = kernel32.GetFileAttributesExW
141
+//sys	GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW
142
+//sys	CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW
143
+//sys	LocalFree(hmem Handle) (handle Handle, err error) [failretval!=0]
144
+//sys	SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error)
145
+//sys	FlushFileBuffers(handle Handle) (err error)
146
+//sys	GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW
147
+//sys	GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW
148
+//sys	GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) = kernel32.GetShortPathNameW
149
+//sys	CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) = kernel32.CreateFileMappingW
150
+//sys	MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error)
151
+//sys	UnmapViewOfFile(addr uintptr) (err error)
152
+//sys	FlushViewOfFile(addr uintptr, length uintptr) (err error)
153
+//sys	VirtualLock(addr uintptr, length uintptr) (err error)
154
+//sys	VirtualUnlock(addr uintptr, length uintptr) (err error)
155
+//sys	TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile
156
+//sys	ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW
157
+//sys	CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW
158
+//sys   CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) [failretval==InvalidHandle] = crypt32.CertOpenStore
159
+//sys	CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore
160
+//sys   CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore
161
+//sys	CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore
162
+//sys   CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain
163
+//sys   CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain
164
+//sys   CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext
165
+//sys   CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext
166
+//sys   CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy
167
+//sys	RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW
168
+//sys	RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey
169
+//sys	RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegQueryInfoKeyW
170
+//sys	RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegEnumKeyExW
171
+//sys	RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegQueryValueExW
172
+//sys	getCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId
173
+//sys	GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode
174
+//sys	WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW
175
+//sys	ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW
176
+//sys	CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot
177
+//sys	Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32FirstW
178
+//sys	Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32NextW
179
+//sys	DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error)
180
+// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
181
+//sys	CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) [failretval&0xff==0] = CreateSymbolicLinkW
182
+//sys	CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) [failretval&0xff==0] = CreateHardLinkW
183
+//sys	GetCurrentThreadId() (id uint32)
184
+//sys	CreateEvent(eventAttrs *syscall.SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) = kernel32.CreateEventW
185
+//sys	SetEvent(event Handle) (err error) = kernel32.SetEvent
186
+
187
+// syscall interface implementation for other packages
188
+
189
+func Exit(code int) { ExitProcess(uint32(code)) }
190
+
191
+func makeInheritSa() *SecurityAttributes {
192
+	var sa SecurityAttributes
193
+	sa.Length = uint32(unsafe.Sizeof(sa))
194
+	sa.InheritHandle = 1
195
+	return &sa
196
+}
197
+
198
+func Open(path string, mode int, perm uint32) (fd Handle, err error) {
199
+	if len(path) == 0 {
200
+		return InvalidHandle, ERROR_FILE_NOT_FOUND
201
+	}
202
+	pathp, err := UTF16PtrFromString(path)
203
+	if err != nil {
204
+		return InvalidHandle, err
205
+	}
206
+	var access uint32
207
+	switch mode & (O_RDONLY | O_WRONLY | O_RDWR) {
208
+	case O_RDONLY:
209
+		access = GENERIC_READ
210
+	case O_WRONLY:
211
+		access = GENERIC_WRITE
212
+	case O_RDWR:
213
+		access = GENERIC_READ | GENERIC_WRITE
214
+	}
215
+	if mode&O_CREAT != 0 {
216
+		access |= GENERIC_WRITE
217
+	}
218
+	if mode&O_APPEND != 0 {
219
+		access &^= GENERIC_WRITE
220
+		access |= FILE_APPEND_DATA
221
+	}
222
+	sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE)
223
+	var sa *SecurityAttributes
224
+	if mode&O_CLOEXEC == 0 {
225
+		sa = makeInheritSa()
226
+	}
227
+	var createmode uint32
228
+	switch {
229
+	case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
230
+		createmode = CREATE_NEW
231
+	case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC):
232
+		createmode = CREATE_ALWAYS
233
+	case mode&O_CREAT == O_CREAT:
234
+		createmode = OPEN_ALWAYS
235
+	case mode&O_TRUNC == O_TRUNC:
236
+		createmode = TRUNCATE_EXISTING
237
+	default:
238
+		createmode = OPEN_EXISTING
239
+	}
240
+	h, e := CreateFile(pathp, access, sharemode, sa, createmode, FILE_ATTRIBUTE_NORMAL, 0)
241
+	return h, e
242
+}
243
+
244
+func Read(fd Handle, p []byte) (n int, err error) {
245
+	var done uint32
246
+	e := ReadFile(fd, p, &done, nil)
247
+	if e != nil {
248
+		if e == ERROR_BROKEN_PIPE {
249
+			// NOTE(brainman): work around ERROR_BROKEN_PIPE is returned on reading EOF from stdin
250
+			return 0, nil
251
+		}
252
+		return 0, e
253
+	}
254
+	if raceenabled {
255
+		if done > 0 {
256
+			raceWriteRange(unsafe.Pointer(&p[0]), int(done))
257
+		}
258
+		raceAcquire(unsafe.Pointer(&ioSync))
259
+	}
260
+	return int(done), nil
261
+}
262
+
263
+func Write(fd Handle, p []byte) (n int, err error) {
264
+	if raceenabled {
265
+		raceReleaseMerge(unsafe.Pointer(&ioSync))
266
+	}
267
+	var done uint32
268
+	e := WriteFile(fd, p, &done, nil)
269
+	if e != nil {
270
+		return 0, e
271
+	}
272
+	if raceenabled && done > 0 {
273
+		raceReadRange(unsafe.Pointer(&p[0]), int(done))
274
+	}
275
+	return int(done), nil
276
+}
277
+
278
+var ioSync int64
279
+
280
+func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) {
281
+	var w uint32
282
+	switch whence {
283
+	case 0:
284
+		w = FILE_BEGIN
285
+	case 1:
286
+		w = FILE_CURRENT
287
+	case 2:
288
+		w = FILE_END
289
+	}
290
+	hi := int32(offset >> 32)
291
+	lo := int32(offset)
292
+	// use GetFileType to check pipe, pipe can't do seek
293
+	ft, _ := GetFileType(fd)
294
+	if ft == FILE_TYPE_PIPE {
295
+		return 0, syscall.EPIPE
296
+	}
297
+	rlo, e := SetFilePointer(fd, lo, &hi, w)
298
+	if e != nil {
299
+		return 0, e
300
+	}
301
+	return int64(hi)<<32 + int64(rlo), nil
302
+}
303
+
304
+func Close(fd Handle) (err error) {
305
+	return CloseHandle(fd)
306
+}
307
+
308
+var (
309
+	Stdin  = getStdHandle(STD_INPUT_HANDLE)
310
+	Stdout = getStdHandle(STD_OUTPUT_HANDLE)
311
+	Stderr = getStdHandle(STD_ERROR_HANDLE)
312
+)
313
+
314
+func getStdHandle(h int) (fd Handle) {
315
+	r, _ := GetStdHandle(h)
316
+	CloseOnExec(r)
317
+	return r
318
+}
319
+
320
+const ImplementsGetwd = true
321
+
322
+func Getwd() (wd string, err error) {
323
+	b := make([]uint16, 300)
324
+	n, e := GetCurrentDirectory(uint32(len(b)), &b[0])
325
+	if e != nil {
326
+		return "", e
327
+	}
328
+	return string(utf16.Decode(b[0:n])), nil
329
+}
330
+
331
+func Chdir(path string) (err error) {
332
+	pathp, err := UTF16PtrFromString(path)
333
+	if err != nil {
334
+		return err
335
+	}
336
+	return SetCurrentDirectory(pathp)
337
+}
338
+
339
+func Mkdir(path string, mode uint32) (err error) {
340
+	pathp, err := UTF16PtrFromString(path)
341
+	if err != nil {
342
+		return err
343
+	}
344
+	return CreateDirectory(pathp, nil)
345
+}
346
+
347
+func Rmdir(path string) (err error) {
348
+	pathp, err := UTF16PtrFromString(path)
349
+	if err != nil {
350
+		return err
351
+	}
352
+	return RemoveDirectory(pathp)
353
+}
354
+
355
+func Unlink(path string) (err error) {
356
+	pathp, err := UTF16PtrFromString(path)
357
+	if err != nil {
358
+		return err
359
+	}
360
+	return DeleteFile(pathp)
361
+}
362
+
363
+func Rename(oldpath, newpath string) (err error) {
364
+	from, err := UTF16PtrFromString(oldpath)
365
+	if err != nil {
366
+		return err
367
+	}
368
+	to, err := UTF16PtrFromString(newpath)
369
+	if err != nil {
370
+		return err
371
+	}
372
+	return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING)
373
+}
374
+
375
+func ComputerName() (name string, err error) {
376
+	var n uint32 = MAX_COMPUTERNAME_LENGTH + 1
377
+	b := make([]uint16, n)
378
+	e := GetComputerName(&b[0], &n)
379
+	if e != nil {
380
+		return "", e
381
+	}
382
+	return string(utf16.Decode(b[0:n])), nil
383
+}
384
+
385
+func Ftruncate(fd Handle, length int64) (err error) {
386
+	curoffset, e := Seek(fd, 0, 1)
387
+	if e != nil {
388
+		return e
389
+	}
390
+	defer Seek(fd, curoffset, 0)
391
+	_, e = Seek(fd, length, 0)
392
+	if e != nil {
393
+		return e
394
+	}
395
+	e = SetEndOfFile(fd)
396
+	if e != nil {
397
+		return e
398
+	}
399
+	return nil
400
+}
401
+
402
+func Gettimeofday(tv *Timeval) (err error) {
403
+	var ft Filetime
404
+	GetSystemTimeAsFileTime(&ft)
405
+	*tv = NsecToTimeval(ft.Nanoseconds())
406
+	return nil
407
+}
408
+
409
+func Pipe(p []Handle) (err error) {
410
+	if len(p) != 2 {
411
+		return syscall.EINVAL
412
+	}
413
+	var r, w Handle
414
+	e := CreatePipe(&r, &w, makeInheritSa(), 0)
415
+	if e != nil {
416
+		return e
417
+	}
418
+	p[0] = r
419
+	p[1] = w
420
+	return nil
421
+}
422
+
423
+func Utimes(path string, tv []Timeval) (err error) {
424
+	if len(tv) != 2 {
425
+		return syscall.EINVAL
426
+	}
427
+	pathp, e := UTF16PtrFromString(path)
428
+	if e != nil {
429
+		return e
430
+	}
431
+	h, e := CreateFile(pathp,
432
+		FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
433
+		OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
434
+	if e != nil {
435
+		return e
436
+	}
437
+	defer Close(h)
438
+	a := NsecToFiletime(tv[0].Nanoseconds())
439
+	w := NsecToFiletime(tv[1].Nanoseconds())
440
+	return SetFileTime(h, nil, &a, &w)
441
+}
442
+
443
+func UtimesNano(path string, ts []Timespec) (err error) {
444
+	if len(ts) != 2 {
445
+		return syscall.EINVAL
446
+	}
447
+	pathp, e := UTF16PtrFromString(path)
448
+	if e != nil {
449
+		return e
450
+	}
451
+	h, e := CreateFile(pathp,
452
+		FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
453
+		OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
454
+	if e != nil {
455
+		return e
456
+	}
457
+	defer Close(h)
458
+	a := NsecToFiletime(TimespecToNsec(ts[0]))
459
+	w := NsecToFiletime(TimespecToNsec(ts[1]))
460
+	return SetFileTime(h, nil, &a, &w)
461
+}
462
+
463
+func Fsync(fd Handle) (err error) {
464
+	return FlushFileBuffers(fd)
465
+}
466
+
467
+func Chmod(path string, mode uint32) (err error) {
468
+	if mode == 0 {
469
+		return syscall.EINVAL
470
+	}
471
+	p, e := UTF16PtrFromString(path)
472
+	if e != nil {
473
+		return e
474
+	}
475
+	attrs, e := GetFileAttributes(p)
476
+	if e != nil {
477
+		return e
478
+	}
479
+	if mode&S_IWRITE != 0 {
480
+		attrs &^= FILE_ATTRIBUTE_READONLY
481
+	} else {
482
+		attrs |= FILE_ATTRIBUTE_READONLY
483
+	}
484
+	return SetFileAttributes(p, attrs)
485
+}
486
+
487
+func LoadCancelIoEx() error {
488
+	return procCancelIoEx.Find()
489
+}
490
+
491
+func LoadSetFileCompletionNotificationModes() error {
492
+	return procSetFileCompletionNotificationModes.Find()
493
+}
494
+
495
+// net api calls
496
+
497
+const socket_error = uintptr(^uint32(0))
498
+
499
+//sys	WSAStartup(verreq uint32, data *WSAData) (sockerr error) = ws2_32.WSAStartup
500
+//sys	WSACleanup() (err error) [failretval==socket_error] = ws2_32.WSACleanup
501
+//sys	WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) [failretval==socket_error] = ws2_32.WSAIoctl
502
+//sys	socket(af int32, typ int32, protocol int32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.socket
503
+//sys	Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) [failretval==socket_error] = ws2_32.setsockopt
504
+//sys	Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockopt
505
+//sys	bind(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.bind
506
+//sys	connect(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.connect
507
+//sys	getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockname
508
+//sys	getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getpeername
509
+//sys	listen(s Handle, backlog int32) (err error) [failretval==socket_error] = ws2_32.listen
510
+//sys	shutdown(s Handle, how int32) (err error) [failretval==socket_error] = ws2_32.shutdown
511
+//sys	Closesocket(s Handle) (err error) [failretval==socket_error] = ws2_32.closesocket
512
+//sys	AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) = mswsock.AcceptEx
513
+//sys	GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) = mswsock.GetAcceptExSockaddrs
514
+//sys	WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecv
515
+//sys	WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASend
516
+//sys	WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32,  from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom
517
+//sys	WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32,  overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo
518
+//sys	GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname
519
+//sys	GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname
520
+//sys	Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs
521
+//sys	GetProtoByName(name string) (p *Protoent, err error) [failretval==nil] = ws2_32.getprotobyname
522
+//sys	DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) = dnsapi.DnsQuery_W
523
+//sys	DnsRecordListFree(rl *DNSRecord, freetype uint32) = dnsapi.DnsRecordListFree
524
+//sys	DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) = dnsapi.DnsNameCompare_W
525
+//sys	GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) = ws2_32.GetAddrInfoW
526
+//sys	FreeAddrInfoW(addrinfo *AddrinfoW) = ws2_32.FreeAddrInfoW
527
+//sys	GetIfEntry(pIfRow *MibIfRow) (errcode error) = iphlpapi.GetIfEntry
528
+//sys	GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) = iphlpapi.GetAdaptersInfo
529
+//sys	SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) = kernel32.SetFileCompletionNotificationModes
530
+//sys	WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) [failretval==-1] = ws2_32.WSAEnumProtocolsW
531
+//sys	GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses
532
+//sys	GetACP() (acp uint32) = kernel32.GetACP
533
+//sys	MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar
534
+
535
+// For testing: clients can set this flag to force
536
+// creation of IPv6 sockets to return EAFNOSUPPORT.
537
+var SocketDisableIPv6 bool
538
+
539
+type RawSockaddrInet4 struct {
540
+	Family uint16
541
+	Port   uint16
542
+	Addr   [4]byte /* in_addr */
543
+	Zero   [8]uint8
544
+}
545
+
546
+type RawSockaddrInet6 struct {
547
+	Family   uint16
548
+	Port     uint16
549
+	Flowinfo uint32
550
+	Addr     [16]byte /* in6_addr */
551
+	Scope_id uint32
552
+}
553
+
554
+type RawSockaddr struct {
555
+	Family uint16
556
+	Data   [14]int8
557
+}
558
+
559
+type RawSockaddrAny struct {
560
+	Addr RawSockaddr
561
+	Pad  [96]int8
562
+}
563
+
564
+type Sockaddr interface {
565
+	sockaddr() (ptr unsafe.Pointer, len int32, err error) // lowercase; only we can define Sockaddrs
566
+}
567
+
568
+type SockaddrInet4 struct {
569
+	Port int
570
+	Addr [4]byte
571
+	raw  RawSockaddrInet4
572
+}
573
+
574
+func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, int32, error) {
575
+	if sa.Port < 0 || sa.Port > 0xFFFF {
576
+		return nil, 0, syscall.EINVAL
577
+	}
578
+	sa.raw.Family = AF_INET
579
+	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
580
+	p[0] = byte(sa.Port >> 8)
581
+	p[1] = byte(sa.Port)
582
+	for i := 0; i < len(sa.Addr); i++ {
583
+		sa.raw.Addr[i] = sa.Addr[i]
584
+	}
585
+	return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
586
+}
587
+
588
+type SockaddrInet6 struct {
589
+	Port   int
590
+	ZoneId uint32
591
+	Addr   [16]byte
592
+	raw    RawSockaddrInet6
593
+}
594
+
595
+func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) {
596
+	if sa.Port < 0 || sa.Port > 0xFFFF {
597
+		return nil, 0, syscall.EINVAL
598
+	}
599
+	sa.raw.Family = AF_INET6
600
+	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
601
+	p[0] = byte(sa.Port >> 8)
602
+	p[1] = byte(sa.Port)
603
+	sa.raw.Scope_id = sa.ZoneId
604
+	for i := 0; i < len(sa.Addr); i++ {
605
+		sa.raw.Addr[i] = sa.Addr[i]
606
+	}
607
+	return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
608
+}
609
+
610
+type SockaddrUnix struct {
611
+	Name string
612
+}
613
+
614
+func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) {
615
+	// TODO(brainman): implement SockaddrUnix.sockaddr()
616
+	return nil, 0, syscall.EWINDOWS
617
+}
618
+
619
+func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) {
620
+	switch rsa.Addr.Family {
621
+	case AF_UNIX:
622
+		return nil, syscall.EWINDOWS
623
+
624
+	case AF_INET:
625
+		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
626
+		sa := new(SockaddrInet4)
627
+		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
628
+		sa.Port = int(p[0])<<8 + int(p[1])
629
+		for i := 0; i < len(sa.Addr); i++ {
630
+			sa.Addr[i] = pp.Addr[i]
631
+		}
632
+		return sa, nil
633
+
634
+	case AF_INET6:
635
+		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
636
+		sa := new(SockaddrInet6)
637
+		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
638
+		sa.Port = int(p[0])<<8 + int(p[1])
639
+		sa.ZoneId = pp.Scope_id
640
+		for i := 0; i < len(sa.Addr); i++ {
641
+			sa.Addr[i] = pp.Addr[i]
642
+		}
643
+		return sa, nil
644
+	}
645
+	return nil, syscall.EAFNOSUPPORT
646
+}
647
+
648
+func Socket(domain, typ, proto int) (fd Handle, err error) {
649
+	if domain == AF_INET6 && SocketDisableIPv6 {
650
+		return InvalidHandle, syscall.EAFNOSUPPORT
651
+	}
652
+	return socket(int32(domain), int32(typ), int32(proto))
653
+}
654
+
655
+func SetsockoptInt(fd Handle, level, opt int, value int) (err error) {
656
+	v := int32(value)
657
+	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), int32(unsafe.Sizeof(v)))
658
+}
659
+
660
+func Bind(fd Handle, sa Sockaddr) (err error) {
661
+	ptr, n, err := sa.sockaddr()
662
+	if err != nil {
663
+		return err
664
+	}
665
+	return bind(fd, ptr, n)
666
+}
667
+
668
+func Connect(fd Handle, sa Sockaddr) (err error) {
669
+	ptr, n, err := sa.sockaddr()
670
+	if err != nil {
671
+		return err
672
+	}
673
+	return connect(fd, ptr, n)
674
+}
675
+
676
+func Getsockname(fd Handle) (sa Sockaddr, err error) {
677
+	var rsa RawSockaddrAny
678
+	l := int32(unsafe.Sizeof(rsa))
679
+	if err = getsockname(fd, &rsa, &l); err != nil {
680
+		return
681
+	}
682
+	return rsa.Sockaddr()
683
+}
684
+
685
+func Getpeername(fd Handle) (sa Sockaddr, err error) {
686
+	var rsa RawSockaddrAny
687
+	l := int32(unsafe.Sizeof(rsa))
688
+	if err = getpeername(fd, &rsa, &l); err != nil {
689
+		return
690
+	}
691
+	return rsa.Sockaddr()
692
+}
693
+
694
+func Listen(s Handle, n int) (err error) {
695
+	return listen(s, int32(n))
696
+}
697
+
698
+func Shutdown(fd Handle, how int) (err error) {
699
+	return shutdown(fd, int32(how))
700
+}
701
+
702
+func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) {
703
+	rsa, l, err := to.sockaddr()
704
+	if err != nil {
705
+		return err
706
+	}
707
+	return WSASendTo(s, bufs, bufcnt, sent, flags, (*RawSockaddrAny)(unsafe.Pointer(rsa)), l, overlapped, croutine)
708
+}
709
+
710
+func LoadGetAddrInfo() error {
711
+	return procGetAddrInfoW.Find()
712
+}
713
+
714
+var connectExFunc struct {
715
+	once sync.Once
716
+	addr uintptr
717
+	err  error
718
+}
719
+
720
+func LoadConnectEx() error {
721
+	connectExFunc.once.Do(func() {
722
+		var s Handle
723
+		s, connectExFunc.err = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
724
+		if connectExFunc.err != nil {
725
+			return
726
+		}
727
+		defer CloseHandle(s)
728
+		var n uint32
729
+		connectExFunc.err = WSAIoctl(s,
730
+			SIO_GET_EXTENSION_FUNCTION_POINTER,
731
+			(*byte)(unsafe.Pointer(&WSAID_CONNECTEX)),
732
+			uint32(unsafe.Sizeof(WSAID_CONNECTEX)),
733
+			(*byte)(unsafe.Pointer(&connectExFunc.addr)),
734
+			uint32(unsafe.Sizeof(connectExFunc.addr)),
735
+			&n, nil, 0)
736
+	})
737
+	return connectExFunc.err
738
+}
739
+
740
+func connectEx(s Handle, name unsafe.Pointer, namelen int32, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) (err error) {
741
+	r1, _, e1 := syscall.Syscall9(connectExFunc.addr, 7, uintptr(s), uintptr(name), uintptr(namelen), uintptr(unsafe.Pointer(sendBuf)), uintptr(sendDataLen), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), 0, 0)
742
+	if r1 == 0 {
743
+		if e1 != 0 {
744
+			err = error(e1)
745
+		} else {
746
+			err = syscall.EINVAL
747
+		}
748
+	}
749
+	return
750
+}
751
+
752
+func ConnectEx(fd Handle, sa Sockaddr, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) error {
753
+	err := LoadConnectEx()
754
+	if err != nil {
755
+		return errorspkg.New("failed to find ConnectEx: " + err.Error())
756
+	}
757
+	ptr, n, err := sa.sockaddr()
758
+	if err != nil {
759
+		return err
760
+	}
761
+	return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped)
762
+}
763
+
764
+// Invented structures to support what package os expects.
765
+type Rusage struct {
766
+	CreationTime Filetime
767
+	ExitTime     Filetime
768
+	KernelTime   Filetime
769
+	UserTime     Filetime
770
+}
771
+
772
+type WaitStatus struct {
773
+	ExitCode uint32
774
+}
775
+
776
+func (w WaitStatus) Exited() bool { return true }
777
+
778
+func (w WaitStatus) ExitStatus() int { return int(w.ExitCode) }
779
+
780
+func (w WaitStatus) Signal() Signal { return -1 }
781
+
782
+func (w WaitStatus) CoreDump() bool { return false }
783
+
784
+func (w WaitStatus) Stopped() bool { return false }
785
+
786
+func (w WaitStatus) Continued() bool { return false }
787
+
788
+func (w WaitStatus) StopSignal() Signal { return -1 }
789
+
790
+func (w WaitStatus) Signaled() bool { return false }
791
+
792
+func (w WaitStatus) TrapCause() int { return -1 }
793
+
794
+// Timespec is an invented structure on Windows, but here for
795
+// consistency with the corresponding package for other operating systems.
796
+type Timespec struct {
797
+	Sec  int64
798
+	Nsec int64
799
+}
800
+
801
+func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
802
+
803
+func NsecToTimespec(nsec int64) (ts Timespec) {
804
+	ts.Sec = nsec / 1e9
805
+	ts.Nsec = nsec % 1e9
806
+	return
807
+}
808
+
809
+// TODO(brainman): fix all needed for net
810
+
811
+func Accept(fd Handle) (nfd Handle, sa Sockaddr, err error) { return 0, nil, syscall.EWINDOWS }
812
+func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) {
813
+	return 0, nil, syscall.EWINDOWS
814
+}
815
+func Sendto(fd Handle, p []byte, flags int, to Sockaddr) (err error)       { return syscall.EWINDOWS }
816
+func SetsockoptTimeval(fd Handle, level, opt int, tv *Timeval) (err error) { return syscall.EWINDOWS }
817
+
818
+// The Linger struct is wrong but we only noticed after Go 1.
819
+// sysLinger is the real system call structure.
820
+
821
+// BUG(brainman): The definition of Linger is not appropriate for direct use
822
+// with Setsockopt and Getsockopt.
823
+// Use SetsockoptLinger instead.
824
+
825
+type Linger struct {
826
+	Onoff  int32
827
+	Linger int32
828
+}
829
+
830
+type sysLinger struct {
831
+	Onoff  uint16
832
+	Linger uint16
833
+}
834
+
835
+type IPMreq struct {
836
+	Multiaddr [4]byte /* in_addr */
837
+	Interface [4]byte /* in_addr */
838
+}
839
+
840
+type IPv6Mreq struct {
841
+	Multiaddr [16]byte /* in6_addr */
842
+	Interface uint32
843
+}
844
+
845
+func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, syscall.EWINDOWS }
846
+
847
+func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) {
848
+	sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)}
849
+	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&sys)), int32(unsafe.Sizeof(sys)))
850
+}
851
+
852
+func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) {
853
+	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4)
854
+}
855
+func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) {
856
+	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq)))
857
+}
858
+func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) {
859
+	return syscall.EWINDOWS
860
+}
861
+
862
+func Getpid() (pid int) { return int(getCurrentProcessId()) }
863
+
864
+func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) {
865
+	// NOTE(rsc): The Win32finddata struct is wrong for the system call:
866
+	// the two paths are each one uint16 short. Use the correct struct,
867
+	// a win32finddata1, and then copy the results out.
868
+	// There is no loss of expressivity here, because the final
869
+	// uint16, if it is used, is supposed to be a NUL, and Go doesn't need that.
870
+	// For Go 1.1, we might avoid the allocation of win32finddata1 here
871
+	// by adding a final Bug [2]uint16 field to the struct and then
872
+	// adjusting the fields in the result directly.
873
+	var data1 win32finddata1
874
+	handle, err = findFirstFile1(name, &data1)
875
+	if err == nil {
876
+		copyFindData(data, &data1)
877
+	}
878
+	return
879
+}
880
+
881
+func FindNextFile(handle Handle, data *Win32finddata) (err error) {
882
+	var data1 win32finddata1
883
+	err = findNextFile1(handle, &data1)
884
+	if err == nil {
885
+		copyFindData(data, &data1)
886
+	}
887
+	return
888
+}
889
+
890
+func getProcessEntry(pid int) (*ProcessEntry32, error) {
891
+	snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
892
+	if err != nil {
893
+		return nil, err
894
+	}
895
+	defer CloseHandle(snapshot)
896
+	var procEntry ProcessEntry32
897
+	procEntry.Size = uint32(unsafe.Sizeof(procEntry))
898
+	if err = Process32First(snapshot, &procEntry); err != nil {
899
+		return nil, err
900
+	}
901
+	for {
902
+		if procEntry.ProcessID == uint32(pid) {
903
+			return &procEntry, nil
904
+		}
905
+		err = Process32Next(snapshot, &procEntry)
906
+		if err != nil {
907
+			return nil, err
908
+		}
909
+	}
910
+}
911
+
912
+func Getppid() (ppid int) {
913
+	pe, err := getProcessEntry(Getpid())
914
+	if err != nil {
915
+		return -1
916
+	}
917
+	return int(pe.ParentProcessID)
918
+}
919
+
920
+// TODO(brainman): fix all needed for os
921
+func Fchdir(fd Handle) (err error)             { return syscall.EWINDOWS }
922
+func Link(oldpath, newpath string) (err error) { return syscall.EWINDOWS }
923
+func Symlink(path, link string) (err error)    { return syscall.EWINDOWS }
924
+
925
+func Fchmod(fd Handle, mode uint32) (err error)        { return syscall.EWINDOWS }
926
+func Chown(path string, uid int, gid int) (err error)  { return syscall.EWINDOWS }
927
+func Lchown(path string, uid int, gid int) (err error) { return syscall.EWINDOWS }
928
+func Fchown(fd Handle, uid int, gid int) (err error)   { return syscall.EWINDOWS }
929
+
930
+func Getuid() (uid int)                  { return -1 }
931
+func Geteuid() (euid int)                { return -1 }
932
+func Getgid() (gid int)                  { return -1 }
933
+func Getegid() (egid int)                { return -1 }
934
+func Getgroups() (gids []int, err error) { return nil, syscall.EWINDOWS }
935
+
936
+type Signal int
937
+
938
+func (s Signal) Signal() {}
939
+
940
+func (s Signal) String() string {
941
+	if 0 <= s && int(s) < len(signals) {
942
+		str := signals[s]
943
+		if str != "" {
944
+			return str
945
+		}
946
+	}
947
+	return "signal " + itoa(int(s))
948
+}
949
+
950
+func LoadCreateSymbolicLink() error {
951
+	return procCreateSymbolicLinkW.Find()
952
+}
953
+
954
+// Readlink returns the destination of the named symbolic link.
955
+func Readlink(path string, buf []byte) (n int, err error) {
956
+	fd, err := CreateFile(StringToUTF16Ptr(path), GENERIC_READ, 0, nil, OPEN_EXISTING,
957
+		FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0)
958
+	if err != nil {
959
+		return -1, err
960
+	}
961
+	defer CloseHandle(fd)
962
+
963
+	rdbbuf := make([]byte, MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
964
+	var bytesReturned uint32
965
+	err = DeviceIoControl(fd, FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
966
+	if err != nil {
967
+		return -1, err
968
+	}
969
+
970
+	rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0]))
971
+	var s string
972
+	switch rdb.ReparseTag {
973
+	case IO_REPARSE_TAG_SYMLINK:
974
+		data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
975
+		p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
976
+		s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2])
977
+	case IO_REPARSE_TAG_MOUNT_POINT:
978
+		data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
979
+		p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
980
+		s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2])
981
+	default:
982
+		// the path is not a symlink or junction but another type of reparse
983
+		// point
984
+		return -1, syscall.ENOENT
985
+	}
986
+	n = copy(buf, []byte(s))
987
+
988
+	return n, nil
989
+}
0 990
new file mode 100644
... ...
@@ -0,0 +1,2220 @@
0
+// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
1
+
2
+package windows
3
+
4
+import "unsafe"
5
+import "syscall"
6
+
7
+var _ unsafe.Pointer
8
+
9
+var (
10
+	modadvapi32 = syscall.NewLazyDLL("advapi32.dll")
11
+	modkernel32 = syscall.NewLazyDLL("kernel32.dll")
12
+	modshell32  = syscall.NewLazyDLL("shell32.dll")
13
+	modmswsock  = syscall.NewLazyDLL("mswsock.dll")
14
+	modcrypt32  = syscall.NewLazyDLL("crypt32.dll")
15
+	modws2_32   = syscall.NewLazyDLL("ws2_32.dll")
16
+	moddnsapi   = syscall.NewLazyDLL("dnsapi.dll")
17
+	modiphlpapi = syscall.NewLazyDLL("iphlpapi.dll")
18
+	modsecur32  = syscall.NewLazyDLL("secur32.dll")
19
+	modnetapi32 = syscall.NewLazyDLL("netapi32.dll")
20
+	moduserenv  = syscall.NewLazyDLL("userenv.dll")
21
+
22
+	procRegisterEventSourceW               = modadvapi32.NewProc("RegisterEventSourceW")
23
+	procDeregisterEventSource              = modadvapi32.NewProc("DeregisterEventSource")
24
+	procReportEventW                       = modadvapi32.NewProc("ReportEventW")
25
+	procOpenSCManagerW                     = modadvapi32.NewProc("OpenSCManagerW")
26
+	procCloseServiceHandle                 = modadvapi32.NewProc("CloseServiceHandle")
27
+	procCreateServiceW                     = modadvapi32.NewProc("CreateServiceW")
28
+	procOpenServiceW                       = modadvapi32.NewProc("OpenServiceW")
29
+	procDeleteService                      = modadvapi32.NewProc("DeleteService")
30
+	procStartServiceW                      = modadvapi32.NewProc("StartServiceW")
31
+	procQueryServiceStatus                 = modadvapi32.NewProc("QueryServiceStatus")
32
+	procControlService                     = modadvapi32.NewProc("ControlService")
33
+	procStartServiceCtrlDispatcherW        = modadvapi32.NewProc("StartServiceCtrlDispatcherW")
34
+	procSetServiceStatus                   = modadvapi32.NewProc("SetServiceStatus")
35
+	procChangeServiceConfigW               = modadvapi32.NewProc("ChangeServiceConfigW")
36
+	procQueryServiceConfigW                = modadvapi32.NewProc("QueryServiceConfigW")
37
+	procChangeServiceConfig2W              = modadvapi32.NewProc("ChangeServiceConfig2W")
38
+	procQueryServiceConfig2W               = modadvapi32.NewProc("QueryServiceConfig2W")
39
+	procGetLastError                       = modkernel32.NewProc("GetLastError")
40
+	procLoadLibraryW                       = modkernel32.NewProc("LoadLibraryW")
41
+	procFreeLibrary                        = modkernel32.NewProc("FreeLibrary")
42
+	procGetProcAddress                     = modkernel32.NewProc("GetProcAddress")
43
+	procGetVersion                         = modkernel32.NewProc("GetVersion")
44
+	procFormatMessageW                     = modkernel32.NewProc("FormatMessageW")
45
+	procExitProcess                        = modkernel32.NewProc("ExitProcess")
46
+	procCreateFileW                        = modkernel32.NewProc("CreateFileW")
47
+	procReadFile                           = modkernel32.NewProc("ReadFile")
48
+	procWriteFile                          = modkernel32.NewProc("WriteFile")
49
+	procSetFilePointer                     = modkernel32.NewProc("SetFilePointer")
50
+	procCloseHandle                        = modkernel32.NewProc("CloseHandle")
51
+	procGetStdHandle                       = modkernel32.NewProc("GetStdHandle")
52
+	procFindFirstFileW                     = modkernel32.NewProc("FindFirstFileW")
53
+	procFindNextFileW                      = modkernel32.NewProc("FindNextFileW")
54
+	procFindClose                          = modkernel32.NewProc("FindClose")
55
+	procGetFileInformationByHandle         = modkernel32.NewProc("GetFileInformationByHandle")
56
+	procGetCurrentDirectoryW               = modkernel32.NewProc("GetCurrentDirectoryW")
57
+	procSetCurrentDirectoryW               = modkernel32.NewProc("SetCurrentDirectoryW")
58
+	procCreateDirectoryW                   = modkernel32.NewProc("CreateDirectoryW")
59
+	procRemoveDirectoryW                   = modkernel32.NewProc("RemoveDirectoryW")
60
+	procDeleteFileW                        = modkernel32.NewProc("DeleteFileW")
61
+	procMoveFileW                          = modkernel32.NewProc("MoveFileW")
62
+	procMoveFileExW                        = modkernel32.NewProc("MoveFileExW")
63
+	procGetComputerNameW                   = modkernel32.NewProc("GetComputerNameW")
64
+	procGetComputerNameExW                 = modkernel32.NewProc("GetComputerNameExW")
65
+	procSetEndOfFile                       = modkernel32.NewProc("SetEndOfFile")
66
+	procGetSystemTimeAsFileTime            = modkernel32.NewProc("GetSystemTimeAsFileTime")
67
+	procGetTimeZoneInformation             = modkernel32.NewProc("GetTimeZoneInformation")
68
+	procCreateIoCompletionPort             = modkernel32.NewProc("CreateIoCompletionPort")
69
+	procGetQueuedCompletionStatus          = modkernel32.NewProc("GetQueuedCompletionStatus")
70
+	procPostQueuedCompletionStatus         = modkernel32.NewProc("PostQueuedCompletionStatus")
71
+	procCancelIo                           = modkernel32.NewProc("CancelIo")
72
+	procCancelIoEx                         = modkernel32.NewProc("CancelIoEx")
73
+	procCreateProcessW                     = modkernel32.NewProc("CreateProcessW")
74
+	procOpenProcess                        = modkernel32.NewProc("OpenProcess")
75
+	procTerminateProcess                   = modkernel32.NewProc("TerminateProcess")
76
+	procGetExitCodeProcess                 = modkernel32.NewProc("GetExitCodeProcess")
77
+	procGetStartupInfoW                    = modkernel32.NewProc("GetStartupInfoW")
78
+	procGetCurrentProcess                  = modkernel32.NewProc("GetCurrentProcess")
79
+	procGetProcessTimes                    = modkernel32.NewProc("GetProcessTimes")
80
+	procDuplicateHandle                    = modkernel32.NewProc("DuplicateHandle")
81
+	procWaitForSingleObject                = modkernel32.NewProc("WaitForSingleObject")
82
+	procGetTempPathW                       = modkernel32.NewProc("GetTempPathW")
83
+	procCreatePipe                         = modkernel32.NewProc("CreatePipe")
84
+	procGetFileType                        = modkernel32.NewProc("GetFileType")
85
+	procCryptAcquireContextW               = modadvapi32.NewProc("CryptAcquireContextW")
86
+	procCryptReleaseContext                = modadvapi32.NewProc("CryptReleaseContext")
87
+	procCryptGenRandom                     = modadvapi32.NewProc("CryptGenRandom")
88
+	procGetEnvironmentStringsW             = modkernel32.NewProc("GetEnvironmentStringsW")
89
+	procFreeEnvironmentStringsW            = modkernel32.NewProc("FreeEnvironmentStringsW")
90
+	procGetEnvironmentVariableW            = modkernel32.NewProc("GetEnvironmentVariableW")
91
+	procSetEnvironmentVariableW            = modkernel32.NewProc("SetEnvironmentVariableW")
92
+	procSetFileTime                        = modkernel32.NewProc("SetFileTime")
93
+	procGetFileAttributesW                 = modkernel32.NewProc("GetFileAttributesW")
94
+	procSetFileAttributesW                 = modkernel32.NewProc("SetFileAttributesW")
95
+	procGetFileAttributesExW               = modkernel32.NewProc("GetFileAttributesExW")
96
+	procGetCommandLineW                    = modkernel32.NewProc("GetCommandLineW")
97
+	procCommandLineToArgvW                 = modshell32.NewProc("CommandLineToArgvW")
98
+	procLocalFree                          = modkernel32.NewProc("LocalFree")
99
+	procSetHandleInformation               = modkernel32.NewProc("SetHandleInformation")
100
+	procFlushFileBuffers                   = modkernel32.NewProc("FlushFileBuffers")
101
+	procGetFullPathNameW                   = modkernel32.NewProc("GetFullPathNameW")
102
+	procGetLongPathNameW                   = modkernel32.NewProc("GetLongPathNameW")
103
+	procGetShortPathNameW                  = modkernel32.NewProc("GetShortPathNameW")
104
+	procCreateFileMappingW                 = modkernel32.NewProc("CreateFileMappingW")
105
+	procMapViewOfFile                      = modkernel32.NewProc("MapViewOfFile")
106
+	procUnmapViewOfFile                    = modkernel32.NewProc("UnmapViewOfFile")
107
+	procFlushViewOfFile                    = modkernel32.NewProc("FlushViewOfFile")
108
+	procVirtualLock                        = modkernel32.NewProc("VirtualLock")
109
+	procVirtualUnlock                      = modkernel32.NewProc("VirtualUnlock")
110
+	procTransmitFile                       = modmswsock.NewProc("TransmitFile")
111
+	procReadDirectoryChangesW              = modkernel32.NewProc("ReadDirectoryChangesW")
112
+	procCertOpenSystemStoreW               = modcrypt32.NewProc("CertOpenSystemStoreW")
113
+	procCertOpenStore                      = modcrypt32.NewProc("CertOpenStore")
114
+	procCertEnumCertificatesInStore        = modcrypt32.NewProc("CertEnumCertificatesInStore")
115
+	procCertAddCertificateContextToStore   = modcrypt32.NewProc("CertAddCertificateContextToStore")
116
+	procCertCloseStore                     = modcrypt32.NewProc("CertCloseStore")
117
+	procCertGetCertificateChain            = modcrypt32.NewProc("CertGetCertificateChain")
118
+	procCertFreeCertificateChain           = modcrypt32.NewProc("CertFreeCertificateChain")
119
+	procCertCreateCertificateContext       = modcrypt32.NewProc("CertCreateCertificateContext")
120
+	procCertFreeCertificateContext         = modcrypt32.NewProc("CertFreeCertificateContext")
121
+	procCertVerifyCertificateChainPolicy   = modcrypt32.NewProc("CertVerifyCertificateChainPolicy")
122
+	procRegOpenKeyExW                      = modadvapi32.NewProc("RegOpenKeyExW")
123
+	procRegCloseKey                        = modadvapi32.NewProc("RegCloseKey")
124
+	procRegQueryInfoKeyW                   = modadvapi32.NewProc("RegQueryInfoKeyW")
125
+	procRegEnumKeyExW                      = modadvapi32.NewProc("RegEnumKeyExW")
126
+	procRegQueryValueExW                   = modadvapi32.NewProc("RegQueryValueExW")
127
+	procGetCurrentProcessId                = modkernel32.NewProc("GetCurrentProcessId")
128
+	procGetConsoleMode                     = modkernel32.NewProc("GetConsoleMode")
129
+	procWriteConsoleW                      = modkernel32.NewProc("WriteConsoleW")
130
+	procReadConsoleW                       = modkernel32.NewProc("ReadConsoleW")
131
+	procCreateToolhelp32Snapshot           = modkernel32.NewProc("CreateToolhelp32Snapshot")
132
+	procProcess32FirstW                    = modkernel32.NewProc("Process32FirstW")
133
+	procProcess32NextW                     = modkernel32.NewProc("Process32NextW")
134
+	procDeviceIoControl                    = modkernel32.NewProc("DeviceIoControl")
135
+	procCreateSymbolicLinkW                = modkernel32.NewProc("CreateSymbolicLinkW")
136
+	procCreateHardLinkW                    = modkernel32.NewProc("CreateHardLinkW")
137
+	procGetCurrentThreadId                 = modkernel32.NewProc("GetCurrentThreadId")
138
+	procCreateEventW                       = modkernel32.NewProc("CreateEventW")
139
+	procSetEvent                           = modkernel32.NewProc("SetEvent")
140
+	procWSAStartup                         = modws2_32.NewProc("WSAStartup")
141
+	procWSACleanup                         = modws2_32.NewProc("WSACleanup")
142
+	procWSAIoctl                           = modws2_32.NewProc("WSAIoctl")
143
+	procsocket                             = modws2_32.NewProc("socket")
144
+	procsetsockopt                         = modws2_32.NewProc("setsockopt")
145
+	procgetsockopt                         = modws2_32.NewProc("getsockopt")
146
+	procbind                               = modws2_32.NewProc("bind")
147
+	procconnect                            = modws2_32.NewProc("connect")
148
+	procgetsockname                        = modws2_32.NewProc("getsockname")
149
+	procgetpeername                        = modws2_32.NewProc("getpeername")
150
+	proclisten                             = modws2_32.NewProc("listen")
151
+	procshutdown                           = modws2_32.NewProc("shutdown")
152
+	procclosesocket                        = modws2_32.NewProc("closesocket")
153
+	procAcceptEx                           = modmswsock.NewProc("AcceptEx")
154
+	procGetAcceptExSockaddrs               = modmswsock.NewProc("GetAcceptExSockaddrs")
155
+	procWSARecv                            = modws2_32.NewProc("WSARecv")
156
+	procWSASend                            = modws2_32.NewProc("WSASend")
157
+	procWSARecvFrom                        = modws2_32.NewProc("WSARecvFrom")
158
+	procWSASendTo                          = modws2_32.NewProc("WSASendTo")
159
+	procgethostbyname                      = modws2_32.NewProc("gethostbyname")
160
+	procgetservbyname                      = modws2_32.NewProc("getservbyname")
161
+	procntohs                              = modws2_32.NewProc("ntohs")
162
+	procgetprotobyname                     = modws2_32.NewProc("getprotobyname")
163
+	procDnsQuery_W                         = moddnsapi.NewProc("DnsQuery_W")
164
+	procDnsRecordListFree                  = moddnsapi.NewProc("DnsRecordListFree")
165
+	procDnsNameCompare_W                   = moddnsapi.NewProc("DnsNameCompare_W")
166
+	procGetAddrInfoW                       = modws2_32.NewProc("GetAddrInfoW")
167
+	procFreeAddrInfoW                      = modws2_32.NewProc("FreeAddrInfoW")
168
+	procGetIfEntry                         = modiphlpapi.NewProc("GetIfEntry")
169
+	procGetAdaptersInfo                    = modiphlpapi.NewProc("GetAdaptersInfo")
170
+	procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
171
+	procWSAEnumProtocolsW                  = modws2_32.NewProc("WSAEnumProtocolsW")
172
+	procGetAdaptersAddresses               = modiphlpapi.NewProc("GetAdaptersAddresses")
173
+	procGetACP                             = modkernel32.NewProc("GetACP")
174
+	procMultiByteToWideChar                = modkernel32.NewProc("MultiByteToWideChar")
175
+	procTranslateNameW                     = modsecur32.NewProc("TranslateNameW")
176
+	procGetUserNameExW                     = modsecur32.NewProc("GetUserNameExW")
177
+	procNetUserGetInfo                     = modnetapi32.NewProc("NetUserGetInfo")
178
+	procNetGetJoinInformation              = modnetapi32.NewProc("NetGetJoinInformation")
179
+	procNetApiBufferFree                   = modnetapi32.NewProc("NetApiBufferFree")
180
+	procLookupAccountSidW                  = modadvapi32.NewProc("LookupAccountSidW")
181
+	procLookupAccountNameW                 = modadvapi32.NewProc("LookupAccountNameW")
182
+	procConvertSidToStringSidW             = modadvapi32.NewProc("ConvertSidToStringSidW")
183
+	procConvertStringSidToSidW             = modadvapi32.NewProc("ConvertStringSidToSidW")
184
+	procGetLengthSid                       = modadvapi32.NewProc("GetLengthSid")
185
+	procCopySid                            = modadvapi32.NewProc("CopySid")
186
+	procAllocateAndInitializeSid           = modadvapi32.NewProc("AllocateAndInitializeSid")
187
+	procFreeSid                            = modadvapi32.NewProc("FreeSid")
188
+	procEqualSid                           = modadvapi32.NewProc("EqualSid")
189
+	procOpenProcessToken                   = modadvapi32.NewProc("OpenProcessToken")
190
+	procGetTokenInformation                = modadvapi32.NewProc("GetTokenInformation")
191
+	procGetUserProfileDirectoryW           = moduserenv.NewProc("GetUserProfileDirectoryW")
192
+)
193
+
194
+func RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) {
195
+	r0, _, e1 := syscall.Syscall(procRegisterEventSourceW.Addr(), 2, uintptr(unsafe.Pointer(uncServerName)), uintptr(unsafe.Pointer(sourceName)), 0)
196
+	handle = Handle(r0)
197
+	if handle == 0 {
198
+		if e1 != 0 {
199
+			err = error(e1)
200
+		} else {
201
+			err = syscall.EINVAL
202
+		}
203
+	}
204
+	return
205
+}
206
+
207
+func DeregisterEventSource(handle Handle) (err error) {
208
+	r1, _, e1 := syscall.Syscall(procDeregisterEventSource.Addr(), 1, uintptr(handle), 0, 0)
209
+	if r1 == 0 {
210
+		if e1 != 0 {
211
+			err = error(e1)
212
+		} else {
213
+			err = syscall.EINVAL
214
+		}
215
+	}
216
+	return
217
+}
218
+
219
+func ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) {
220
+	r1, _, e1 := syscall.Syscall9(procReportEventW.Addr(), 9, uintptr(log), uintptr(etype), uintptr(category), uintptr(eventId), uintptr(usrSId), uintptr(numStrings), uintptr(dataSize), uintptr(unsafe.Pointer(strings)), uintptr(unsafe.Pointer(rawData)))
221
+	if r1 == 0 {
222
+		if e1 != 0 {
223
+			err = error(e1)
224
+		} else {
225
+			err = syscall.EINVAL
226
+		}
227
+	}
228
+	return
229
+}
230
+
231
+func OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) {
232
+	r0, _, e1 := syscall.Syscall(procOpenSCManagerW.Addr(), 3, uintptr(unsafe.Pointer(machineName)), uintptr(unsafe.Pointer(databaseName)), uintptr(access))
233
+	handle = Handle(r0)
234
+	if handle == 0 {
235
+		if e1 != 0 {
236
+			err = error(e1)
237
+		} else {
238
+			err = syscall.EINVAL
239
+		}
240
+	}
241
+	return
242
+}
243
+
244
+func CloseServiceHandle(handle Handle) (err error) {
245
+	r1, _, e1 := syscall.Syscall(procCloseServiceHandle.Addr(), 1, uintptr(handle), 0, 0)
246
+	if r1 == 0 {
247
+		if e1 != 0 {
248
+			err = error(e1)
249
+		} else {
250
+			err = syscall.EINVAL
251
+		}
252
+	}
253
+	return
254
+}
255
+
256
+func CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) {
257
+	r0, _, e1 := syscall.Syscall15(procCreateServiceW.Addr(), 13, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(unsafe.Pointer(displayName)), uintptr(access), uintptr(srvType), uintptr(startType), uintptr(errCtl), uintptr(unsafe.Pointer(pathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), 0, 0)
258
+	handle = Handle(r0)
259
+	if handle == 0 {
260
+		if e1 != 0 {
261
+			err = error(e1)
262
+		} else {
263
+			err = syscall.EINVAL
264
+		}
265
+	}
266
+	return
267
+}
268
+
269
+func OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) {
270
+	r0, _, e1 := syscall.Syscall(procOpenServiceW.Addr(), 3, uintptr(mgr), uintptr(unsafe.Pointer(serviceName)), uintptr(access))
271
+	handle = Handle(r0)
272
+	if handle == 0 {
273
+		if e1 != 0 {
274
+			err = error(e1)
275
+		} else {
276
+			err = syscall.EINVAL
277
+		}
278
+	}
279
+	return
280
+}
281
+
282
+func DeleteService(service Handle) (err error) {
283
+	r1, _, e1 := syscall.Syscall(procDeleteService.Addr(), 1, uintptr(service), 0, 0)
284
+	if r1 == 0 {
285
+		if e1 != 0 {
286
+			err = error(e1)
287
+		} else {
288
+			err = syscall.EINVAL
289
+		}
290
+	}
291
+	return
292
+}
293
+
294
+func StartService(service Handle, numArgs uint32, argVectors **uint16) (err error) {
295
+	r1, _, e1 := syscall.Syscall(procStartServiceW.Addr(), 3, uintptr(service), uintptr(numArgs), uintptr(unsafe.Pointer(argVectors)))
296
+	if r1 == 0 {
297
+		if e1 != 0 {
298
+			err = error(e1)
299
+		} else {
300
+			err = syscall.EINVAL
301
+		}
302
+	}
303
+	return
304
+}
305
+
306
+func QueryServiceStatus(service Handle, status *SERVICE_STATUS) (err error) {
307
+	r1, _, e1 := syscall.Syscall(procQueryServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(status)), 0)
308
+	if r1 == 0 {
309
+		if e1 != 0 {
310
+			err = error(e1)
311
+		} else {
312
+			err = syscall.EINVAL
313
+		}
314
+	}
315
+	return
316
+}
317
+
318
+func ControlService(service Handle, control uint32, status *SERVICE_STATUS) (err error) {
319
+	r1, _, e1 := syscall.Syscall(procControlService.Addr(), 3, uintptr(service), uintptr(control), uintptr(unsafe.Pointer(status)))
320
+	if r1 == 0 {
321
+		if e1 != 0 {
322
+			err = error(e1)
323
+		} else {
324
+			err = syscall.EINVAL
325
+		}
326
+	}
327
+	return
328
+}
329
+
330
+func StartServiceCtrlDispatcher(serviceTable *SERVICE_TABLE_ENTRY) (err error) {
331
+	r1, _, e1 := syscall.Syscall(procStartServiceCtrlDispatcherW.Addr(), 1, uintptr(unsafe.Pointer(serviceTable)), 0, 0)
332
+	if r1 == 0 {
333
+		if e1 != 0 {
334
+			err = error(e1)
335
+		} else {
336
+			err = syscall.EINVAL
337
+		}
338
+	}
339
+	return
340
+}
341
+
342
+func SetServiceStatus(service Handle, serviceStatus *SERVICE_STATUS) (err error) {
343
+	r1, _, e1 := syscall.Syscall(procSetServiceStatus.Addr(), 2, uintptr(service), uintptr(unsafe.Pointer(serviceStatus)), 0)
344
+	if r1 == 0 {
345
+		if e1 != 0 {
346
+			err = error(e1)
347
+		} else {
348
+			err = syscall.EINVAL
349
+		}
350
+	}
351
+	return
352
+}
353
+
354
+func ChangeServiceConfig(service Handle, serviceType uint32, startType uint32, errorControl uint32, binaryPathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16, displayName *uint16) (err error) {
355
+	r1, _, e1 := syscall.Syscall12(procChangeServiceConfigW.Addr(), 11, uintptr(service), uintptr(serviceType), uintptr(startType), uintptr(errorControl), uintptr(unsafe.Pointer(binaryPathName)), uintptr(unsafe.Pointer(loadOrderGroup)), uintptr(unsafe.Pointer(tagId)), uintptr(unsafe.Pointer(dependencies)), uintptr(unsafe.Pointer(serviceStartName)), uintptr(unsafe.Pointer(password)), uintptr(unsafe.Pointer(displayName)), 0)
356
+	if r1 == 0 {
357
+		if e1 != 0 {
358
+			err = error(e1)
359
+		} else {
360
+			err = syscall.EINVAL
361
+		}
362
+	}
363
+	return
364
+}
365
+
366
+func QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, bufSize uint32, bytesNeeded *uint32) (err error) {
367
+	r1, _, e1 := syscall.Syscall6(procQueryServiceConfigW.Addr(), 4, uintptr(service), uintptr(unsafe.Pointer(serviceConfig)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), 0, 0)
368
+	if r1 == 0 {
369
+		if e1 != 0 {
370
+			err = error(e1)
371
+		} else {
372
+			err = syscall.EINVAL
373
+		}
374
+	}
375
+	return
376
+}
377
+
378
+func ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) {
379
+	r1, _, e1 := syscall.Syscall(procChangeServiceConfig2W.Addr(), 3, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(info)))
380
+	if r1 == 0 {
381
+		if e1 != 0 {
382
+			err = error(e1)
383
+		} else {
384
+			err = syscall.EINVAL
385
+		}
386
+	}
387
+	return
388
+}
389
+
390
+func QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) {
391
+	r1, _, e1 := syscall.Syscall6(procQueryServiceConfig2W.Addr(), 5, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), 0)
392
+	if r1 == 0 {
393
+		if e1 != 0 {
394
+			err = error(e1)
395
+		} else {
396
+			err = syscall.EINVAL
397
+		}
398
+	}
399
+	return
400
+}
401
+
402
+func GetLastError() (lasterr error) {
403
+	r0, _, _ := syscall.Syscall(procGetLastError.Addr(), 0, 0, 0, 0)
404
+	if r0 != 0 {
405
+		lasterr = syscall.Errno(r0)
406
+	}
407
+	return
408
+}
409
+
410
+func LoadLibrary(libname string) (handle Handle, err error) {
411
+	var _p0 *uint16
412
+	_p0, err = syscall.UTF16PtrFromString(libname)
413
+	if err != nil {
414
+		return
415
+	}
416
+	return _LoadLibrary(_p0)
417
+}
418
+
419
+func _LoadLibrary(libname *uint16) (handle Handle, err error) {
420
+	r0, _, e1 := syscall.Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(libname)), 0, 0)
421
+	handle = Handle(r0)
422
+	if handle == 0 {
423
+		if e1 != 0 {
424
+			err = error(e1)
425
+		} else {
426
+			err = syscall.EINVAL
427
+		}
428
+	}
429
+	return
430
+}
431
+
432
+func FreeLibrary(handle Handle) (err error) {
433
+	r1, _, e1 := syscall.Syscall(procFreeLibrary.Addr(), 1, uintptr(handle), 0, 0)
434
+	if r1 == 0 {
435
+		if e1 != 0 {
436
+			err = error(e1)
437
+		} else {
438
+			err = syscall.EINVAL
439
+		}
440
+	}
441
+	return
442
+}
443
+
444
+func GetProcAddress(module Handle, procname string) (proc uintptr, err error) {
445
+	var _p0 *byte
446
+	_p0, err = syscall.BytePtrFromString(procname)
447
+	if err != nil {
448
+		return
449
+	}
450
+	return _GetProcAddress(module, _p0)
451
+}
452
+
453
+func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) {
454
+	r0, _, e1 := syscall.Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(procname)), 0)
455
+	proc = uintptr(r0)
456
+	if proc == 0 {
457
+		if e1 != 0 {
458
+			err = error(e1)
459
+		} else {
460
+			err = syscall.EINVAL
461
+		}
462
+	}
463
+	return
464
+}
465
+
466
+func GetVersion() (ver uint32, err error) {
467
+	r0, _, e1 := syscall.Syscall(procGetVersion.Addr(), 0, 0, 0, 0)
468
+	ver = uint32(r0)
469
+	if ver == 0 {
470
+		if e1 != 0 {
471
+			err = error(e1)
472
+		} else {
473
+			err = syscall.EINVAL
474
+		}
475
+	}
476
+	return
477
+}
478
+
479
+func FormatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) {
480
+	var _p0 *uint16
481
+	if len(buf) > 0 {
482
+		_p0 = &buf[0]
483
+	}
484
+	r0, _, e1 := syscall.Syscall9(procFormatMessageW.Addr(), 7, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0)
485
+	n = uint32(r0)
486
+	if n == 0 {
487
+		if e1 != 0 {
488
+			err = error(e1)
489
+		} else {
490
+			err = syscall.EINVAL
491
+		}
492
+	}
493
+	return
494
+}
495
+
496
+func ExitProcess(exitcode uint32) {
497
+	syscall.Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0)
498
+	return
499
+}
500
+
501
+func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) {
502
+	r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
503
+	handle = Handle(r0)
504
+	if handle == InvalidHandle {
505
+		if e1 != 0 {
506
+			err = error(e1)
507
+		} else {
508
+			err = syscall.EINVAL
509
+		}
510
+	}
511
+	return
512
+}
513
+
514
+func ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) {
515
+	var _p0 *byte
516
+	if len(buf) > 0 {
517
+		_p0 = &buf[0]
518
+	}
519
+	r1, _, e1 := syscall.Syscall6(procReadFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0)
520
+	if r1 == 0 {
521
+		if e1 != 0 {
522
+			err = error(e1)
523
+		} else {
524
+			err = syscall.EINVAL
525
+		}
526
+	}
527
+	return
528
+}
529
+
530
+func WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) {
531
+	var _p0 *byte
532
+	if len(buf) > 0 {
533
+		_p0 = &buf[0]
534
+	}
535
+	r1, _, e1 := syscall.Syscall6(procWriteFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0)
536
+	if r1 == 0 {
537
+		if e1 != 0 {
538
+			err = error(e1)
539
+		} else {
540
+			err = syscall.EINVAL
541
+		}
542
+	}
543
+	return
544
+}
545
+
546
+func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) {
547
+	r0, _, e1 := syscall.Syscall6(procSetFilePointer.Addr(), 4, uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence), 0, 0)
548
+	newlowoffset = uint32(r0)
549
+	if newlowoffset == 0xffffffff {
550
+		if e1 != 0 {
551
+			err = error(e1)
552
+		} else {
553
+			err = syscall.EINVAL
554
+		}
555
+	}
556
+	return
557
+}
558
+
559
+func CloseHandle(handle Handle) (err error) {
560
+	r1, _, e1 := syscall.Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0)
561
+	if r1 == 0 {
562
+		if e1 != 0 {
563
+			err = error(e1)
564
+		} else {
565
+			err = syscall.EINVAL
566
+		}
567
+	}
568
+	return
569
+}
570
+
571
+func GetStdHandle(stdhandle int) (handle Handle, err error) {
572
+	r0, _, e1 := syscall.Syscall(procGetStdHandle.Addr(), 1, uintptr(stdhandle), 0, 0)
573
+	handle = Handle(r0)
574
+	if handle == InvalidHandle {
575
+		if e1 != 0 {
576
+			err = error(e1)
577
+		} else {
578
+			err = syscall.EINVAL
579
+		}
580
+	}
581
+	return
582
+}
583
+
584
+func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) {
585
+	r0, _, e1 := syscall.Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0)
586
+	handle = Handle(r0)
587
+	if handle == InvalidHandle {
588
+		if e1 != 0 {
589
+			err = error(e1)
590
+		} else {
591
+			err = syscall.EINVAL
592
+		}
593
+	}
594
+	return
595
+}
596
+
597
+func findNextFile1(handle Handle, data *win32finddata1) (err error) {
598
+	r1, _, e1 := syscall.Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
599
+	if r1 == 0 {
600
+		if e1 != 0 {
601
+			err = error(e1)
602
+		} else {
603
+			err = syscall.EINVAL
604
+		}
605
+	}
606
+	return
607
+}
608
+
609
+func FindClose(handle Handle) (err error) {
610
+	r1, _, e1 := syscall.Syscall(procFindClose.Addr(), 1, uintptr(handle), 0, 0)
611
+	if r1 == 0 {
612
+		if e1 != 0 {
613
+			err = error(e1)
614
+		} else {
615
+			err = syscall.EINVAL
616
+		}
617
+	}
618
+	return
619
+}
620
+
621
+func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) {
622
+	r1, _, e1 := syscall.Syscall(procGetFileInformationByHandle.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
623
+	if r1 == 0 {
624
+		if e1 != 0 {
625
+			err = error(e1)
626
+		} else {
627
+			err = syscall.EINVAL
628
+		}
629
+	}
630
+	return
631
+}
632
+
633
+func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) {
634
+	r0, _, e1 := syscall.Syscall(procGetCurrentDirectoryW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
635
+	n = uint32(r0)
636
+	if n == 0 {
637
+		if e1 != 0 {
638
+			err = error(e1)
639
+		} else {
640
+			err = syscall.EINVAL
641
+		}
642
+	}
643
+	return
644
+}
645
+
646
+func SetCurrentDirectory(path *uint16) (err error) {
647
+	r1, _, e1 := syscall.Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
648
+	if r1 == 0 {
649
+		if e1 != 0 {
650
+			err = error(e1)
651
+		} else {
652
+			err = syscall.EINVAL
653
+		}
654
+	}
655
+	return
656
+}
657
+
658
+func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) {
659
+	r1, _, e1 := syscall.Syscall(procCreateDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa)), 0)
660
+	if r1 == 0 {
661
+		if e1 != 0 {
662
+			err = error(e1)
663
+		} else {
664
+			err = syscall.EINVAL
665
+		}
666
+	}
667
+	return
668
+}
669
+
670
+func RemoveDirectory(path *uint16) (err error) {
671
+	r1, _, e1 := syscall.Syscall(procRemoveDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
672
+	if r1 == 0 {
673
+		if e1 != 0 {
674
+			err = error(e1)
675
+		} else {
676
+			err = syscall.EINVAL
677
+		}
678
+	}
679
+	return
680
+}
681
+
682
+func DeleteFile(path *uint16) (err error) {
683
+	r1, _, e1 := syscall.Syscall(procDeleteFileW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
684
+	if r1 == 0 {
685
+		if e1 != 0 {
686
+			err = error(e1)
687
+		} else {
688
+			err = syscall.EINVAL
689
+		}
690
+	}
691
+	return
692
+}
693
+
694
+func MoveFile(from *uint16, to *uint16) (err error) {
695
+	r1, _, e1 := syscall.Syscall(procMoveFileW.Addr(), 2, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), 0)
696
+	if r1 == 0 {
697
+		if e1 != 0 {
698
+			err = error(e1)
699
+		} else {
700
+			err = syscall.EINVAL
701
+		}
702
+	}
703
+	return
704
+}
705
+
706
+func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) {
707
+	r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags))
708
+	if r1 == 0 {
709
+		if e1 != 0 {
710
+			err = error(e1)
711
+		} else {
712
+			err = syscall.EINVAL
713
+		}
714
+	}
715
+	return
716
+}
717
+
718
+func GetComputerName(buf *uint16, n *uint32) (err error) {
719
+	r1, _, e1 := syscall.Syscall(procGetComputerNameW.Addr(), 2, uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)), 0)
720
+	if r1 == 0 {
721
+		if e1 != 0 {
722
+			err = error(e1)
723
+		} else {
724
+			err = syscall.EINVAL
725
+		}
726
+	}
727
+	return
728
+}
729
+
730
+func GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) {
731
+	r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nametype), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)))
732
+	if r1 == 0 {
733
+		if e1 != 0 {
734
+			err = error(e1)
735
+		} else {
736
+			err = syscall.EINVAL
737
+		}
738
+	}
739
+	return
740
+}
741
+
742
+func SetEndOfFile(handle Handle) (err error) {
743
+	r1, _, e1 := syscall.Syscall(procSetEndOfFile.Addr(), 1, uintptr(handle), 0, 0)
744
+	if r1 == 0 {
745
+		if e1 != 0 {
746
+			err = error(e1)
747
+		} else {
748
+			err = syscall.EINVAL
749
+		}
750
+	}
751
+	return
752
+}
753
+
754
+func GetSystemTimeAsFileTime(time *Filetime) {
755
+	syscall.Syscall(procGetSystemTimeAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0)
756
+	return
757
+}
758
+
759
+func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) {
760
+	r0, _, e1 := syscall.Syscall(procGetTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(tzi)), 0, 0)
761
+	rc = uint32(r0)
762
+	if rc == 0xffffffff {
763
+		if e1 != 0 {
764
+			err = error(e1)
765
+		} else {
766
+			err = syscall.EINVAL
767
+		}
768
+	}
769
+	return
770
+}
771
+
772
+func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error) {
773
+	r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt), 0, 0)
774
+	handle = Handle(r0)
775
+	if handle == 0 {
776
+		if e1 != 0 {
777
+			err = error(e1)
778
+		} else {
779
+			err = syscall.EINVAL
780
+		}
781
+	}
782
+	return
783
+}
784
+
785
+func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error) {
786
+	r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0)
787
+	if r1 == 0 {
788
+		if e1 != 0 {
789
+			err = error(e1)
790
+		} else {
791
+			err = syscall.EINVAL
792
+		}
793
+	}
794
+	return
795
+}
796
+
797
+func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error) {
798
+	r1, _, e1 := syscall.Syscall6(procPostQueuedCompletionStatus.Addr(), 4, uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped)), 0, 0)
799
+	if r1 == 0 {
800
+		if e1 != 0 {
801
+			err = error(e1)
802
+		} else {
803
+			err = syscall.EINVAL
804
+		}
805
+	}
806
+	return
807
+}
808
+
809
+func CancelIo(s Handle) (err error) {
810
+	r1, _, e1 := syscall.Syscall(procCancelIo.Addr(), 1, uintptr(s), 0, 0)
811
+	if r1 == 0 {
812
+		if e1 != 0 {
813
+			err = error(e1)
814
+		} else {
815
+			err = syscall.EINVAL
816
+		}
817
+	}
818
+	return
819
+}
820
+
821
+func CancelIoEx(s Handle, o *Overlapped) (err error) {
822
+	r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(s), uintptr(unsafe.Pointer(o)), 0)
823
+	if r1 == 0 {
824
+		if e1 != 0 {
825
+			err = error(e1)
826
+		} else {
827
+			err = syscall.EINVAL
828
+		}
829
+	}
830
+	return
831
+}
832
+
833
+func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) {
834
+	var _p0 uint32
835
+	if inheritHandles {
836
+		_p0 = 1
837
+	} else {
838
+		_p0 = 0
839
+	}
840
+	r1, _, e1 := syscall.Syscall12(procCreateProcessW.Addr(), 10, uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0, 0)
841
+	if r1 == 0 {
842
+		if e1 != 0 {
843
+			err = error(e1)
844
+		} else {
845
+			err = syscall.EINVAL
846
+		}
847
+	}
848
+	return
849
+}
850
+
851
+func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) {
852
+	var _p0 uint32
853
+	if inheritHandle {
854
+		_p0 = 1
855
+	} else {
856
+		_p0 = 0
857
+	}
858
+	r0, _, e1 := syscall.Syscall(procOpenProcess.Addr(), 3, uintptr(da), uintptr(_p0), uintptr(pid))
859
+	handle = Handle(r0)
860
+	if handle == 0 {
861
+		if e1 != 0 {
862
+			err = error(e1)
863
+		} else {
864
+			err = syscall.EINVAL
865
+		}
866
+	}
867
+	return
868
+}
869
+
870
+func TerminateProcess(handle Handle, exitcode uint32) (err error) {
871
+	r1, _, e1 := syscall.Syscall(procTerminateProcess.Addr(), 2, uintptr(handle), uintptr(exitcode), 0)
872
+	if r1 == 0 {
873
+		if e1 != 0 {
874
+			err = error(e1)
875
+		} else {
876
+			err = syscall.EINVAL
877
+		}
878
+	}
879
+	return
880
+}
881
+
882
+func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) {
883
+	r1, _, e1 := syscall.Syscall(procGetExitCodeProcess.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(exitcode)), 0)
884
+	if r1 == 0 {
885
+		if e1 != 0 {
886
+			err = error(e1)
887
+		} else {
888
+			err = syscall.EINVAL
889
+		}
890
+	}
891
+	return
892
+}
893
+
894
+func GetStartupInfo(startupInfo *StartupInfo) (err error) {
895
+	r1, _, e1 := syscall.Syscall(procGetStartupInfoW.Addr(), 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0)
896
+	if r1 == 0 {
897
+		if e1 != 0 {
898
+			err = error(e1)
899
+		} else {
900
+			err = syscall.EINVAL
901
+		}
902
+	}
903
+	return
904
+}
905
+
906
+func GetCurrentProcess() (pseudoHandle Handle, err error) {
907
+	r0, _, e1 := syscall.Syscall(procGetCurrentProcess.Addr(), 0, 0, 0, 0)
908
+	pseudoHandle = Handle(r0)
909
+	if pseudoHandle == 0 {
910
+		if e1 != 0 {
911
+			err = error(e1)
912
+		} else {
913
+			err = syscall.EINVAL
914
+		}
915
+	}
916
+	return
917
+}
918
+
919
+func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) {
920
+	r1, _, e1 := syscall.Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0)
921
+	if r1 == 0 {
922
+		if e1 != 0 {
923
+			err = error(e1)
924
+		} else {
925
+			err = syscall.EINVAL
926
+		}
927
+	}
928
+	return
929
+}
930
+
931
+func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) {
932
+	var _p0 uint32
933
+	if bInheritHandle {
934
+		_p0 = 1
935
+	} else {
936
+		_p0 = 0
937
+	}
938
+	r1, _, e1 := syscall.Syscall9(procDuplicateHandle.Addr(), 7, uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions), 0, 0)
939
+	if r1 == 0 {
940
+		if e1 != 0 {
941
+			err = error(e1)
942
+		} else {
943
+			err = syscall.EINVAL
944
+		}
945
+	}
946
+	return
947
+}
948
+
949
+func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) {
950
+	r0, _, e1 := syscall.Syscall(procWaitForSingleObject.Addr(), 2, uintptr(handle), uintptr(waitMilliseconds), 0)
951
+	event = uint32(r0)
952
+	if event == 0xffffffff {
953
+		if e1 != 0 {
954
+			err = error(e1)
955
+		} else {
956
+			err = syscall.EINVAL
957
+		}
958
+	}
959
+	return
960
+}
961
+
962
+func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) {
963
+	r0, _, e1 := syscall.Syscall(procGetTempPathW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
964
+	n = uint32(r0)
965
+	if n == 0 {
966
+		if e1 != 0 {
967
+			err = error(e1)
968
+		} else {
969
+			err = syscall.EINVAL
970
+		}
971
+	}
972
+	return
973
+}
974
+
975
+func CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) {
976
+	r1, _, e1 := syscall.Syscall6(procCreatePipe.Addr(), 4, uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size), 0, 0)
977
+	if r1 == 0 {
978
+		if e1 != 0 {
979
+			err = error(e1)
980
+		} else {
981
+			err = syscall.EINVAL
982
+		}
983
+	}
984
+	return
985
+}
986
+
987
+func GetFileType(filehandle Handle) (n uint32, err error) {
988
+	r0, _, e1 := syscall.Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0)
989
+	n = uint32(r0)
990
+	if n == 0 {
991
+		if e1 != 0 {
992
+			err = error(e1)
993
+		} else {
994
+			err = syscall.EINVAL
995
+		}
996
+	}
997
+	return
998
+}
999
+
1000
+func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) {
1001
+	r1, _, e1 := syscall.Syscall6(procCryptAcquireContextW.Addr(), 5, uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags), 0)
1002
+	if r1 == 0 {
1003
+		if e1 != 0 {
1004
+			err = error(e1)
1005
+		} else {
1006
+			err = syscall.EINVAL
1007
+		}
1008
+	}
1009
+	return
1010
+}
1011
+
1012
+func CryptReleaseContext(provhandle Handle, flags uint32) (err error) {
1013
+	r1, _, e1 := syscall.Syscall(procCryptReleaseContext.Addr(), 2, uintptr(provhandle), uintptr(flags), 0)
1014
+	if r1 == 0 {
1015
+		if e1 != 0 {
1016
+			err = error(e1)
1017
+		} else {
1018
+			err = syscall.EINVAL
1019
+		}
1020
+	}
1021
+	return
1022
+}
1023
+
1024
+func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) {
1025
+	r1, _, e1 := syscall.Syscall(procCryptGenRandom.Addr(), 3, uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf)))
1026
+	if r1 == 0 {
1027
+		if e1 != 0 {
1028
+			err = error(e1)
1029
+		} else {
1030
+			err = syscall.EINVAL
1031
+		}
1032
+	}
1033
+	return
1034
+}
1035
+
1036
+func GetEnvironmentStrings() (envs *uint16, err error) {
1037
+	r0, _, e1 := syscall.Syscall(procGetEnvironmentStringsW.Addr(), 0, 0, 0, 0)
1038
+	envs = (*uint16)(unsafe.Pointer(r0))
1039
+	if envs == nil {
1040
+		if e1 != 0 {
1041
+			err = error(e1)
1042
+		} else {
1043
+			err = syscall.EINVAL
1044
+		}
1045
+	}
1046
+	return
1047
+}
1048
+
1049
+func FreeEnvironmentStrings(envs *uint16) (err error) {
1050
+	r1, _, e1 := syscall.Syscall(procFreeEnvironmentStringsW.Addr(), 1, uintptr(unsafe.Pointer(envs)), 0, 0)
1051
+	if r1 == 0 {
1052
+		if e1 != 0 {
1053
+			err = error(e1)
1054
+		} else {
1055
+			err = syscall.EINVAL
1056
+		}
1057
+	}
1058
+	return
1059
+}
1060
+
1061
+func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) {
1062
+	r0, _, e1 := syscall.Syscall(procGetEnvironmentVariableW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size))
1063
+	n = uint32(r0)
1064
+	if n == 0 {
1065
+		if e1 != 0 {
1066
+			err = error(e1)
1067
+		} else {
1068
+			err = syscall.EINVAL
1069
+		}
1070
+	}
1071
+	return
1072
+}
1073
+
1074
+func SetEnvironmentVariable(name *uint16, value *uint16) (err error) {
1075
+	r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0)
1076
+	if r1 == 0 {
1077
+		if e1 != 0 {
1078
+			err = error(e1)
1079
+		} else {
1080
+			err = syscall.EINVAL
1081
+		}
1082
+	}
1083
+	return
1084
+}
1085
+
1086
+func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) {
1087
+	r1, _, e1 := syscall.Syscall6(procSetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0)
1088
+	if r1 == 0 {
1089
+		if e1 != 0 {
1090
+			err = error(e1)
1091
+		} else {
1092
+			err = syscall.EINVAL
1093
+		}
1094
+	}
1095
+	return
1096
+}
1097
+
1098
+func GetFileAttributes(name *uint16) (attrs uint32, err error) {
1099
+	r0, _, e1 := syscall.Syscall(procGetFileAttributesW.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
1100
+	attrs = uint32(r0)
1101
+	if attrs == INVALID_FILE_ATTRIBUTES {
1102
+		if e1 != 0 {
1103
+			err = error(e1)
1104
+		} else {
1105
+			err = syscall.EINVAL
1106
+		}
1107
+	}
1108
+	return
1109
+}
1110
+
1111
+func SetFileAttributes(name *uint16, attrs uint32) (err error) {
1112
+	r1, _, e1 := syscall.Syscall(procSetFileAttributesW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(attrs), 0)
1113
+	if r1 == 0 {
1114
+		if e1 != 0 {
1115
+			err = error(e1)
1116
+		} else {
1117
+			err = syscall.EINVAL
1118
+		}
1119
+	}
1120
+	return
1121
+}
1122
+
1123
+func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) {
1124
+	r1, _, e1 := syscall.Syscall(procGetFileAttributesExW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info)))
1125
+	if r1 == 0 {
1126
+		if e1 != 0 {
1127
+			err = error(e1)
1128
+		} else {
1129
+			err = syscall.EINVAL
1130
+		}
1131
+	}
1132
+	return
1133
+}
1134
+
1135
+func GetCommandLine() (cmd *uint16) {
1136
+	r0, _, _ := syscall.Syscall(procGetCommandLineW.Addr(), 0, 0, 0, 0)
1137
+	cmd = (*uint16)(unsafe.Pointer(r0))
1138
+	return
1139
+}
1140
+
1141
+func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) {
1142
+	r0, _, e1 := syscall.Syscall(procCommandLineToArgvW.Addr(), 2, uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc)), 0)
1143
+	argv = (*[8192]*[8192]uint16)(unsafe.Pointer(r0))
1144
+	if argv == nil {
1145
+		if e1 != 0 {
1146
+			err = error(e1)
1147
+		} else {
1148
+			err = syscall.EINVAL
1149
+		}
1150
+	}
1151
+	return
1152
+}
1153
+
1154
+func LocalFree(hmem Handle) (handle Handle, err error) {
1155
+	r0, _, e1 := syscall.Syscall(procLocalFree.Addr(), 1, uintptr(hmem), 0, 0)
1156
+	handle = Handle(r0)
1157
+	if handle != 0 {
1158
+		if e1 != 0 {
1159
+			err = error(e1)
1160
+		} else {
1161
+			err = syscall.EINVAL
1162
+		}
1163
+	}
1164
+	return
1165
+}
1166
+
1167
+func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) {
1168
+	r1, _, e1 := syscall.Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags))
1169
+	if r1 == 0 {
1170
+		if e1 != 0 {
1171
+			err = error(e1)
1172
+		} else {
1173
+			err = syscall.EINVAL
1174
+		}
1175
+	}
1176
+	return
1177
+}
1178
+
1179
+func FlushFileBuffers(handle Handle) (err error) {
1180
+	r1, _, e1 := syscall.Syscall(procFlushFileBuffers.Addr(), 1, uintptr(handle), 0, 0)
1181
+	if r1 == 0 {
1182
+		if e1 != 0 {
1183
+			err = error(e1)
1184
+		} else {
1185
+			err = syscall.EINVAL
1186
+		}
1187
+	}
1188
+	return
1189
+}
1190
+
1191
+func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) {
1192
+	r0, _, e1 := syscall.Syscall6(procGetFullPathNameW.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname)), 0, 0)
1193
+	n = uint32(r0)
1194
+	if n == 0 {
1195
+		if e1 != 0 {
1196
+			err = error(e1)
1197
+		} else {
1198
+			err = syscall.EINVAL
1199
+		}
1200
+	}
1201
+	return
1202
+}
1203
+
1204
+func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) {
1205
+	r0, _, e1 := syscall.Syscall(procGetLongPathNameW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen))
1206
+	n = uint32(r0)
1207
+	if n == 0 {
1208
+		if e1 != 0 {
1209
+			err = error(e1)
1210
+		} else {
1211
+			err = syscall.EINVAL
1212
+		}
1213
+	}
1214
+	return
1215
+}
1216
+
1217
+func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) {
1218
+	r0, _, e1 := syscall.Syscall(procGetShortPathNameW.Addr(), 3, uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen))
1219
+	n = uint32(r0)
1220
+	if n == 0 {
1221
+		if e1 != 0 {
1222
+			err = error(e1)
1223
+		} else {
1224
+			err = syscall.EINVAL
1225
+		}
1226
+	}
1227
+	return
1228
+}
1229
+
1230
+func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) {
1231
+	r0, _, e1 := syscall.Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name)))
1232
+	handle = Handle(r0)
1233
+	if handle == 0 {
1234
+		if e1 != 0 {
1235
+			err = error(e1)
1236
+		} else {
1237
+			err = syscall.EINVAL
1238
+		}
1239
+	}
1240
+	return
1241
+}
1242
+
1243
+func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) {
1244
+	r0, _, e1 := syscall.Syscall6(procMapViewOfFile.Addr(), 5, uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length), 0)
1245
+	addr = uintptr(r0)
1246
+	if addr == 0 {
1247
+		if e1 != 0 {
1248
+			err = error(e1)
1249
+		} else {
1250
+			err = syscall.EINVAL
1251
+		}
1252
+	}
1253
+	return
1254
+}
1255
+
1256
+func UnmapViewOfFile(addr uintptr) (err error) {
1257
+	r1, _, e1 := syscall.Syscall(procUnmapViewOfFile.Addr(), 1, uintptr(addr), 0, 0)
1258
+	if r1 == 0 {
1259
+		if e1 != 0 {
1260
+			err = error(e1)
1261
+		} else {
1262
+			err = syscall.EINVAL
1263
+		}
1264
+	}
1265
+	return
1266
+}
1267
+
1268
+func FlushViewOfFile(addr uintptr, length uintptr) (err error) {
1269
+	r1, _, e1 := syscall.Syscall(procFlushViewOfFile.Addr(), 2, uintptr(addr), uintptr(length), 0)
1270
+	if r1 == 0 {
1271
+		if e1 != 0 {
1272
+			err = error(e1)
1273
+		} else {
1274
+			err = syscall.EINVAL
1275
+		}
1276
+	}
1277
+	return
1278
+}
1279
+
1280
+func VirtualLock(addr uintptr, length uintptr) (err error) {
1281
+	r1, _, e1 := syscall.Syscall(procVirtualLock.Addr(), 2, uintptr(addr), uintptr(length), 0)
1282
+	if r1 == 0 {
1283
+		if e1 != 0 {
1284
+			err = error(e1)
1285
+		} else {
1286
+			err = syscall.EINVAL
1287
+		}
1288
+	}
1289
+	return
1290
+}
1291
+
1292
+func VirtualUnlock(addr uintptr, length uintptr) (err error) {
1293
+	r1, _, e1 := syscall.Syscall(procVirtualUnlock.Addr(), 2, uintptr(addr), uintptr(length), 0)
1294
+	if r1 == 0 {
1295
+		if e1 != 0 {
1296
+			err = error(e1)
1297
+		} else {
1298
+			err = syscall.EINVAL
1299
+		}
1300
+	}
1301
+	return
1302
+}
1303
+
1304
+func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) {
1305
+	r1, _, e1 := syscall.Syscall9(procTransmitFile.Addr(), 7, uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags), 0, 0)
1306
+	if r1 == 0 {
1307
+		if e1 != 0 {
1308
+			err = error(e1)
1309
+		} else {
1310
+			err = syscall.EINVAL
1311
+		}
1312
+	}
1313
+	return
1314
+}
1315
+
1316
+func ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) {
1317
+	var _p0 uint32
1318
+	if watchSubTree {
1319
+		_p0 = 1
1320
+	} else {
1321
+		_p0 = 0
1322
+	}
1323
+	r1, _, e1 := syscall.Syscall9(procReadDirectoryChangesW.Addr(), 8, uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine), 0)
1324
+	if r1 == 0 {
1325
+		if e1 != 0 {
1326
+			err = error(e1)
1327
+		} else {
1328
+			err = syscall.EINVAL
1329
+		}
1330
+	}
1331
+	return
1332
+}
1333
+
1334
+func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) {
1335
+	r0, _, e1 := syscall.Syscall(procCertOpenSystemStoreW.Addr(), 2, uintptr(hprov), uintptr(unsafe.Pointer(name)), 0)
1336
+	store = Handle(r0)
1337
+	if store == 0 {
1338
+		if e1 != 0 {
1339
+			err = error(e1)
1340
+		} else {
1341
+			err = syscall.EINVAL
1342
+		}
1343
+	}
1344
+	return
1345
+}
1346
+
1347
+func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) {
1348
+	r0, _, e1 := syscall.Syscall6(procCertOpenStore.Addr(), 5, uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para), 0)
1349
+	handle = Handle(r0)
1350
+	if handle == InvalidHandle {
1351
+		if e1 != 0 {
1352
+			err = error(e1)
1353
+		} else {
1354
+			err = syscall.EINVAL
1355
+		}
1356
+	}
1357
+	return
1358
+}
1359
+
1360
+func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) {
1361
+	r0, _, e1 := syscall.Syscall(procCertEnumCertificatesInStore.Addr(), 2, uintptr(store), uintptr(unsafe.Pointer(prevContext)), 0)
1362
+	context = (*CertContext)(unsafe.Pointer(r0))
1363
+	if context == nil {
1364
+		if e1 != 0 {
1365
+			err = error(e1)
1366
+		} else {
1367
+			err = syscall.EINVAL
1368
+		}
1369
+	}
1370
+	return
1371
+}
1372
+
1373
+func CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) {
1374
+	r1, _, e1 := syscall.Syscall6(procCertAddCertificateContextToStore.Addr(), 4, uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext)), 0, 0)
1375
+	if r1 == 0 {
1376
+		if e1 != 0 {
1377
+			err = error(e1)
1378
+		} else {
1379
+			err = syscall.EINVAL
1380
+		}
1381
+	}
1382
+	return
1383
+}
1384
+
1385
+func CertCloseStore(store Handle, flags uint32) (err error) {
1386
+	r1, _, e1 := syscall.Syscall(procCertCloseStore.Addr(), 2, uintptr(store), uintptr(flags), 0)
1387
+	if r1 == 0 {
1388
+		if e1 != 0 {
1389
+			err = error(e1)
1390
+		} else {
1391
+			err = syscall.EINVAL
1392
+		}
1393
+	}
1394
+	return
1395
+}
1396
+
1397
+func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) {
1398
+	r1, _, e1 := syscall.Syscall9(procCertGetCertificateChain.Addr(), 8, uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx)), 0)
1399
+	if r1 == 0 {
1400
+		if e1 != 0 {
1401
+			err = error(e1)
1402
+		} else {
1403
+			err = syscall.EINVAL
1404
+		}
1405
+	}
1406
+	return
1407
+}
1408
+
1409
+func CertFreeCertificateChain(ctx *CertChainContext) {
1410
+	syscall.Syscall(procCertFreeCertificateChain.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0)
1411
+	return
1412
+}
1413
+
1414
+func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) {
1415
+	r0, _, e1 := syscall.Syscall(procCertCreateCertificateContext.Addr(), 3, uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen))
1416
+	context = (*CertContext)(unsafe.Pointer(r0))
1417
+	if context == nil {
1418
+		if e1 != 0 {
1419
+			err = error(e1)
1420
+		} else {
1421
+			err = syscall.EINVAL
1422
+		}
1423
+	}
1424
+	return
1425
+}
1426
+
1427
+func CertFreeCertificateContext(ctx *CertContext) (err error) {
1428
+	r1, _, e1 := syscall.Syscall(procCertFreeCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0)
1429
+	if r1 == 0 {
1430
+		if e1 != 0 {
1431
+			err = error(e1)
1432
+		} else {
1433
+			err = syscall.EINVAL
1434
+		}
1435
+	}
1436
+	return
1437
+}
1438
+
1439
+func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) {
1440
+	r1, _, e1 := syscall.Syscall6(procCertVerifyCertificateChainPolicy.Addr(), 4, uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status)), 0, 0)
1441
+	if r1 == 0 {
1442
+		if e1 != 0 {
1443
+			err = error(e1)
1444
+		} else {
1445
+			err = syscall.EINVAL
1446
+		}
1447
+	}
1448
+	return
1449
+}
1450
+
1451
+func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) {
1452
+	r0, _, _ := syscall.Syscall6(procRegOpenKeyExW.Addr(), 5, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result)), 0)
1453
+	if r0 != 0 {
1454
+		regerrno = syscall.Errno(r0)
1455
+	}
1456
+	return
1457
+}
1458
+
1459
+func RegCloseKey(key Handle) (regerrno error) {
1460
+	r0, _, _ := syscall.Syscall(procRegCloseKey.Addr(), 1, uintptr(key), 0, 0)
1461
+	if r0 != 0 {
1462
+		regerrno = syscall.Errno(r0)
1463
+	}
1464
+	return
1465
+}
1466
+
1467
+func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) {
1468
+	r0, _, _ := syscall.Syscall12(procRegQueryInfoKeyW.Addr(), 12, uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime)))
1469
+	if r0 != 0 {
1470
+		regerrno = syscall.Errno(r0)
1471
+	}
1472
+	return
1473
+}
1474
+
1475
+func RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) {
1476
+	r0, _, _ := syscall.Syscall9(procRegEnumKeyExW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime)), 0)
1477
+	if r0 != 0 {
1478
+		regerrno = syscall.Errno(r0)
1479
+	}
1480
+	return
1481
+}
1482
+
1483
+func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) {
1484
+	r0, _, _ := syscall.Syscall6(procRegQueryValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen)))
1485
+	if r0 != 0 {
1486
+		regerrno = syscall.Errno(r0)
1487
+	}
1488
+	return
1489
+}
1490
+
1491
+func getCurrentProcessId() (pid uint32) {
1492
+	r0, _, _ := syscall.Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0)
1493
+	pid = uint32(r0)
1494
+	return
1495
+}
1496
+
1497
+func GetConsoleMode(console Handle, mode *uint32) (err error) {
1498
+	r1, _, e1 := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0)
1499
+	if r1 == 0 {
1500
+		if e1 != 0 {
1501
+			err = error(e1)
1502
+		} else {
1503
+			err = syscall.EINVAL
1504
+		}
1505
+	}
1506
+	return
1507
+}
1508
+
1509
+func WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) {
1510
+	r1, _, e1 := syscall.Syscall6(procWriteConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved)), 0)
1511
+	if r1 == 0 {
1512
+		if e1 != 0 {
1513
+			err = error(e1)
1514
+		} else {
1515
+			err = syscall.EINVAL
1516
+		}
1517
+	}
1518
+	return
1519
+}
1520
+
1521
+func ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) {
1522
+	r1, _, e1 := syscall.Syscall6(procReadConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl)), 0)
1523
+	if r1 == 0 {
1524
+		if e1 != 0 {
1525
+			err = error(e1)
1526
+		} else {
1527
+			err = syscall.EINVAL
1528
+		}
1529
+	}
1530
+	return
1531
+}
1532
+
1533
+func CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) {
1534
+	r0, _, e1 := syscall.Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processId), 0)
1535
+	handle = Handle(r0)
1536
+	if handle == InvalidHandle {
1537
+		if e1 != 0 {
1538
+			err = error(e1)
1539
+		} else {
1540
+			err = syscall.EINVAL
1541
+		}
1542
+	}
1543
+	return
1544
+}
1545
+
1546
+func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) {
1547
+	r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0)
1548
+	if r1 == 0 {
1549
+		if e1 != 0 {
1550
+			err = error(e1)
1551
+		} else {
1552
+			err = syscall.EINVAL
1553
+		}
1554
+	}
1555
+	return
1556
+}
1557
+
1558
+func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) {
1559
+	r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0)
1560
+	if r1 == 0 {
1561
+		if e1 != 0 {
1562
+			err = error(e1)
1563
+		} else {
1564
+			err = syscall.EINVAL
1565
+		}
1566
+	}
1567
+	return
1568
+}
1569
+
1570
+func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) {
1571
+	r1, _, e1 := syscall.Syscall9(procDeviceIoControl.Addr(), 8, uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped)), 0)
1572
+	if r1 == 0 {
1573
+		if e1 != 0 {
1574
+			err = error(e1)
1575
+		} else {
1576
+			err = syscall.EINVAL
1577
+		}
1578
+	}
1579
+	return
1580
+}
1581
+
1582
+func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) {
1583
+	r1, _, e1 := syscall.Syscall(procCreateSymbolicLinkW.Addr(), 3, uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags))
1584
+	if r1&0xff == 0 {
1585
+		if e1 != 0 {
1586
+			err = error(e1)
1587
+		} else {
1588
+			err = syscall.EINVAL
1589
+		}
1590
+	}
1591
+	return
1592
+}
1593
+
1594
+func CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) {
1595
+	r1, _, e1 := syscall.Syscall(procCreateHardLinkW.Addr(), 3, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(existingfilename)), uintptr(reserved))
1596
+	if r1&0xff == 0 {
1597
+		if e1 != 0 {
1598
+			err = error(e1)
1599
+		} else {
1600
+			err = syscall.EINVAL
1601
+		}
1602
+	}
1603
+	return
1604
+}
1605
+
1606
+func GetCurrentThreadId() (id uint32) {
1607
+	r0, _, _ := syscall.Syscall(procGetCurrentThreadId.Addr(), 0, 0, 0, 0)
1608
+	id = uint32(r0)
1609
+	return
1610
+}
1611
+
1612
+func CreateEvent(eventAttrs *syscall.SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle Handle, err error) {
1613
+	r0, _, e1 := syscall.Syscall6(procCreateEventW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(manualReset), uintptr(initialState), uintptr(unsafe.Pointer(name)), 0, 0)
1614
+	handle = Handle(r0)
1615
+	if handle == 0 {
1616
+		if e1 != 0 {
1617
+			err = error(e1)
1618
+		} else {
1619
+			err = syscall.EINVAL
1620
+		}
1621
+	}
1622
+	return
1623
+}
1624
+
1625
+func SetEvent(event Handle) (err error) {
1626
+	r1, _, e1 := syscall.Syscall(procSetEvent.Addr(), 1, uintptr(event), 0, 0)
1627
+	if r1 == 0 {
1628
+		if e1 != 0 {
1629
+			err = error(e1)
1630
+		} else {
1631
+			err = syscall.EINVAL
1632
+		}
1633
+	}
1634
+	return
1635
+}
1636
+
1637
+func WSAStartup(verreq uint32, data *WSAData) (sockerr error) {
1638
+	r0, _, _ := syscall.Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0)
1639
+	if r0 != 0 {
1640
+		sockerr = syscall.Errno(r0)
1641
+	}
1642
+	return
1643
+}
1644
+
1645
+func WSACleanup() (err error) {
1646
+	r1, _, e1 := syscall.Syscall(procWSACleanup.Addr(), 0, 0, 0, 0)
1647
+	if r1 == socket_error {
1648
+		if e1 != 0 {
1649
+			err = error(e1)
1650
+		} else {
1651
+			err = syscall.EINVAL
1652
+		}
1653
+	}
1654
+	return
1655
+}
1656
+
1657
+func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) {
1658
+	r1, _, e1 := syscall.Syscall9(procWSAIoctl.Addr(), 9, uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine))
1659
+	if r1 == socket_error {
1660
+		if e1 != 0 {
1661
+			err = error(e1)
1662
+		} else {
1663
+			err = syscall.EINVAL
1664
+		}
1665
+	}
1666
+	return
1667
+}
1668
+
1669
+func socket(af int32, typ int32, protocol int32) (handle Handle, err error) {
1670
+	r0, _, e1 := syscall.Syscall(procsocket.Addr(), 3, uintptr(af), uintptr(typ), uintptr(protocol))
1671
+	handle = Handle(r0)
1672
+	if handle == InvalidHandle {
1673
+		if e1 != 0 {
1674
+			err = error(e1)
1675
+		} else {
1676
+			err = syscall.EINVAL
1677
+		}
1678
+	}
1679
+	return
1680
+}
1681
+
1682
+func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) {
1683
+	r1, _, e1 := syscall.Syscall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen), 0)
1684
+	if r1 == socket_error {
1685
+		if e1 != 0 {
1686
+			err = error(e1)
1687
+		} else {
1688
+			err = syscall.EINVAL
1689
+		}
1690
+	}
1691
+	return
1692
+}
1693
+
1694
+func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) {
1695
+	r1, _, e1 := syscall.Syscall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen)), 0)
1696
+	if r1 == socket_error {
1697
+		if e1 != 0 {
1698
+			err = error(e1)
1699
+		} else {
1700
+			err = syscall.EINVAL
1701
+		}
1702
+	}
1703
+	return
1704
+}
1705
+
1706
+func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) {
1707
+	r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
1708
+	if r1 == socket_error {
1709
+		if e1 != 0 {
1710
+			err = error(e1)
1711
+		} else {
1712
+			err = syscall.EINVAL
1713
+		}
1714
+	}
1715
+	return
1716
+}
1717
+
1718
+func connect(s Handle, name unsafe.Pointer, namelen int32) (err error) {
1719
+	r1, _, e1 := syscall.Syscall(procconnect.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
1720
+	if r1 == socket_error {
1721
+		if e1 != 0 {
1722
+			err = error(e1)
1723
+		} else {
1724
+			err = syscall.EINVAL
1725
+		}
1726
+	}
1727
+	return
1728
+}
1729
+
1730
+func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) {
1731
+	r1, _, e1 := syscall.Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
1732
+	if r1 == socket_error {
1733
+		if e1 != 0 {
1734
+			err = error(e1)
1735
+		} else {
1736
+			err = syscall.EINVAL
1737
+		}
1738
+	}
1739
+	return
1740
+}
1741
+
1742
+func getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) {
1743
+	r1, _, e1 := syscall.Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
1744
+	if r1 == socket_error {
1745
+		if e1 != 0 {
1746
+			err = error(e1)
1747
+		} else {
1748
+			err = syscall.EINVAL
1749
+		}
1750
+	}
1751
+	return
1752
+}
1753
+
1754
+func listen(s Handle, backlog int32) (err error) {
1755
+	r1, _, e1 := syscall.Syscall(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0)
1756
+	if r1 == socket_error {
1757
+		if e1 != 0 {
1758
+			err = error(e1)
1759
+		} else {
1760
+			err = syscall.EINVAL
1761
+		}
1762
+	}
1763
+	return
1764
+}
1765
+
1766
+func shutdown(s Handle, how int32) (err error) {
1767
+	r1, _, e1 := syscall.Syscall(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0)
1768
+	if r1 == socket_error {
1769
+		if e1 != 0 {
1770
+			err = error(e1)
1771
+		} else {
1772
+			err = syscall.EINVAL
1773
+		}
1774
+	}
1775
+	return
1776
+}
1777
+
1778
+func Closesocket(s Handle) (err error) {
1779
+	r1, _, e1 := syscall.Syscall(procclosesocket.Addr(), 1, uintptr(s), 0, 0)
1780
+	if r1 == socket_error {
1781
+		if e1 != 0 {
1782
+			err = error(e1)
1783
+		} else {
1784
+			err = syscall.EINVAL
1785
+		}
1786
+	}
1787
+	return
1788
+}
1789
+
1790
+func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) {
1791
+	r1, _, e1 := syscall.Syscall9(procAcceptEx.Addr(), 8, uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped)), 0)
1792
+	if r1 == 0 {
1793
+		if e1 != 0 {
1794
+			err = error(e1)
1795
+		} else {
1796
+			err = syscall.EINVAL
1797
+		}
1798
+	}
1799
+	return
1800
+}
1801
+
1802
+func GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) {
1803
+	syscall.Syscall9(procGetAcceptExSockaddrs.Addr(), 8, uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen)), 0)
1804
+	return
1805
+}
1806
+
1807
+func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) {
1808
+	r1, _, e1 := syscall.Syscall9(procWSARecv.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0)
1809
+	if r1 == socket_error {
1810
+		if e1 != 0 {
1811
+			err = error(e1)
1812
+		} else {
1813
+			err = syscall.EINVAL
1814
+		}
1815
+	}
1816
+	return
1817
+}
1818
+
1819
+func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) {
1820
+	r1, _, e1 := syscall.Syscall9(procWSASend.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0)
1821
+	if r1 == socket_error {
1822
+		if e1 != 0 {
1823
+			err = error(e1)
1824
+		} else {
1825
+			err = syscall.EINVAL
1826
+		}
1827
+	}
1828
+	return
1829
+}
1830
+
1831
+func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) {
1832
+	r1, _, e1 := syscall.Syscall9(procWSARecvFrom.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
1833
+	if r1 == socket_error {
1834
+		if e1 != 0 {
1835
+			err = error(e1)
1836
+		} else {
1837
+			err = syscall.EINVAL
1838
+		}
1839
+	}
1840
+	return
1841
+}
1842
+
1843
+func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) {
1844
+	r1, _, e1 := syscall.Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
1845
+	if r1 == socket_error {
1846
+		if e1 != 0 {
1847
+			err = error(e1)
1848
+		} else {
1849
+			err = syscall.EINVAL
1850
+		}
1851
+	}
1852
+	return
1853
+}
1854
+
1855
+func GetHostByName(name string) (h *Hostent, err error) {
1856
+	var _p0 *byte
1857
+	_p0, err = syscall.BytePtrFromString(name)
1858
+	if err != nil {
1859
+		return
1860
+	}
1861
+	return _GetHostByName(_p0)
1862
+}
1863
+
1864
+func _GetHostByName(name *byte) (h *Hostent, err error) {
1865
+	r0, _, e1 := syscall.Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
1866
+	h = (*Hostent)(unsafe.Pointer(r0))
1867
+	if h == nil {
1868
+		if e1 != 0 {
1869
+			err = error(e1)
1870
+		} else {
1871
+			err = syscall.EINVAL
1872
+		}
1873
+	}
1874
+	return
1875
+}
1876
+
1877
+func GetServByName(name string, proto string) (s *Servent, err error) {
1878
+	var _p0 *byte
1879
+	_p0, err = syscall.BytePtrFromString(name)
1880
+	if err != nil {
1881
+		return
1882
+	}
1883
+	var _p1 *byte
1884
+	_p1, err = syscall.BytePtrFromString(proto)
1885
+	if err != nil {
1886
+		return
1887
+	}
1888
+	return _GetServByName(_p0, _p1)
1889
+}
1890
+
1891
+func _GetServByName(name *byte, proto *byte) (s *Servent, err error) {
1892
+	r0, _, e1 := syscall.Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto)), 0)
1893
+	s = (*Servent)(unsafe.Pointer(r0))
1894
+	if s == nil {
1895
+		if e1 != 0 {
1896
+			err = error(e1)
1897
+		} else {
1898
+			err = syscall.EINVAL
1899
+		}
1900
+	}
1901
+	return
1902
+}
1903
+
1904
+func Ntohs(netshort uint16) (u uint16) {
1905
+	r0, _, _ := syscall.Syscall(procntohs.Addr(), 1, uintptr(netshort), 0, 0)
1906
+	u = uint16(r0)
1907
+	return
1908
+}
1909
+
1910
+func GetProtoByName(name string) (p *Protoent, err error) {
1911
+	var _p0 *byte
1912
+	_p0, err = syscall.BytePtrFromString(name)
1913
+	if err != nil {
1914
+		return
1915
+	}
1916
+	return _GetProtoByName(_p0)
1917
+}
1918
+
1919
+func _GetProtoByName(name *byte) (p *Protoent, err error) {
1920
+	r0, _, e1 := syscall.Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
1921
+	p = (*Protoent)(unsafe.Pointer(r0))
1922
+	if p == nil {
1923
+		if e1 != 0 {
1924
+			err = error(e1)
1925
+		} else {
1926
+			err = syscall.EINVAL
1927
+		}
1928
+	}
1929
+	return
1930
+}
1931
+
1932
+func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) {
1933
+	var _p0 *uint16
1934
+	_p0, status = syscall.UTF16PtrFromString(name)
1935
+	if status != nil {
1936
+		return
1937
+	}
1938
+	return _DnsQuery(_p0, qtype, options, extra, qrs, pr)
1939
+}
1940
+
1941
+func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) {
1942
+	r0, _, _ := syscall.Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr)))
1943
+	if r0 != 0 {
1944
+		status = syscall.Errno(r0)
1945
+	}
1946
+	return
1947
+}
1948
+
1949
+func DnsRecordListFree(rl *DNSRecord, freetype uint32) {
1950
+	syscall.Syscall(procDnsRecordListFree.Addr(), 2, uintptr(unsafe.Pointer(rl)), uintptr(freetype), 0)
1951
+	return
1952
+}
1953
+
1954
+func DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) {
1955
+	r0, _, _ := syscall.Syscall(procDnsNameCompare_W.Addr(), 2, uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2)), 0)
1956
+	same = r0 != 0
1957
+	return
1958
+}
1959
+
1960
+func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) {
1961
+	r0, _, _ := syscall.Syscall6(procGetAddrInfoW.Addr(), 4, uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result)), 0, 0)
1962
+	if r0 != 0 {
1963
+		sockerr = syscall.Errno(r0)
1964
+	}
1965
+	return
1966
+}
1967
+
1968
+func FreeAddrInfoW(addrinfo *AddrinfoW) {
1969
+	syscall.Syscall(procFreeAddrInfoW.Addr(), 1, uintptr(unsafe.Pointer(addrinfo)), 0, 0)
1970
+	return
1971
+}
1972
+
1973
+func GetIfEntry(pIfRow *MibIfRow) (errcode error) {
1974
+	r0, _, _ := syscall.Syscall(procGetIfEntry.Addr(), 1, uintptr(unsafe.Pointer(pIfRow)), 0, 0)
1975
+	if r0 != 0 {
1976
+		errcode = syscall.Errno(r0)
1977
+	}
1978
+	return
1979
+}
1980
+
1981
+func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) {
1982
+	r0, _, _ := syscall.Syscall(procGetAdaptersInfo.Addr(), 2, uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol)), 0)
1983
+	if r0 != 0 {
1984
+		errcode = syscall.Errno(r0)
1985
+	}
1986
+	return
1987
+}
1988
+
1989
+func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) {
1990
+	r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(handle), uintptr(flags), 0)
1991
+	if r1 == 0 {
1992
+		if e1 != 0 {
1993
+			err = error(e1)
1994
+		} else {
1995
+			err = syscall.EINVAL
1996
+		}
1997
+	}
1998
+	return
1999
+}
2000
+
2001
+func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) {
2002
+	r0, _, e1 := syscall.Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength)))
2003
+	n = int32(r0)
2004
+	if n == -1 {
2005
+		if e1 != 0 {
2006
+			err = error(e1)
2007
+		} else {
2008
+			err = syscall.EINVAL
2009
+		}
2010
+	}
2011
+	return
2012
+}
2013
+
2014
+func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) {
2015
+	r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0)
2016
+	if r0 != 0 {
2017
+		errcode = syscall.Errno(r0)
2018
+	}
2019
+	return
2020
+}
2021
+
2022
+func GetACP() (acp uint32) {
2023
+	r0, _, _ := syscall.Syscall(procGetACP.Addr(), 0, 0, 0, 0)
2024
+	acp = uint32(r0)
2025
+	return
2026
+}
2027
+
2028
+func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) {
2029
+	r0, _, e1 := syscall.Syscall6(procMultiByteToWideChar.Addr(), 6, uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar))
2030
+	nwrite = int32(r0)
2031
+	if nwrite == 0 {
2032
+		if e1 != 0 {
2033
+			err = error(e1)
2034
+		} else {
2035
+			err = syscall.EINVAL
2036
+		}
2037
+	}
2038
+	return
2039
+}
2040
+
2041
+func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) {
2042
+	r1, _, e1 := syscall.Syscall6(procTranslateNameW.Addr(), 5, uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize)), 0)
2043
+	if r1&0xff == 0 {
2044
+		if e1 != 0 {
2045
+			err = error(e1)
2046
+		} else {
2047
+			err = syscall.EINVAL
2048
+		}
2049
+	}
2050
+	return
2051
+}
2052
+
2053
+func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) {
2054
+	r1, _, e1 := syscall.Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize)))
2055
+	if r1&0xff == 0 {
2056
+		if e1 != 0 {
2057
+			err = error(e1)
2058
+		} else {
2059
+			err = syscall.EINVAL
2060
+		}
2061
+	}
2062
+	return
2063
+}
2064
+
2065
+func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) {
2066
+	r0, _, _ := syscall.Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0)
2067
+	if r0 != 0 {
2068
+		neterr = syscall.Errno(r0)
2069
+	}
2070
+	return
2071
+}
2072
+
2073
+func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) {
2074
+	r0, _, _ := syscall.Syscall(procNetGetJoinInformation.Addr(), 3, uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType)))
2075
+	if r0 != 0 {
2076
+		neterr = syscall.Errno(r0)
2077
+	}
2078
+	return
2079
+}
2080
+
2081
+func NetApiBufferFree(buf *byte) (neterr error) {
2082
+	r0, _, _ := syscall.Syscall(procNetApiBufferFree.Addr(), 1, uintptr(unsafe.Pointer(buf)), 0, 0)
2083
+	if r0 != 0 {
2084
+		neterr = syscall.Errno(r0)
2085
+	}
2086
+	return
2087
+}
2088
+
2089
+func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) {
2090
+	r1, _, e1 := syscall.Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0)
2091
+	if r1 == 0 {
2092
+		if e1 != 0 {
2093
+			err = error(e1)
2094
+		} else {
2095
+			err = syscall.EINVAL
2096
+		}
2097
+	}
2098
+	return
2099
+}
2100
+
2101
+func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) {
2102
+	r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0)
2103
+	if r1 == 0 {
2104
+		if e1 != 0 {
2105
+			err = error(e1)
2106
+		} else {
2107
+			err = syscall.EINVAL
2108
+		}
2109
+	}
2110
+	return
2111
+}
2112
+
2113
+func ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) {
2114
+	r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid)), 0)
2115
+	if r1 == 0 {
2116
+		if e1 != 0 {
2117
+			err = error(e1)
2118
+		} else {
2119
+			err = syscall.EINVAL
2120
+		}
2121
+	}
2122
+	return
2123
+}
2124
+
2125
+func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) {
2126
+	r1, _, e1 := syscall.Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid)), 0)
2127
+	if r1 == 0 {
2128
+		if e1 != 0 {
2129
+			err = error(e1)
2130
+		} else {
2131
+			err = syscall.EINVAL
2132
+		}
2133
+	}
2134
+	return
2135
+}
2136
+
2137
+func GetLengthSid(sid *SID) (len uint32) {
2138
+	r0, _, _ := syscall.Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
2139
+	len = uint32(r0)
2140
+	return
2141
+}
2142
+
2143
+func CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) {
2144
+	r1, _, e1 := syscall.Syscall(procCopySid.Addr(), 3, uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid)))
2145
+	if r1 == 0 {
2146
+		if e1 != 0 {
2147
+			err = error(e1)
2148
+		} else {
2149
+			err = syscall.EINVAL
2150
+		}
2151
+	}
2152
+	return
2153
+}
2154
+
2155
+func AllocateAndInitializeSid(identAuth *SidIdentifierAuthority, subAuth byte, subAuth0 uint32, subAuth1 uint32, subAuth2 uint32, subAuth3 uint32, subAuth4 uint32, subAuth5 uint32, subAuth6 uint32, subAuth7 uint32, sid **SID) (err error) {
2156
+	r1, _, e1 := syscall.Syscall12(procAllocateAndInitializeSid.Addr(), 11, uintptr(unsafe.Pointer(identAuth)), uintptr(subAuth), uintptr(subAuth0), uintptr(subAuth1), uintptr(subAuth2), uintptr(subAuth3), uintptr(subAuth4), uintptr(subAuth5), uintptr(subAuth6), uintptr(subAuth7), uintptr(unsafe.Pointer(sid)), 0)
2157
+	if r1 == 0 {
2158
+		if e1 != 0 {
2159
+			err = error(e1)
2160
+		} else {
2161
+			err = syscall.EINVAL
2162
+		}
2163
+	}
2164
+	return
2165
+}
2166
+
2167
+func FreeSid(sid *SID) (err error) {
2168
+	r1, _, e1 := syscall.Syscall(procFreeSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
2169
+	if r1 != 0 {
2170
+		if e1 != 0 {
2171
+			err = error(e1)
2172
+		} else {
2173
+			err = syscall.EINVAL
2174
+		}
2175
+	}
2176
+	return
2177
+}
2178
+
2179
+func EqualSid(sid1 *SID, sid2 *SID) (isEqual bool) {
2180
+	r0, _, _ := syscall.Syscall(procEqualSid.Addr(), 2, uintptr(unsafe.Pointer(sid1)), uintptr(unsafe.Pointer(sid2)), 0)
2181
+	isEqual = r0 != 0
2182
+	return
2183
+}
2184
+
2185
+func OpenProcessToken(h Handle, access uint32, token *Token) (err error) {
2186
+	r1, _, e1 := syscall.Syscall(procOpenProcessToken.Addr(), 3, uintptr(h), uintptr(access), uintptr(unsafe.Pointer(token)))
2187
+	if r1 == 0 {
2188
+		if e1 != 0 {
2189
+			err = error(e1)
2190
+		} else {
2191
+			err = syscall.EINVAL
2192
+		}
2193
+	}
2194
+	return
2195
+}
2196
+
2197
+func GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) {
2198
+	r1, _, e1 := syscall.Syscall6(procGetTokenInformation.Addr(), 5, uintptr(t), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen)), 0)
2199
+	if r1 == 0 {
2200
+		if e1 != 0 {
2201
+			err = error(e1)
2202
+		} else {
2203
+			err = syscall.EINVAL
2204
+		}
2205
+	}
2206
+	return
2207
+}
2208
+
2209
+func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) {
2210
+	r1, _, e1 := syscall.Syscall(procGetUserProfileDirectoryW.Addr(), 3, uintptr(t), uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen)))
2211
+	if r1 == 0 {
2212
+		if e1 != 0 {
2213
+			err = error(e1)
2214
+		} else {
2215
+			err = syscall.EINVAL
2216
+		}
2217
+	}
2218
+	return
2219
+}
0 2220
new file mode 100644
... ...
@@ -0,0 +1,1242 @@
0
+// Copyright 2011 The Go Authors.  All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+package windows
5
+
6
+import "syscall"
7
+
8
+const (
9
+	// Windows errors.
10
+	ERROR_FILE_NOT_FOUND         syscall.Errno = 2
11
+	ERROR_PATH_NOT_FOUND         syscall.Errno = 3
12
+	ERROR_ACCESS_DENIED          syscall.Errno = 5
13
+	ERROR_NO_MORE_FILES          syscall.Errno = 18
14
+	ERROR_HANDLE_EOF             syscall.Errno = 38
15
+	ERROR_NETNAME_DELETED        syscall.Errno = 64
16
+	ERROR_FILE_EXISTS            syscall.Errno = 80
17
+	ERROR_BROKEN_PIPE            syscall.Errno = 109
18
+	ERROR_BUFFER_OVERFLOW        syscall.Errno = 111
19
+	ERROR_INSUFFICIENT_BUFFER    syscall.Errno = 122
20
+	ERROR_MOD_NOT_FOUND          syscall.Errno = 126
21
+	ERROR_PROC_NOT_FOUND         syscall.Errno = 127
22
+	ERROR_ALREADY_EXISTS         syscall.Errno = 183
23
+	ERROR_ENVVAR_NOT_FOUND       syscall.Errno = 203
24
+	ERROR_MORE_DATA              syscall.Errno = 234
25
+	ERROR_OPERATION_ABORTED      syscall.Errno = 995
26
+	ERROR_IO_PENDING             syscall.Errno = 997
27
+	ERROR_SERVICE_SPECIFIC_ERROR syscall.Errno = 1066
28
+	ERROR_NOT_FOUND              syscall.Errno = 1168
29
+	ERROR_PRIVILEGE_NOT_HELD     syscall.Errno = 1314
30
+	WSAEACCES                    syscall.Errno = 10013
31
+	WSAECONNRESET                syscall.Errno = 10054
32
+)
33
+
34
+const (
35
+	// Invented values to support what package os expects.
36
+	O_RDONLY   = 0x00000
37
+	O_WRONLY   = 0x00001
38
+	O_RDWR     = 0x00002
39
+	O_CREAT    = 0x00040
40
+	O_EXCL     = 0x00080
41
+	O_NOCTTY   = 0x00100
42
+	O_TRUNC    = 0x00200
43
+	O_NONBLOCK = 0x00800
44
+	O_APPEND   = 0x00400
45
+	O_SYNC     = 0x01000
46
+	O_ASYNC    = 0x02000
47
+	O_CLOEXEC  = 0x80000
48
+)
49
+
50
+const (
51
+	// More invented values for signals
52
+	SIGHUP  = Signal(0x1)
53
+	SIGINT  = Signal(0x2)
54
+	SIGQUIT = Signal(0x3)
55
+	SIGILL  = Signal(0x4)
56
+	SIGTRAP = Signal(0x5)
57
+	SIGABRT = Signal(0x6)
58
+	SIGBUS  = Signal(0x7)
59
+	SIGFPE  = Signal(0x8)
60
+	SIGKILL = Signal(0x9)
61
+	SIGSEGV = Signal(0xb)
62
+	SIGPIPE = Signal(0xd)
63
+	SIGALRM = Signal(0xe)
64
+	SIGTERM = Signal(0xf)
65
+)
66
+
67
+var signals = [...]string{
68
+	1:  "hangup",
69
+	2:  "interrupt",
70
+	3:  "quit",
71
+	4:  "illegal instruction",
72
+	5:  "trace/breakpoint trap",
73
+	6:  "aborted",
74
+	7:  "bus error",
75
+	8:  "floating point exception",
76
+	9:  "killed",
77
+	10: "user defined signal 1",
78
+	11: "segmentation fault",
79
+	12: "user defined signal 2",
80
+	13: "broken pipe",
81
+	14: "alarm clock",
82
+	15: "terminated",
83
+}
84
+
85
+const (
86
+	GENERIC_READ    = 0x80000000
87
+	GENERIC_WRITE   = 0x40000000
88
+	GENERIC_EXECUTE = 0x20000000
89
+	GENERIC_ALL     = 0x10000000
90
+
91
+	FILE_LIST_DIRECTORY   = 0x00000001
92
+	FILE_APPEND_DATA      = 0x00000004
93
+	FILE_WRITE_ATTRIBUTES = 0x00000100
94
+
95
+	FILE_SHARE_READ              = 0x00000001
96
+	FILE_SHARE_WRITE             = 0x00000002
97
+	FILE_SHARE_DELETE            = 0x00000004
98
+	FILE_ATTRIBUTE_READONLY      = 0x00000001
99
+	FILE_ATTRIBUTE_HIDDEN        = 0x00000002
100
+	FILE_ATTRIBUTE_SYSTEM        = 0x00000004
101
+	FILE_ATTRIBUTE_DIRECTORY     = 0x00000010
102
+	FILE_ATTRIBUTE_ARCHIVE       = 0x00000020
103
+	FILE_ATTRIBUTE_NORMAL        = 0x00000080
104
+	FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400
105
+
106
+	INVALID_FILE_ATTRIBUTES = 0xffffffff
107
+
108
+	CREATE_NEW        = 1
109
+	CREATE_ALWAYS     = 2
110
+	OPEN_EXISTING     = 3
111
+	OPEN_ALWAYS       = 4
112
+	TRUNCATE_EXISTING = 5
113
+
114
+	FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000
115
+	FILE_FLAG_BACKUP_SEMANTICS   = 0x02000000
116
+	FILE_FLAG_OVERLAPPED         = 0x40000000
117
+
118
+	HANDLE_FLAG_INHERIT    = 0x00000001
119
+	STARTF_USESTDHANDLES   = 0x00000100
120
+	STARTF_USESHOWWINDOW   = 0x00000001
121
+	DUPLICATE_CLOSE_SOURCE = 0x00000001
122
+	DUPLICATE_SAME_ACCESS  = 0x00000002
123
+
124
+	STD_INPUT_HANDLE  = -10
125
+	STD_OUTPUT_HANDLE = -11
126
+	STD_ERROR_HANDLE  = -12
127
+
128
+	FILE_BEGIN   = 0
129
+	FILE_CURRENT = 1
130
+	FILE_END     = 2
131
+
132
+	LANG_ENGLISH       = 0x09
133
+	SUBLANG_ENGLISH_US = 0x01
134
+
135
+	FORMAT_MESSAGE_ALLOCATE_BUFFER = 256
136
+	FORMAT_MESSAGE_IGNORE_INSERTS  = 512
137
+	FORMAT_MESSAGE_FROM_STRING     = 1024
138
+	FORMAT_MESSAGE_FROM_HMODULE    = 2048
139
+	FORMAT_MESSAGE_FROM_SYSTEM     = 4096
140
+	FORMAT_MESSAGE_ARGUMENT_ARRAY  = 8192
141
+	FORMAT_MESSAGE_MAX_WIDTH_MASK  = 255
142
+
143
+	MAX_PATH      = 260
144
+	MAX_LONG_PATH = 32768
145
+
146
+	MAX_COMPUTERNAME_LENGTH = 15
147
+
148
+	TIME_ZONE_ID_UNKNOWN  = 0
149
+	TIME_ZONE_ID_STANDARD = 1
150
+
151
+	TIME_ZONE_ID_DAYLIGHT = 2
152
+	IGNORE                = 0
153
+	INFINITE              = 0xffffffff
154
+
155
+	WAIT_TIMEOUT   = 258
156
+	WAIT_ABANDONED = 0x00000080
157
+	WAIT_OBJECT_0  = 0x00000000
158
+	WAIT_FAILED    = 0xFFFFFFFF
159
+
160
+	CREATE_NEW_PROCESS_GROUP   = 0x00000200
161
+	CREATE_UNICODE_ENVIRONMENT = 0x00000400
162
+
163
+	PROCESS_TERMINATE         = 1
164
+	PROCESS_QUERY_INFORMATION = 0x00000400
165
+	SYNCHRONIZE               = 0x00100000
166
+
167
+	PAGE_READONLY          = 0x02
168
+	PAGE_READWRITE         = 0x04
169
+	PAGE_WRITECOPY         = 0x08
170
+	PAGE_EXECUTE_READ      = 0x20
171
+	PAGE_EXECUTE_READWRITE = 0x40
172
+	PAGE_EXECUTE_WRITECOPY = 0x80
173
+
174
+	FILE_MAP_COPY    = 0x01
175
+	FILE_MAP_WRITE   = 0x02
176
+	FILE_MAP_READ    = 0x04
177
+	FILE_MAP_EXECUTE = 0x20
178
+
179
+	CTRL_C_EVENT     = 0
180
+	CTRL_BREAK_EVENT = 1
181
+
182
+	// Windows reserves errors >= 1<<29 for application use.
183
+	APPLICATION_ERROR = 1 << 29
184
+)
185
+
186
+const (
187
+	// flags for CreateToolhelp32Snapshot
188
+	TH32CS_SNAPHEAPLIST = 0x01
189
+	TH32CS_SNAPPROCESS  = 0x02
190
+	TH32CS_SNAPTHREAD   = 0x04
191
+	TH32CS_SNAPMODULE   = 0x08
192
+	TH32CS_SNAPMODULE32 = 0x10
193
+	TH32CS_SNAPALL      = TH32CS_SNAPHEAPLIST | TH32CS_SNAPMODULE | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD
194
+	TH32CS_INHERIT      = 0x80000000
195
+)
196
+
197
+const (
198
+	// filters for ReadDirectoryChangesW
199
+	FILE_NOTIFY_CHANGE_FILE_NAME   = 0x001
200
+	FILE_NOTIFY_CHANGE_DIR_NAME    = 0x002
201
+	FILE_NOTIFY_CHANGE_ATTRIBUTES  = 0x004
202
+	FILE_NOTIFY_CHANGE_SIZE        = 0x008
203
+	FILE_NOTIFY_CHANGE_LAST_WRITE  = 0x010
204
+	FILE_NOTIFY_CHANGE_LAST_ACCESS = 0x020
205
+	FILE_NOTIFY_CHANGE_CREATION    = 0x040
206
+	FILE_NOTIFY_CHANGE_SECURITY    = 0x100
207
+)
208
+
209
+const (
210
+	// do not reorder
211
+	FILE_ACTION_ADDED = iota + 1
212
+	FILE_ACTION_REMOVED
213
+	FILE_ACTION_MODIFIED
214
+	FILE_ACTION_RENAMED_OLD_NAME
215
+	FILE_ACTION_RENAMED_NEW_NAME
216
+)
217
+
218
+const (
219
+	// wincrypt.h
220
+	PROV_RSA_FULL                    = 1
221
+	PROV_RSA_SIG                     = 2
222
+	PROV_DSS                         = 3
223
+	PROV_FORTEZZA                    = 4
224
+	PROV_MS_EXCHANGE                 = 5
225
+	PROV_SSL                         = 6
226
+	PROV_RSA_SCHANNEL                = 12
227
+	PROV_DSS_DH                      = 13
228
+	PROV_EC_ECDSA_SIG                = 14
229
+	PROV_EC_ECNRA_SIG                = 15
230
+	PROV_EC_ECDSA_FULL               = 16
231
+	PROV_EC_ECNRA_FULL               = 17
232
+	PROV_DH_SCHANNEL                 = 18
233
+	PROV_SPYRUS_LYNKS                = 20
234
+	PROV_RNG                         = 21
235
+	PROV_INTEL_SEC                   = 22
236
+	PROV_REPLACE_OWF                 = 23
237
+	PROV_RSA_AES                     = 24
238
+	CRYPT_VERIFYCONTEXT              = 0xF0000000
239
+	CRYPT_NEWKEYSET                  = 0x00000008
240
+	CRYPT_DELETEKEYSET               = 0x00000010
241
+	CRYPT_MACHINE_KEYSET             = 0x00000020
242
+	CRYPT_SILENT                     = 0x00000040
243
+	CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x00000080
244
+
245
+	USAGE_MATCH_TYPE_AND = 0
246
+	USAGE_MATCH_TYPE_OR  = 1
247
+
248
+	X509_ASN_ENCODING   = 0x00000001
249
+	PKCS_7_ASN_ENCODING = 0x00010000
250
+
251
+	CERT_STORE_PROV_MEMORY = 2
252
+
253
+	CERT_STORE_ADD_ALWAYS = 4
254
+
255
+	CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG = 0x00000004
256
+
257
+	CERT_TRUST_NO_ERROR                          = 0x00000000
258
+	CERT_TRUST_IS_NOT_TIME_VALID                 = 0x00000001
259
+	CERT_TRUST_IS_REVOKED                        = 0x00000004
260
+	CERT_TRUST_IS_NOT_SIGNATURE_VALID            = 0x00000008
261
+	CERT_TRUST_IS_NOT_VALID_FOR_USAGE            = 0x00000010
262
+	CERT_TRUST_IS_UNTRUSTED_ROOT                 = 0x00000020
263
+	CERT_TRUST_REVOCATION_STATUS_UNKNOWN         = 0x00000040
264
+	CERT_TRUST_IS_CYCLIC                         = 0x00000080
265
+	CERT_TRUST_INVALID_EXTENSION                 = 0x00000100
266
+	CERT_TRUST_INVALID_POLICY_CONSTRAINTS        = 0x00000200
267
+	CERT_TRUST_INVALID_BASIC_CONSTRAINTS         = 0x00000400
268
+	CERT_TRUST_INVALID_NAME_CONSTRAINTS          = 0x00000800
269
+	CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT = 0x00001000
270
+	CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT   = 0x00002000
271
+	CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT = 0x00004000
272
+	CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT      = 0x00008000
273
+	CERT_TRUST_IS_OFFLINE_REVOCATION             = 0x01000000
274
+	CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY          = 0x02000000
275
+	CERT_TRUST_IS_EXPLICIT_DISTRUST              = 0x04000000
276
+	CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT    = 0x08000000
277
+
278
+	CERT_CHAIN_POLICY_BASE              = 1
279
+	CERT_CHAIN_POLICY_AUTHENTICODE      = 2
280
+	CERT_CHAIN_POLICY_AUTHENTICODE_TS   = 3
281
+	CERT_CHAIN_POLICY_SSL               = 4
282
+	CERT_CHAIN_POLICY_BASIC_CONSTRAINTS = 5
283
+	CERT_CHAIN_POLICY_NT_AUTH           = 6
284
+	CERT_CHAIN_POLICY_MICROSOFT_ROOT    = 7
285
+	CERT_CHAIN_POLICY_EV                = 8
286
+
287
+	CERT_E_EXPIRED       = 0x800B0101
288
+	CERT_E_ROLE          = 0x800B0103
289
+	CERT_E_PURPOSE       = 0x800B0106
290
+	CERT_E_UNTRUSTEDROOT = 0x800B0109
291
+	CERT_E_CN_NO_MATCH   = 0x800B010F
292
+
293
+	AUTHTYPE_CLIENT = 1
294
+	AUTHTYPE_SERVER = 2
295
+)
296
+
297
+var (
298
+	OID_PKIX_KP_SERVER_AUTH = []byte("1.3.6.1.5.5.7.3.1\x00")
299
+	OID_SERVER_GATED_CRYPTO = []byte("1.3.6.1.4.1.311.10.3.3\x00")
300
+	OID_SGC_NETSCAPE        = []byte("2.16.840.1.113730.4.1\x00")
301
+)
302
+
303
+// Invented values to support what package os expects.
304
+type Timeval struct {
305
+	Sec  int32
306
+	Usec int32
307
+}
308
+
309
+func (tv *Timeval) Nanoseconds() int64 {
310
+	return (int64(tv.Sec)*1e6 + int64(tv.Usec)) * 1e3
311
+}
312
+
313
+func NsecToTimeval(nsec int64) (tv Timeval) {
314
+	tv.Sec = int32(nsec / 1e9)
315
+	tv.Usec = int32(nsec % 1e9 / 1e3)
316
+	return
317
+}
318
+
319
+type SecurityAttributes struct {
320
+	Length             uint32
321
+	SecurityDescriptor uintptr
322
+	InheritHandle      uint32
323
+}
324
+
325
+type Overlapped struct {
326
+	Internal     uintptr
327
+	InternalHigh uintptr
328
+	Offset       uint32
329
+	OffsetHigh   uint32
330
+	HEvent       Handle
331
+}
332
+
333
+type FileNotifyInformation struct {
334
+	NextEntryOffset uint32
335
+	Action          uint32
336
+	FileNameLength  uint32
337
+	FileName        uint16
338
+}
339
+
340
+type Filetime struct {
341
+	LowDateTime  uint32
342
+	HighDateTime uint32
343
+}
344
+
345
+// Nanoseconds returns Filetime ft in nanoseconds
346
+// since Epoch (00:00:00 UTC, January 1, 1970).
347
+func (ft *Filetime) Nanoseconds() int64 {
348
+	// 100-nanosecond intervals since January 1, 1601
349
+	nsec := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime)
350
+	// change starting time to the Epoch (00:00:00 UTC, January 1, 1970)
351
+	nsec -= 116444736000000000
352
+	// convert into nanoseconds
353
+	nsec *= 100
354
+	return nsec
355
+}
356
+
357
+func NsecToFiletime(nsec int64) (ft Filetime) {
358
+	// convert into 100-nanosecond
359
+	nsec /= 100
360
+	// change starting time to January 1, 1601
361
+	nsec += 116444736000000000
362
+	// split into high / low
363
+	ft.LowDateTime = uint32(nsec & 0xffffffff)
364
+	ft.HighDateTime = uint32(nsec >> 32 & 0xffffffff)
365
+	return ft
366
+}
367
+
368
+type Win32finddata struct {
369
+	FileAttributes    uint32
370
+	CreationTime      Filetime
371
+	LastAccessTime    Filetime
372
+	LastWriteTime     Filetime
373
+	FileSizeHigh      uint32
374
+	FileSizeLow       uint32
375
+	Reserved0         uint32
376
+	Reserved1         uint32
377
+	FileName          [MAX_PATH - 1]uint16
378
+	AlternateFileName [13]uint16
379
+}
380
+
381
+// This is the actual system call structure.
382
+// Win32finddata is what we committed to in Go 1.
383
+type win32finddata1 struct {
384
+	FileAttributes    uint32
385
+	CreationTime      Filetime
386
+	LastAccessTime    Filetime
387
+	LastWriteTime     Filetime
388
+	FileSizeHigh      uint32
389
+	FileSizeLow       uint32
390
+	Reserved0         uint32
391
+	Reserved1         uint32
392
+	FileName          [MAX_PATH]uint16
393
+	AlternateFileName [14]uint16
394
+}
395
+
396
+func copyFindData(dst *Win32finddata, src *win32finddata1) {
397
+	dst.FileAttributes = src.FileAttributes
398
+	dst.CreationTime = src.CreationTime
399
+	dst.LastAccessTime = src.LastAccessTime
400
+	dst.LastWriteTime = src.LastWriteTime
401
+	dst.FileSizeHigh = src.FileSizeHigh
402
+	dst.FileSizeLow = src.FileSizeLow
403
+	dst.Reserved0 = src.Reserved0
404
+	dst.Reserved1 = src.Reserved1
405
+
406
+	// The src is 1 element bigger than dst, but it must be NUL.
407
+	copy(dst.FileName[:], src.FileName[:])
408
+	copy(dst.AlternateFileName[:], src.AlternateFileName[:])
409
+}
410
+
411
+type ByHandleFileInformation struct {
412
+	FileAttributes     uint32
413
+	CreationTime       Filetime
414
+	LastAccessTime     Filetime
415
+	LastWriteTime      Filetime
416
+	VolumeSerialNumber uint32
417
+	FileSizeHigh       uint32
418
+	FileSizeLow        uint32
419
+	NumberOfLinks      uint32
420
+	FileIndexHigh      uint32
421
+	FileIndexLow       uint32
422
+}
423
+
424
+const (
425
+	GetFileExInfoStandard = 0
426
+	GetFileExMaxInfoLevel = 1
427
+)
428
+
429
+type Win32FileAttributeData struct {
430
+	FileAttributes uint32
431
+	CreationTime   Filetime
432
+	LastAccessTime Filetime
433
+	LastWriteTime  Filetime
434
+	FileSizeHigh   uint32
435
+	FileSizeLow    uint32
436
+}
437
+
438
+// ShowWindow constants
439
+const (
440
+	// winuser.h
441
+	SW_HIDE            = 0
442
+	SW_NORMAL          = 1
443
+	SW_SHOWNORMAL      = 1
444
+	SW_SHOWMINIMIZED   = 2
445
+	SW_SHOWMAXIMIZED   = 3
446
+	SW_MAXIMIZE        = 3
447
+	SW_SHOWNOACTIVATE  = 4
448
+	SW_SHOW            = 5
449
+	SW_MINIMIZE        = 6
450
+	SW_SHOWMINNOACTIVE = 7
451
+	SW_SHOWNA          = 8
452
+	SW_RESTORE         = 9
453
+	SW_SHOWDEFAULT     = 10
454
+	SW_FORCEMINIMIZE   = 11
455
+)
456
+
457
+type StartupInfo struct {
458
+	Cb            uint32
459
+	_             *uint16
460
+	Desktop       *uint16
461
+	Title         *uint16
462
+	X             uint32
463
+	Y             uint32
464
+	XSize         uint32
465
+	YSize         uint32
466
+	XCountChars   uint32
467
+	YCountChars   uint32
468
+	FillAttribute uint32
469
+	Flags         uint32
470
+	ShowWindow    uint16
471
+	_             uint16
472
+	_             *byte
473
+	StdInput      Handle
474
+	StdOutput     Handle
475
+	StdErr        Handle
476
+}
477
+
478
+type ProcessInformation struct {
479
+	Process   Handle
480
+	Thread    Handle
481
+	ProcessId uint32
482
+	ThreadId  uint32
483
+}
484
+
485
+type ProcessEntry32 struct {
486
+	Size            uint32
487
+	Usage           uint32
488
+	ProcessID       uint32
489
+	DefaultHeapID   uintptr
490
+	ModuleID        uint32
491
+	Threads         uint32
492
+	ParentProcessID uint32
493
+	PriClassBase    int32
494
+	Flags           uint32
495
+	ExeFile         [MAX_PATH]uint16
496
+}
497
+
498
+type Systemtime struct {
499
+	Year         uint16
500
+	Month        uint16
501
+	DayOfWeek    uint16
502
+	Day          uint16
503
+	Hour         uint16
504
+	Minute       uint16
505
+	Second       uint16
506
+	Milliseconds uint16
507
+}
508
+
509
+type Timezoneinformation struct {
510
+	Bias         int32
511
+	StandardName [32]uint16
512
+	StandardDate Systemtime
513
+	StandardBias int32
514
+	DaylightName [32]uint16
515
+	DaylightDate Systemtime
516
+	DaylightBias int32
517
+}
518
+
519
+// Socket related.
520
+
521
+const (
522
+	AF_UNSPEC  = 0
523
+	AF_UNIX    = 1
524
+	AF_INET    = 2
525
+	AF_INET6   = 23
526
+	AF_NETBIOS = 17
527
+
528
+	SOCK_STREAM    = 1
529
+	SOCK_DGRAM     = 2
530
+	SOCK_RAW       = 3
531
+	SOCK_SEQPACKET = 5
532
+
533
+	IPPROTO_IP   = 0
534
+	IPPROTO_IPV6 = 0x29
535
+	IPPROTO_TCP  = 6
536
+	IPPROTO_UDP  = 17
537
+
538
+	SOL_SOCKET                = 0xffff
539
+	SO_REUSEADDR              = 4
540
+	SO_KEEPALIVE              = 8
541
+	SO_DONTROUTE              = 16
542
+	SO_BROADCAST              = 32
543
+	SO_LINGER                 = 128
544
+	SO_RCVBUF                 = 0x1002
545
+	SO_SNDBUF                 = 0x1001
546
+	SO_UPDATE_ACCEPT_CONTEXT  = 0x700b
547
+	SO_UPDATE_CONNECT_CONTEXT = 0x7010
548
+
549
+	IOC_OUT                            = 0x40000000
550
+	IOC_IN                             = 0x80000000
551
+	IOC_VENDOR                         = 0x18000000
552
+	IOC_INOUT                          = IOC_IN | IOC_OUT
553
+	IOC_WS2                            = 0x08000000
554
+	SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6
555
+	SIO_KEEPALIVE_VALS                 = IOC_IN | IOC_VENDOR | 4
556
+	SIO_UDP_CONNRESET                  = IOC_IN | IOC_VENDOR | 12
557
+
558
+	// cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460
559
+
560
+	IP_TOS             = 0x3
561
+	IP_TTL             = 0x4
562
+	IP_MULTICAST_IF    = 0x9
563
+	IP_MULTICAST_TTL   = 0xa
564
+	IP_MULTICAST_LOOP  = 0xb
565
+	IP_ADD_MEMBERSHIP  = 0xc
566
+	IP_DROP_MEMBERSHIP = 0xd
567
+
568
+	IPV6_V6ONLY         = 0x1b
569
+	IPV6_UNICAST_HOPS   = 0x4
570
+	IPV6_MULTICAST_IF   = 0x9
571
+	IPV6_MULTICAST_HOPS = 0xa
572
+	IPV6_MULTICAST_LOOP = 0xb
573
+	IPV6_JOIN_GROUP     = 0xc
574
+	IPV6_LEAVE_GROUP    = 0xd
575
+
576
+	SOMAXCONN = 0x7fffffff
577
+
578
+	TCP_NODELAY = 1
579
+
580
+	SHUT_RD   = 0
581
+	SHUT_WR   = 1
582
+	SHUT_RDWR = 2
583
+
584
+	WSADESCRIPTION_LEN = 256
585
+	WSASYS_STATUS_LEN  = 128
586
+)
587
+
588
+type WSABuf struct {
589
+	Len uint32
590
+	Buf *byte
591
+}
592
+
593
+// Invented values to support what package os expects.
594
+const (
595
+	S_IFMT   = 0x1f000
596
+	S_IFIFO  = 0x1000
597
+	S_IFCHR  = 0x2000
598
+	S_IFDIR  = 0x4000
599
+	S_IFBLK  = 0x6000
600
+	S_IFREG  = 0x8000
601
+	S_IFLNK  = 0xa000
602
+	S_IFSOCK = 0xc000
603
+	S_ISUID  = 0x800
604
+	S_ISGID  = 0x400
605
+	S_ISVTX  = 0x200
606
+	S_IRUSR  = 0x100
607
+	S_IWRITE = 0x80
608
+	S_IWUSR  = 0x80
609
+	S_IXUSR  = 0x40
610
+)
611
+
612
+const (
613
+	FILE_TYPE_CHAR    = 0x0002
614
+	FILE_TYPE_DISK    = 0x0001
615
+	FILE_TYPE_PIPE    = 0x0003
616
+	FILE_TYPE_REMOTE  = 0x8000
617
+	FILE_TYPE_UNKNOWN = 0x0000
618
+)
619
+
620
+type Hostent struct {
621
+	Name     *byte
622
+	Aliases  **byte
623
+	AddrType uint16
624
+	Length   uint16
625
+	AddrList **byte
626
+}
627
+
628
+type Protoent struct {
629
+	Name    *byte
630
+	Aliases **byte
631
+	Proto   uint16
632
+}
633
+
634
+const (
635
+	DNS_TYPE_A       = 0x0001
636
+	DNS_TYPE_NS      = 0x0002
637
+	DNS_TYPE_MD      = 0x0003
638
+	DNS_TYPE_MF      = 0x0004
639
+	DNS_TYPE_CNAME   = 0x0005
640
+	DNS_TYPE_SOA     = 0x0006
641
+	DNS_TYPE_MB      = 0x0007
642
+	DNS_TYPE_MG      = 0x0008
643
+	DNS_TYPE_MR      = 0x0009
644
+	DNS_TYPE_NULL    = 0x000a
645
+	DNS_TYPE_WKS     = 0x000b
646
+	DNS_TYPE_PTR     = 0x000c
647
+	DNS_TYPE_HINFO   = 0x000d
648
+	DNS_TYPE_MINFO   = 0x000e
649
+	DNS_TYPE_MX      = 0x000f
650
+	DNS_TYPE_TEXT    = 0x0010
651
+	DNS_TYPE_RP      = 0x0011
652
+	DNS_TYPE_AFSDB   = 0x0012
653
+	DNS_TYPE_X25     = 0x0013
654
+	DNS_TYPE_ISDN    = 0x0014
655
+	DNS_TYPE_RT      = 0x0015
656
+	DNS_TYPE_NSAP    = 0x0016
657
+	DNS_TYPE_NSAPPTR = 0x0017
658
+	DNS_TYPE_SIG     = 0x0018
659
+	DNS_TYPE_KEY     = 0x0019
660
+	DNS_TYPE_PX      = 0x001a
661
+	DNS_TYPE_GPOS    = 0x001b
662
+	DNS_TYPE_AAAA    = 0x001c
663
+	DNS_TYPE_LOC     = 0x001d
664
+	DNS_TYPE_NXT     = 0x001e
665
+	DNS_TYPE_EID     = 0x001f
666
+	DNS_TYPE_NIMLOC  = 0x0020
667
+	DNS_TYPE_SRV     = 0x0021
668
+	DNS_TYPE_ATMA    = 0x0022
669
+	DNS_TYPE_NAPTR   = 0x0023
670
+	DNS_TYPE_KX      = 0x0024
671
+	DNS_TYPE_CERT    = 0x0025
672
+	DNS_TYPE_A6      = 0x0026
673
+	DNS_TYPE_DNAME   = 0x0027
674
+	DNS_TYPE_SINK    = 0x0028
675
+	DNS_TYPE_OPT     = 0x0029
676
+	DNS_TYPE_DS      = 0x002B
677
+	DNS_TYPE_RRSIG   = 0x002E
678
+	DNS_TYPE_NSEC    = 0x002F
679
+	DNS_TYPE_DNSKEY  = 0x0030
680
+	DNS_TYPE_DHCID   = 0x0031
681
+	DNS_TYPE_UINFO   = 0x0064
682
+	DNS_TYPE_UID     = 0x0065
683
+	DNS_TYPE_GID     = 0x0066
684
+	DNS_TYPE_UNSPEC  = 0x0067
685
+	DNS_TYPE_ADDRS   = 0x00f8
686
+	DNS_TYPE_TKEY    = 0x00f9
687
+	DNS_TYPE_TSIG    = 0x00fa
688
+	DNS_TYPE_IXFR    = 0x00fb
689
+	DNS_TYPE_AXFR    = 0x00fc
690
+	DNS_TYPE_MAILB   = 0x00fd
691
+	DNS_TYPE_MAILA   = 0x00fe
692
+	DNS_TYPE_ALL     = 0x00ff
693
+	DNS_TYPE_ANY     = 0x00ff
694
+	DNS_TYPE_WINS    = 0xff01
695
+	DNS_TYPE_WINSR   = 0xff02
696
+	DNS_TYPE_NBSTAT  = 0xff01
697
+)
698
+
699
+const (
700
+	DNS_INFO_NO_RECORDS = 0x251D
701
+)
702
+
703
+const (
704
+	// flags inside DNSRecord.Dw
705
+	DnsSectionQuestion   = 0x0000
706
+	DnsSectionAnswer     = 0x0001
707
+	DnsSectionAuthority  = 0x0002
708
+	DnsSectionAdditional = 0x0003
709
+)
710
+
711
+type DNSSRVData struct {
712
+	Target   *uint16
713
+	Priority uint16
714
+	Weight   uint16
715
+	Port     uint16
716
+	Pad      uint16
717
+}
718
+
719
+type DNSPTRData struct {
720
+	Host *uint16
721
+}
722
+
723
+type DNSMXData struct {
724
+	NameExchange *uint16
725
+	Preference   uint16
726
+	Pad          uint16
727
+}
728
+
729
+type DNSTXTData struct {
730
+	StringCount uint16
731
+	StringArray [1]*uint16
732
+}
733
+
734
+type DNSRecord struct {
735
+	Next     *DNSRecord
736
+	Name     *uint16
737
+	Type     uint16
738
+	Length   uint16
739
+	Dw       uint32
740
+	Ttl      uint32
741
+	Reserved uint32
742
+	Data     [40]byte
743
+}
744
+
745
+const (
746
+	TF_DISCONNECT         = 1
747
+	TF_REUSE_SOCKET       = 2
748
+	TF_WRITE_BEHIND       = 4
749
+	TF_USE_DEFAULT_WORKER = 0
750
+	TF_USE_SYSTEM_THREAD  = 16
751
+	TF_USE_KERNEL_APC     = 32
752
+)
753
+
754
+type TransmitFileBuffers struct {
755
+	Head       uintptr
756
+	HeadLength uint32
757
+	Tail       uintptr
758
+	TailLength uint32
759
+}
760
+
761
+const (
762
+	IFF_UP           = 1
763
+	IFF_BROADCAST    = 2
764
+	IFF_LOOPBACK     = 4
765
+	IFF_POINTTOPOINT = 8
766
+	IFF_MULTICAST    = 16
767
+)
768
+
769
+const SIO_GET_INTERFACE_LIST = 0x4004747F
770
+
771
+// TODO(mattn): SockaddrGen is union of sockaddr/sockaddr_in/sockaddr_in6_old.
772
+// will be fixed to change variable type as suitable.
773
+
774
+type SockaddrGen [24]byte
775
+
776
+type InterfaceInfo struct {
777
+	Flags            uint32
778
+	Address          SockaddrGen
779
+	BroadcastAddress SockaddrGen
780
+	Netmask          SockaddrGen
781
+}
782
+
783
+type IpAddressString struct {
784
+	String [16]byte
785
+}
786
+
787
+type IpMaskString IpAddressString
788
+
789
+type IpAddrString struct {
790
+	Next      *IpAddrString
791
+	IpAddress IpAddressString
792
+	IpMask    IpMaskString
793
+	Context   uint32
794
+}
795
+
796
+const MAX_ADAPTER_NAME_LENGTH = 256
797
+const MAX_ADAPTER_DESCRIPTION_LENGTH = 128
798
+const MAX_ADAPTER_ADDRESS_LENGTH = 8
799
+
800
+type IpAdapterInfo struct {
801
+	Next                *IpAdapterInfo
802
+	ComboIndex          uint32
803
+	AdapterName         [MAX_ADAPTER_NAME_LENGTH + 4]byte
804
+	Description         [MAX_ADAPTER_DESCRIPTION_LENGTH + 4]byte
805
+	AddressLength       uint32
806
+	Address             [MAX_ADAPTER_ADDRESS_LENGTH]byte
807
+	Index               uint32
808
+	Type                uint32
809
+	DhcpEnabled         uint32
810
+	CurrentIpAddress    *IpAddrString
811
+	IpAddressList       IpAddrString
812
+	GatewayList         IpAddrString
813
+	DhcpServer          IpAddrString
814
+	HaveWins            bool
815
+	PrimaryWinsServer   IpAddrString
816
+	SecondaryWinsServer IpAddrString
817
+	LeaseObtained       int64
818
+	LeaseExpires        int64
819
+}
820
+
821
+const MAXLEN_PHYSADDR = 8
822
+const MAX_INTERFACE_NAME_LEN = 256
823
+const MAXLEN_IFDESCR = 256
824
+
825
+type MibIfRow struct {
826
+	Name            [MAX_INTERFACE_NAME_LEN]uint16
827
+	Index           uint32
828
+	Type            uint32
829
+	Mtu             uint32
830
+	Speed           uint32
831
+	PhysAddrLen     uint32
832
+	PhysAddr        [MAXLEN_PHYSADDR]byte
833
+	AdminStatus     uint32
834
+	OperStatus      uint32
835
+	LastChange      uint32
836
+	InOctets        uint32
837
+	InUcastPkts     uint32
838
+	InNUcastPkts    uint32
839
+	InDiscards      uint32
840
+	InErrors        uint32
841
+	InUnknownProtos uint32
842
+	OutOctets       uint32
843
+	OutUcastPkts    uint32
844
+	OutNUcastPkts   uint32
845
+	OutDiscards     uint32
846
+	OutErrors       uint32
847
+	OutQLen         uint32
848
+	DescrLen        uint32
849
+	Descr           [MAXLEN_IFDESCR]byte
850
+}
851
+
852
+type CertContext struct {
853
+	EncodingType uint32
854
+	EncodedCert  *byte
855
+	Length       uint32
856
+	CertInfo     uintptr
857
+	Store        Handle
858
+}
859
+
860
+type CertChainContext struct {
861
+	Size                       uint32
862
+	TrustStatus                CertTrustStatus
863
+	ChainCount                 uint32
864
+	Chains                     **CertSimpleChain
865
+	LowerQualityChainCount     uint32
866
+	LowerQualityChains         **CertChainContext
867
+	HasRevocationFreshnessTime uint32
868
+	RevocationFreshnessTime    uint32
869
+}
870
+
871
+type CertSimpleChain struct {
872
+	Size                       uint32
873
+	TrustStatus                CertTrustStatus
874
+	NumElements                uint32
875
+	Elements                   **CertChainElement
876
+	TrustListInfo              uintptr
877
+	HasRevocationFreshnessTime uint32
878
+	RevocationFreshnessTime    uint32
879
+}
880
+
881
+type CertChainElement struct {
882
+	Size              uint32
883
+	CertContext       *CertContext
884
+	TrustStatus       CertTrustStatus
885
+	RevocationInfo    *CertRevocationInfo
886
+	IssuanceUsage     *CertEnhKeyUsage
887
+	ApplicationUsage  *CertEnhKeyUsage
888
+	ExtendedErrorInfo *uint16
889
+}
890
+
891
+type CertRevocationInfo struct {
892
+	Size             uint32
893
+	RevocationResult uint32
894
+	RevocationOid    *byte
895
+	OidSpecificInfo  uintptr
896
+	HasFreshnessTime uint32
897
+	FreshnessTime    uint32
898
+	CrlInfo          uintptr // *CertRevocationCrlInfo
899
+}
900
+
901
+type CertTrustStatus struct {
902
+	ErrorStatus uint32
903
+	InfoStatus  uint32
904
+}
905
+
906
+type CertUsageMatch struct {
907
+	Type  uint32
908
+	Usage CertEnhKeyUsage
909
+}
910
+
911
+type CertEnhKeyUsage struct {
912
+	Length           uint32
913
+	UsageIdentifiers **byte
914
+}
915
+
916
+type CertChainPara struct {
917
+	Size                         uint32
918
+	RequestedUsage               CertUsageMatch
919
+	RequstedIssuancePolicy       CertUsageMatch
920
+	URLRetrievalTimeout          uint32
921
+	CheckRevocationFreshnessTime uint32
922
+	RevocationFreshnessTime      uint32
923
+	CacheResync                  *Filetime
924
+}
925
+
926
+type CertChainPolicyPara struct {
927
+	Size            uint32
928
+	Flags           uint32
929
+	ExtraPolicyPara uintptr
930
+}
931
+
932
+type SSLExtraCertChainPolicyPara struct {
933
+	Size       uint32
934
+	AuthType   uint32
935
+	Checks     uint32
936
+	ServerName *uint16
937
+}
938
+
939
+type CertChainPolicyStatus struct {
940
+	Size              uint32
941
+	Error             uint32
942
+	ChainIndex        uint32
943
+	ElementIndex      uint32
944
+	ExtraPolicyStatus uintptr
945
+}
946
+
947
+const (
948
+	// do not reorder
949
+	HKEY_CLASSES_ROOT = 0x80000000 + iota
950
+	HKEY_CURRENT_USER
951
+	HKEY_LOCAL_MACHINE
952
+	HKEY_USERS
953
+	HKEY_PERFORMANCE_DATA
954
+	HKEY_CURRENT_CONFIG
955
+	HKEY_DYN_DATA
956
+
957
+	KEY_QUERY_VALUE        = 1
958
+	KEY_SET_VALUE          = 2
959
+	KEY_CREATE_SUB_KEY     = 4
960
+	KEY_ENUMERATE_SUB_KEYS = 8
961
+	KEY_NOTIFY             = 16
962
+	KEY_CREATE_LINK        = 32
963
+	KEY_WRITE              = 0x20006
964
+	KEY_EXECUTE            = 0x20019
965
+	KEY_READ               = 0x20019
966
+	KEY_WOW64_64KEY        = 0x0100
967
+	KEY_WOW64_32KEY        = 0x0200
968
+	KEY_ALL_ACCESS         = 0xf003f
969
+)
970
+
971
+const (
972
+	// do not reorder
973
+	REG_NONE = iota
974
+	REG_SZ
975
+	REG_EXPAND_SZ
976
+	REG_BINARY
977
+	REG_DWORD_LITTLE_ENDIAN
978
+	REG_DWORD_BIG_ENDIAN
979
+	REG_LINK
980
+	REG_MULTI_SZ
981
+	REG_RESOURCE_LIST
982
+	REG_FULL_RESOURCE_DESCRIPTOR
983
+	REG_RESOURCE_REQUIREMENTS_LIST
984
+	REG_QWORD_LITTLE_ENDIAN
985
+	REG_DWORD = REG_DWORD_LITTLE_ENDIAN
986
+	REG_QWORD = REG_QWORD_LITTLE_ENDIAN
987
+)
988
+
989
+type AddrinfoW struct {
990
+	Flags     int32
991
+	Family    int32
992
+	Socktype  int32
993
+	Protocol  int32
994
+	Addrlen   uintptr
995
+	Canonname *uint16
996
+	Addr      uintptr
997
+	Next      *AddrinfoW
998
+}
999
+
1000
+const (
1001
+	AI_PASSIVE     = 1
1002
+	AI_CANONNAME   = 2
1003
+	AI_NUMERICHOST = 4
1004
+)
1005
+
1006
+type GUID struct {
1007
+	Data1 uint32
1008
+	Data2 uint16
1009
+	Data3 uint16
1010
+	Data4 [8]byte
1011
+}
1012
+
1013
+var WSAID_CONNECTEX = GUID{
1014
+	0x25a207b9,
1015
+	0xddf3,
1016
+	0x4660,
1017
+	[8]byte{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e},
1018
+}
1019
+
1020
+const (
1021
+	FILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
1022
+	FILE_SKIP_SET_EVENT_ON_HANDLE        = 2
1023
+)
1024
+
1025
+const (
1026
+	WSAPROTOCOL_LEN    = 255
1027
+	MAX_PROTOCOL_CHAIN = 7
1028
+	BASE_PROTOCOL      = 1
1029
+	LAYERED_PROTOCOL   = 0
1030
+
1031
+	XP1_CONNECTIONLESS           = 0x00000001
1032
+	XP1_GUARANTEED_DELIVERY      = 0x00000002
1033
+	XP1_GUARANTEED_ORDER         = 0x00000004
1034
+	XP1_MESSAGE_ORIENTED         = 0x00000008
1035
+	XP1_PSEUDO_STREAM            = 0x00000010
1036
+	XP1_GRACEFUL_CLOSE           = 0x00000020
1037
+	XP1_EXPEDITED_DATA           = 0x00000040
1038
+	XP1_CONNECT_DATA             = 0x00000080
1039
+	XP1_DISCONNECT_DATA          = 0x00000100
1040
+	XP1_SUPPORT_BROADCAST        = 0x00000200
1041
+	XP1_SUPPORT_MULTIPOINT       = 0x00000400
1042
+	XP1_MULTIPOINT_CONTROL_PLANE = 0x00000800
1043
+	XP1_MULTIPOINT_DATA_PLANE    = 0x00001000
1044
+	XP1_QOS_SUPPORTED            = 0x00002000
1045
+	XP1_UNI_SEND                 = 0x00008000
1046
+	XP1_UNI_RECV                 = 0x00010000
1047
+	XP1_IFS_HANDLES              = 0x00020000
1048
+	XP1_PARTIAL_MESSAGE          = 0x00040000
1049
+	XP1_SAN_SUPPORT_SDP          = 0x00080000
1050
+
1051
+	PFL_MULTIPLE_PROTO_ENTRIES  = 0x00000001
1052
+	PFL_RECOMMENDED_PROTO_ENTRY = 0x00000002
1053
+	PFL_HIDDEN                  = 0x00000004
1054
+	PFL_MATCHES_PROTOCOL_ZERO   = 0x00000008
1055
+	PFL_NETWORKDIRECT_PROVIDER  = 0x00000010
1056
+)
1057
+
1058
+type WSAProtocolInfo struct {
1059
+	ServiceFlags1     uint32
1060
+	ServiceFlags2     uint32
1061
+	ServiceFlags3     uint32
1062
+	ServiceFlags4     uint32
1063
+	ProviderFlags     uint32
1064
+	ProviderId        GUID
1065
+	CatalogEntryId    uint32
1066
+	ProtocolChain     WSAProtocolChain
1067
+	Version           int32
1068
+	AddressFamily     int32
1069
+	MaxSockAddr       int32
1070
+	MinSockAddr       int32
1071
+	SocketType        int32
1072
+	Protocol          int32
1073
+	ProtocolMaxOffset int32
1074
+	NetworkByteOrder  int32
1075
+	SecurityScheme    int32
1076
+	MessageSize       uint32
1077
+	ProviderReserved  uint32
1078
+	ProtocolName      [WSAPROTOCOL_LEN + 1]uint16
1079
+}
1080
+
1081
+type WSAProtocolChain struct {
1082
+	ChainLen     int32
1083
+	ChainEntries [MAX_PROTOCOL_CHAIN]uint32
1084
+}
1085
+
1086
+type TCPKeepalive struct {
1087
+	OnOff    uint32
1088
+	Time     uint32
1089
+	Interval uint32
1090
+}
1091
+
1092
+type symbolicLinkReparseBuffer struct {
1093
+	SubstituteNameOffset uint16
1094
+	SubstituteNameLength uint16
1095
+	PrintNameOffset      uint16
1096
+	PrintNameLength      uint16
1097
+	Flags                uint32
1098
+	PathBuffer           [1]uint16
1099
+}
1100
+
1101
+type mountPointReparseBuffer struct {
1102
+	SubstituteNameOffset uint16
1103
+	SubstituteNameLength uint16
1104
+	PrintNameOffset      uint16
1105
+	PrintNameLength      uint16
1106
+	PathBuffer           [1]uint16
1107
+}
1108
+
1109
+type reparseDataBuffer struct {
1110
+	ReparseTag        uint32
1111
+	ReparseDataLength uint16
1112
+	Reserved          uint16
1113
+
1114
+	// GenericReparseBuffer
1115
+	reparseBuffer byte
1116
+}
1117
+
1118
+const (
1119
+	FSCTL_GET_REPARSE_POINT          = 0x900A8
1120
+	MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024
1121
+	IO_REPARSE_TAG_MOUNT_POINT       = 0xA0000003
1122
+	IO_REPARSE_TAG_SYMLINK           = 0xA000000C
1123
+	SYMBOLIC_LINK_FLAG_DIRECTORY     = 0x1
1124
+)
1125
+
1126
+const (
1127
+	ComputerNameNetBIOS                   = 0
1128
+	ComputerNameDnsHostname               = 1
1129
+	ComputerNameDnsDomain                 = 2
1130
+	ComputerNameDnsFullyQualified         = 3
1131
+	ComputerNamePhysicalNetBIOS           = 4
1132
+	ComputerNamePhysicalDnsHostname       = 5
1133
+	ComputerNamePhysicalDnsDomain         = 6
1134
+	ComputerNamePhysicalDnsFullyQualified = 7
1135
+	ComputerNameMax                       = 8
1136
+)
1137
+
1138
+const (
1139
+	MOVEFILE_REPLACE_EXISTING      = 0x1
1140
+	MOVEFILE_COPY_ALLOWED          = 0x2
1141
+	MOVEFILE_DELAY_UNTIL_REBOOT    = 0x4
1142
+	MOVEFILE_WRITE_THROUGH         = 0x8
1143
+	MOVEFILE_CREATE_HARDLINK       = 0x10
1144
+	MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20
1145
+)
1146
+
1147
+const GAA_FLAG_INCLUDE_PREFIX = 0x00000010
1148
+
1149
+const (
1150
+	IF_TYPE_OTHER              = 1
1151
+	IF_TYPE_ETHERNET_CSMACD    = 6
1152
+	IF_TYPE_ISO88025_TOKENRING = 9
1153
+	IF_TYPE_PPP                = 23
1154
+	IF_TYPE_SOFTWARE_LOOPBACK  = 24
1155
+	IF_TYPE_ATM                = 37
1156
+	IF_TYPE_IEEE80211          = 71
1157
+	IF_TYPE_TUNNEL             = 131
1158
+	IF_TYPE_IEEE1394           = 144
1159
+)
1160
+
1161
+type SocketAddress struct {
1162
+	Sockaddr       *syscall.RawSockaddrAny
1163
+	SockaddrLength int32
1164
+}
1165
+
1166
+type IpAdapterUnicastAddress struct {
1167
+	Length             uint32
1168
+	Flags              uint32
1169
+	Next               *IpAdapterUnicastAddress
1170
+	Address            SocketAddress
1171
+	PrefixOrigin       int32
1172
+	SuffixOrigin       int32
1173
+	DadState           int32
1174
+	ValidLifetime      uint32
1175
+	PreferredLifetime  uint32
1176
+	LeaseLifetime      uint32
1177
+	OnLinkPrefixLength uint8
1178
+}
1179
+
1180
+type IpAdapterAnycastAddress struct {
1181
+	Length  uint32
1182
+	Flags   uint32
1183
+	Next    *IpAdapterAnycastAddress
1184
+	Address SocketAddress
1185
+}
1186
+
1187
+type IpAdapterMulticastAddress struct {
1188
+	Length  uint32
1189
+	Flags   uint32
1190
+	Next    *IpAdapterMulticastAddress
1191
+	Address SocketAddress
1192
+}
1193
+
1194
+type IpAdapterDnsServerAdapter struct {
1195
+	Length   uint32
1196
+	Reserved uint32
1197
+	Next     *IpAdapterDnsServerAdapter
1198
+	Address  SocketAddress
1199
+}
1200
+
1201
+type IpAdapterPrefix struct {
1202
+	Length       uint32
1203
+	Flags        uint32
1204
+	Next         *IpAdapterPrefix
1205
+	Address      SocketAddress
1206
+	PrefixLength uint32
1207
+}
1208
+
1209
+type IpAdapterAddresses struct {
1210
+	Length                uint32
1211
+	IfIndex               uint32
1212
+	Next                  *IpAdapterAddresses
1213
+	AdapterName           *byte
1214
+	FirstUnicastAddress   *IpAdapterUnicastAddress
1215
+	FirstAnycastAddress   *IpAdapterAnycastAddress
1216
+	FirstMulticastAddress *IpAdapterMulticastAddress
1217
+	FirstDnsServerAddress *IpAdapterDnsServerAdapter
1218
+	DnsSuffix             *uint16
1219
+	Description           *uint16
1220
+	FriendlyName          *uint16
1221
+	PhysicalAddress       [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte
1222
+	PhysicalAddressLength uint32
1223
+	Flags                 uint32
1224
+	Mtu                   uint32
1225
+	IfType                uint32
1226
+	OperStatus            uint32
1227
+	Ipv6IfIndex           uint32
1228
+	ZoneIndices           [16]uint32
1229
+	FirstPrefix           *IpAdapterPrefix
1230
+	/* more fields might be present here. */
1231
+}
1232
+
1233
+const (
1234
+	IfOperStatusUp             = 1
1235
+	IfOperStatusDown           = 2
1236
+	IfOperStatusTesting        = 3
1237
+	IfOperStatusUnknown        = 4
1238
+	IfOperStatusDormant        = 5
1239
+	IfOperStatusNotPresent     = 6
1240
+	IfOperStatusLowerLayerDown = 7
1241
+)
0 1242
new file mode 100644
... ...
@@ -0,0 +1,22 @@
0
+// Copyright 2011 The Go Authors.  All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+package windows
5
+
6
+type WSAData struct {
7
+	Version      uint16
8
+	HighVersion  uint16
9
+	Description  [WSADESCRIPTION_LEN + 1]byte
10
+	SystemStatus [WSASYS_STATUS_LEN + 1]byte
11
+	MaxSockets   uint16
12
+	MaxUdpDg     uint16
13
+	VendorInfo   *byte
14
+}
15
+
16
+type Servent struct {
17
+	Name    *byte
18
+	Aliases **byte
19
+	Port    uint16
20
+	Proto   *byte
21
+}
0 22
new file mode 100644
... ...
@@ -0,0 +1,22 @@
0
+// Copyright 2011 The Go Authors.  All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+package windows
5
+
6
+type WSAData struct {
7
+	Version      uint16
8
+	HighVersion  uint16
9
+	MaxSockets   uint16
10
+	MaxUdpDg     uint16
11
+	VendorInfo   *byte
12
+	Description  [WSADESCRIPTION_LEN + 1]byte
13
+	SystemStatus [WSASYS_STATUS_LEN + 1]byte
14
+}
15
+
16
+type Servent struct {
17
+	Name    *byte
18
+	Aliases **byte
19
+	Proto   *byte
20
+	Port    uint16
21
+}