From ed9118b34620f1ecd5f28506328d4ffe1b04793d Mon Sep 17 00:00:00 2001
From: Wim <wim@42.be>
Date: Sun, 3 Dec 2017 01:24:05 +0100
Subject: Add sshchat dependencies in vendor

---
 vendor/golang.org/x/sys/windows/svc/debug/log.go   |  56 ++++
 .../golang.org/x/sys/windows/svc/debug/service.go  |  45 +++
 vendor/golang.org/x/sys/windows/svc/event.go       |  48 +++
 .../x/sys/windows/svc/eventlog/install.go          |  80 +++++
 .../golang.org/x/sys/windows/svc/eventlog/log.go   |  70 ++++
 .../golang.org/x/sys/windows/svc/example/beep.go   |  22 ++
 .../x/sys/windows/svc/example/install.go           |  92 ++++++
 .../golang.org/x/sys/windows/svc/example/main.go   |  76 +++++
 .../golang.org/x/sys/windows/svc/example/manage.go |  62 ++++
 .../x/sys/windows/svc/example/service.go           |  82 +++++
 vendor/golang.org/x/sys/windows/svc/go12.c         |  24 ++
 vendor/golang.org/x/sys/windows/svc/go12.go        |  11 +
 vendor/golang.org/x/sys/windows/svc/go13.go        |  31 ++
 vendor/golang.org/x/sys/windows/svc/mgr/config.go  | 139 ++++++++
 vendor/golang.org/x/sys/windows/svc/mgr/mgr.go     | 162 +++++++++
 vendor/golang.org/x/sys/windows/svc/mgr/service.go |  72 ++++
 vendor/golang.org/x/sys/windows/svc/security.go    |  62 ++++
 vendor/golang.org/x/sys/windows/svc/service.go     | 363 +++++++++++++++++++++
 vendor/golang.org/x/sys/windows/svc/sys_386.s      |  68 ++++
 vendor/golang.org/x/sys/windows/svc/sys_amd64.s    |  42 +++
 20 files changed, 1607 insertions(+)
 create mode 100644 vendor/golang.org/x/sys/windows/svc/debug/log.go
 create mode 100644 vendor/golang.org/x/sys/windows/svc/debug/service.go
 create mode 100644 vendor/golang.org/x/sys/windows/svc/event.go
 create mode 100644 vendor/golang.org/x/sys/windows/svc/eventlog/install.go
 create mode 100644 vendor/golang.org/x/sys/windows/svc/eventlog/log.go
 create mode 100644 vendor/golang.org/x/sys/windows/svc/example/beep.go
 create mode 100644 vendor/golang.org/x/sys/windows/svc/example/install.go
 create mode 100644 vendor/golang.org/x/sys/windows/svc/example/main.go
 create mode 100644 vendor/golang.org/x/sys/windows/svc/example/manage.go
 create mode 100644 vendor/golang.org/x/sys/windows/svc/example/service.go
 create mode 100644 vendor/golang.org/x/sys/windows/svc/go12.c
 create mode 100644 vendor/golang.org/x/sys/windows/svc/go12.go
 create mode 100644 vendor/golang.org/x/sys/windows/svc/go13.go
 create mode 100644 vendor/golang.org/x/sys/windows/svc/mgr/config.go
 create mode 100644 vendor/golang.org/x/sys/windows/svc/mgr/mgr.go
 create mode 100644 vendor/golang.org/x/sys/windows/svc/mgr/service.go
 create mode 100644 vendor/golang.org/x/sys/windows/svc/security.go
 create mode 100644 vendor/golang.org/x/sys/windows/svc/service.go
 create mode 100644 vendor/golang.org/x/sys/windows/svc/sys_386.s
 create mode 100644 vendor/golang.org/x/sys/windows/svc/sys_amd64.s

(limited to 'vendor/golang.org/x/sys/windows/svc')

diff --git a/vendor/golang.org/x/sys/windows/svc/debug/log.go b/vendor/golang.org/x/sys/windows/svc/debug/log.go
new file mode 100644
index 00000000..e51ab42a
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/debug/log.go
@@ -0,0 +1,56 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package debug
+
+import (
+	"os"
+	"strconv"
+)
+
+// Log interface allows different log implementations to be used.
+type Log interface {
+	Close() error
+	Info(eid uint32, msg string) error
+	Warning(eid uint32, msg string) error
+	Error(eid uint32, msg string) error
+}
+
+// ConsoleLog provides access to the console.
+type ConsoleLog struct {
+	Name string
+}
+
+// New creates new ConsoleLog.
+func New(source string) *ConsoleLog {
+	return &ConsoleLog{Name: source}
+}
+
+// Close closes console log l.
+func (l *ConsoleLog) Close() error {
+	return nil
+}
+
+func (l *ConsoleLog) report(kind string, eid uint32, msg string) error {
+	s := l.Name + "." + kind + "(" + strconv.Itoa(int(eid)) + "): " + msg + "\n"
+	_, err := os.Stdout.Write([]byte(s))
+	return err
+}
+
+// Info writes an information event msg with event id eid to the console l.
+func (l *ConsoleLog) Info(eid uint32, msg string) error {
+	return l.report("info", eid, msg)
+}
+
+// Warning writes an warning event msg with event id eid to the console l.
+func (l *ConsoleLog) Warning(eid uint32, msg string) error {
+	return l.report("warn", eid, msg)
+}
+
+// Error writes an error event msg with event id eid to the console l.
+func (l *ConsoleLog) Error(eid uint32, msg string) error {
+	return l.report("error", eid, msg)
+}
diff --git a/vendor/golang.org/x/sys/windows/svc/debug/service.go b/vendor/golang.org/x/sys/windows/svc/debug/service.go
new file mode 100644
index 00000000..123df989
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/debug/service.go
@@ -0,0 +1,45 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// Package debug provides facilities to execute svc.Handler on console.
+//
+package debug
+
+import (
+	"os"
+	"os/signal"
+	"syscall"
+
+	"golang.org/x/sys/windows/svc"
+)
+
+// Run executes service name by calling appropriate handler function.
+// The process is running on console, unlike real service. Use Ctrl+C to
+// send "Stop" command to your service.
+func Run(name string, handler svc.Handler) error {
+	cmds := make(chan svc.ChangeRequest)
+	changes := make(chan svc.Status)
+
+	sig := make(chan os.Signal)
+	signal.Notify(sig)
+
+	go func() {
+		status := svc.Status{State: svc.Stopped}
+		for {
+			select {
+			case <-sig:
+				cmds <- svc.ChangeRequest{svc.Stop, 0, 0, status}
+			case status = <-changes:
+			}
+		}
+	}()
+
+	_, errno := handler.Execute([]string{name}, cmds, changes)
+	if errno != 0 {
+		return syscall.Errno(errno)
+	}
+	return nil
+}
diff --git a/vendor/golang.org/x/sys/windows/svc/event.go b/vendor/golang.org/x/sys/windows/svc/event.go
new file mode 100644
index 00000000..0508e228
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/event.go
@@ -0,0 +1,48 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package svc
+
+import (
+	"errors"
+
+	"golang.org/x/sys/windows"
+)
+
+// event represents auto-reset, initially non-signaled Windows event.
+// It is used to communicate between go and asm parts of this package.
+type event struct {
+	h windows.Handle
+}
+
+func newEvent() (*event, error) {
+	h, err := windows.CreateEvent(nil, 0, 0, nil)
+	if err != nil {
+		return nil, err
+	}
+	return &event{h: h}, nil
+}
+
+func (e *event) Close() error {
+	return windows.CloseHandle(e.h)
+}
+
+func (e *event) Set() error {
+	return windows.SetEvent(e.h)
+}
+
+func (e *event) Wait() error {
+	s, err := windows.WaitForSingleObject(e.h, windows.INFINITE)
+	switch s {
+	case windows.WAIT_OBJECT_0:
+		break
+	case windows.WAIT_FAILED:
+		return err
+	default:
+		return errors.New("unexpected result from WaitForSingleObject")
+	}
+	return nil
+}
diff --git a/vendor/golang.org/x/sys/windows/svc/eventlog/install.go b/vendor/golang.org/x/sys/windows/svc/eventlog/install.go
new file mode 100644
index 00000000..c76a3760
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/eventlog/install.go
@@ -0,0 +1,80 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package eventlog
+
+import (
+	"errors"
+
+	"golang.org/x/sys/windows"
+	"golang.org/x/sys/windows/registry"
+)
+
+const (
+	// Log levels.
+	Info    = windows.EVENTLOG_INFORMATION_TYPE
+	Warning = windows.EVENTLOG_WARNING_TYPE
+	Error   = windows.EVENTLOG_ERROR_TYPE
+)
+
+const addKeyName = `SYSTEM\CurrentControlSet\Services\EventLog\Application`
+
+// Install modifies PC registry to allow logging with an event source src.
+// It adds all required keys and values to the event log registry key.
+// Install uses msgFile as the event message file. If useExpandKey is true,
+// the event message file is installed as REG_EXPAND_SZ value,
+// otherwise as REG_SZ. Use bitwise of log.Error, log.Warning and
+// log.Info to specify events supported by the new event source.
+func Install(src, msgFile string, useExpandKey bool, eventsSupported uint32) error {
+	appkey, err := registry.OpenKey(registry.LOCAL_MACHINE, addKeyName, registry.CREATE_SUB_KEY)
+	if err != nil {
+		return err
+	}
+	defer appkey.Close()
+
+	sk, alreadyExist, err := registry.CreateKey(appkey, src, registry.SET_VALUE)
+	if err != nil {
+		return err
+	}
+	defer sk.Close()
+	if alreadyExist {
+		return errors.New(addKeyName + `\` + src + " registry key already exists")
+	}
+
+	err = sk.SetDWordValue("CustomSource", 1)
+	if err != nil {
+		return err
+	}
+	if useExpandKey {
+		err = sk.SetExpandStringValue("EventMessageFile", msgFile)
+	} else {
+		err = sk.SetStringValue("EventMessageFile", msgFile)
+	}
+	if err != nil {
+		return err
+	}
+	err = sk.SetDWordValue("TypesSupported", eventsSupported)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+// InstallAsEventCreate is the same as Install, but uses
+// %SystemRoot%\System32\EventCreate.exe as the event message file.
+func InstallAsEventCreate(src string, eventsSupported uint32) error {
+	return Install(src, "%SystemRoot%\\System32\\EventCreate.exe", true, eventsSupported)
+}
+
+// Remove deletes all registry elements installed by the correspondent Install.
+func Remove(src string) error {
+	appkey, err := registry.OpenKey(registry.LOCAL_MACHINE, addKeyName, registry.SET_VALUE)
+	if err != nil {
+		return err
+	}
+	defer appkey.Close()
+	return registry.DeleteKey(appkey, src)
+}
diff --git a/vendor/golang.org/x/sys/windows/svc/eventlog/log.go b/vendor/golang.org/x/sys/windows/svc/eventlog/log.go
new file mode 100644
index 00000000..46e5153d
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/eventlog/log.go
@@ -0,0 +1,70 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// Package eventlog implements access to Windows event log.
+//
+package eventlog
+
+import (
+	"errors"
+	"syscall"
+
+	"golang.org/x/sys/windows"
+)
+
+// Log provides access to the system log.
+type Log struct {
+	Handle windows.Handle
+}
+
+// Open retrieves a handle to the specified event log.
+func Open(source string) (*Log, error) {
+	return OpenRemote("", source)
+}
+
+// OpenRemote does the same as Open, but on different computer host.
+func OpenRemote(host, source string) (*Log, error) {
+	if source == "" {
+		return nil, errors.New("Specify event log source")
+	}
+	var s *uint16
+	if host != "" {
+		s = syscall.StringToUTF16Ptr(host)
+	}
+	h, err := windows.RegisterEventSource(s, syscall.StringToUTF16Ptr(source))
+	if err != nil {
+		return nil, err
+	}
+	return &Log{Handle: h}, nil
+}
+
+// Close closes event log l.
+func (l *Log) Close() error {
+	return windows.DeregisterEventSource(l.Handle)
+}
+
+func (l *Log) report(etype uint16, eid uint32, msg string) error {
+	ss := []*uint16{syscall.StringToUTF16Ptr(msg)}
+	return windows.ReportEvent(l.Handle, etype, 0, eid, 0, 1, 0, &ss[0], nil)
+}
+
+// Info writes an information event msg with event id eid to the end of event log l.
+// When EventCreate.exe is used, eid must be between 1 and 1000.
+func (l *Log) Info(eid uint32, msg string) error {
+	return l.report(windows.EVENTLOG_INFORMATION_TYPE, eid, msg)
+}
+
+// Warning writes an warning event msg with event id eid to the end of event log l.
+// When EventCreate.exe is used, eid must be between 1 and 1000.
+func (l *Log) Warning(eid uint32, msg string) error {
+	return l.report(windows.EVENTLOG_WARNING_TYPE, eid, msg)
+}
+
+// Error writes an error event msg with event id eid to the end of event log l.
+// When EventCreate.exe is used, eid must be between 1 and 1000.
+func (l *Log) Error(eid uint32, msg string) error {
+	return l.report(windows.EVENTLOG_ERROR_TYPE, eid, msg)
+}
diff --git a/vendor/golang.org/x/sys/windows/svc/example/beep.go b/vendor/golang.org/x/sys/windows/svc/example/beep.go
new file mode 100644
index 00000000..dcf23408
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/example/beep.go
@@ -0,0 +1,22 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package main
+
+import (
+	"syscall"
+)
+
+// BUG(brainman): MessageBeep Windows api is broken on Windows 7,
+// so this example does not beep when runs as service on Windows 7.
+
+var (
+	beepFunc = syscall.MustLoadDLL("user32.dll").MustFindProc("MessageBeep")
+)
+
+func beep() {
+	beepFunc.Call(0xffffffff)
+}
diff --git a/vendor/golang.org/x/sys/windows/svc/example/install.go b/vendor/golang.org/x/sys/windows/svc/example/install.go
new file mode 100644
index 00000000..39cb00d2
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/example/install.go
@@ -0,0 +1,92 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package main
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+
+	"golang.org/x/sys/windows/svc/eventlog"
+	"golang.org/x/sys/windows/svc/mgr"
+)
+
+func exePath() (string, error) {
+	prog := os.Args[0]
+	p, err := filepath.Abs(prog)
+	if err != nil {
+		return "", err
+	}
+	fi, err := os.Stat(p)
+	if err == nil {
+		if !fi.Mode().IsDir() {
+			return p, nil
+		}
+		err = fmt.Errorf("%s is directory", p)
+	}
+	if filepath.Ext(p) == "" {
+		p += ".exe"
+		fi, err := os.Stat(p)
+		if err == nil {
+			if !fi.Mode().IsDir() {
+				return p, nil
+			}
+			err = fmt.Errorf("%s is directory", p)
+		}
+	}
+	return "", err
+}
+
+func installService(name, desc string) error {
+	exepath, err := exePath()
+	if err != nil {
+		return err
+	}
+	m, err := mgr.Connect()
+	if err != nil {
+		return err
+	}
+	defer m.Disconnect()
+	s, err := m.OpenService(name)
+	if err == nil {
+		s.Close()
+		return fmt.Errorf("service %s already exists", name)
+	}
+	s, err = m.CreateService(name, exepath, mgr.Config{DisplayName: desc}, "is", "auto-started")
+	if err != nil {
+		return err
+	}
+	defer s.Close()
+	err = eventlog.InstallAsEventCreate(name, eventlog.Error|eventlog.Warning|eventlog.Info)
+	if err != nil {
+		s.Delete()
+		return fmt.Errorf("SetupEventLogSource() failed: %s", err)
+	}
+	return nil
+}
+
+func removeService(name string) error {
+	m, err := mgr.Connect()
+	if err != nil {
+		return err
+	}
+	defer m.Disconnect()
+	s, err := m.OpenService(name)
+	if err != nil {
+		return fmt.Errorf("service %s is not installed", name)
+	}
+	defer s.Close()
+	err = s.Delete()
+	if err != nil {
+		return err
+	}
+	err = eventlog.Remove(name)
+	if err != nil {
+		return fmt.Errorf("RemoveEventLogSource() failed: %s", err)
+	}
+	return nil
+}
diff --git a/vendor/golang.org/x/sys/windows/svc/example/main.go b/vendor/golang.org/x/sys/windows/svc/example/main.go
new file mode 100644
index 00000000..dc96c081
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/example/main.go
@@ -0,0 +1,76 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// Example service program that beeps.
+//
+// The program demonstrates how to create Windows service and
+// install / remove it on a computer. It also shows how to
+// stop / start / pause / continue any service, and how to
+// write to event log. It also shows how to use debug
+// facilities available in debug package.
+//
+package main
+
+import (
+	"fmt"
+	"log"
+	"os"
+	"strings"
+
+	"golang.org/x/sys/windows/svc"
+)
+
+func usage(errmsg string) {
+	fmt.Fprintf(os.Stderr,
+		"%s\n\n"+
+			"usage: %s <command>\n"+
+			"       where <command> is one of\n"+
+			"       install, remove, debug, start, stop, pause or continue.\n",
+		errmsg, os.Args[0])
+	os.Exit(2)
+}
+
+func main() {
+	const svcName = "myservice"
+
+	isIntSess, err := svc.IsAnInteractiveSession()
+	if err != nil {
+		log.Fatalf("failed to determine if we are running in an interactive session: %v", err)
+	}
+	if !isIntSess {
+		runService(svcName, false)
+		return
+	}
+
+	if len(os.Args) < 2 {
+		usage("no command specified")
+	}
+
+	cmd := strings.ToLower(os.Args[1])
+	switch cmd {
+	case "debug":
+		runService(svcName, true)
+		return
+	case "install":
+		err = installService(svcName, "my service")
+	case "remove":
+		err = removeService(svcName)
+	case "start":
+		err = startService(svcName)
+	case "stop":
+		err = controlService(svcName, svc.Stop, svc.Stopped)
+	case "pause":
+		err = controlService(svcName, svc.Pause, svc.Paused)
+	case "continue":
+		err = controlService(svcName, svc.Continue, svc.Running)
+	default:
+		usage(fmt.Sprintf("invalid command %s", cmd))
+	}
+	if err != nil {
+		log.Fatalf("failed to %s %s: %v", cmd, svcName, err)
+	}
+	return
+}
diff --git a/vendor/golang.org/x/sys/windows/svc/example/manage.go b/vendor/golang.org/x/sys/windows/svc/example/manage.go
new file mode 100644
index 00000000..782dbd96
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/example/manage.go
@@ -0,0 +1,62 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package main
+
+import (
+	"fmt"
+	"time"
+
+	"golang.org/x/sys/windows/svc"
+	"golang.org/x/sys/windows/svc/mgr"
+)
+
+func startService(name string) error {
+	m, err := mgr.Connect()
+	if err != nil {
+		return err
+	}
+	defer m.Disconnect()
+	s, err := m.OpenService(name)
+	if err != nil {
+		return fmt.Errorf("could not access service: %v", err)
+	}
+	defer s.Close()
+	err = s.Start("is", "manual-started")
+	if err != nil {
+		return fmt.Errorf("could not start service: %v", err)
+	}
+	return nil
+}
+
+func controlService(name string, c svc.Cmd, to svc.State) error {
+	m, err := mgr.Connect()
+	if err != nil {
+		return err
+	}
+	defer m.Disconnect()
+	s, err := m.OpenService(name)
+	if err != nil {
+		return fmt.Errorf("could not access service: %v", err)
+	}
+	defer s.Close()
+	status, err := s.Control(c)
+	if err != nil {
+		return fmt.Errorf("could not send control=%d: %v", c, err)
+	}
+	timeout := time.Now().Add(10 * time.Second)
+	for status.State != to {
+		if timeout.Before(time.Now()) {
+			return fmt.Errorf("timeout waiting for service to go to state=%d", to)
+		}
+		time.Sleep(300 * time.Millisecond)
+		status, err = s.Query()
+		if err != nil {
+			return fmt.Errorf("could not retrieve service status: %v", err)
+		}
+	}
+	return nil
+}
diff --git a/vendor/golang.org/x/sys/windows/svc/example/service.go b/vendor/golang.org/x/sys/windows/svc/example/service.go
new file mode 100644
index 00000000..237e8098
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/example/service.go
@@ -0,0 +1,82 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package main
+
+import (
+	"fmt"
+	"time"
+
+	"golang.org/x/sys/windows/svc"
+	"golang.org/x/sys/windows/svc/debug"
+	"golang.org/x/sys/windows/svc/eventlog"
+)
+
+var elog debug.Log
+
+type myservice struct{}
+
+func (m *myservice) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
+	const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue
+	changes <- svc.Status{State: svc.StartPending}
+	fasttick := time.Tick(500 * time.Millisecond)
+	slowtick := time.Tick(2 * time.Second)
+	tick := fasttick
+	changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
+loop:
+	for {
+		select {
+		case <-tick:
+			beep()
+			elog.Info(1, "beep")
+		case c := <-r:
+			switch c.Cmd {
+			case svc.Interrogate:
+				changes <- c.CurrentStatus
+				// Testing deadlock from https://code.google.com/p/winsvc/issues/detail?id=4
+				time.Sleep(100 * time.Millisecond)
+				changes <- c.CurrentStatus
+			case svc.Stop, svc.Shutdown:
+				break loop
+			case svc.Pause:
+				changes <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted}
+				tick = slowtick
+			case svc.Continue:
+				changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
+				tick = fasttick
+			default:
+				elog.Error(1, fmt.Sprintf("unexpected control request #%d", c))
+			}
+		}
+	}
+	changes <- svc.Status{State: svc.StopPending}
+	return
+}
+
+func runService(name string, isDebug bool) {
+	var err error
+	if isDebug {
+		elog = debug.New(name)
+	} else {
+		elog, err = eventlog.Open(name)
+		if err != nil {
+			return
+		}
+	}
+	defer elog.Close()
+
+	elog.Info(1, fmt.Sprintf("starting %s service", name))
+	run := svc.Run
+	if isDebug {
+		run = debug.Run
+	}
+	err = run(name, &myservice{})
+	if err != nil {
+		elog.Error(1, fmt.Sprintf("%s service failed: %v", name, err))
+		return
+	}
+	elog.Info(1, fmt.Sprintf("%s service stopped", name))
+}
diff --git a/vendor/golang.org/x/sys/windows/svc/go12.c b/vendor/golang.org/x/sys/windows/svc/go12.c
new file mode 100644
index 00000000..6f1be1fa
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/go12.c
@@ -0,0 +1,24 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+// +build !go1.3
+
+// copied from pkg/runtime
+typedef	unsigned int	uint32;
+typedef	unsigned long long int	uint64;
+#ifdef _64BIT
+typedef	uint64		uintptr;
+#else
+typedef	uint32		uintptr;
+#endif
+
+// from sys_386.s or sys_amd64.s
+void ·servicemain(void);
+
+void
+·getServiceMain(uintptr *r)
+{
+	*r = (uintptr)·servicemain;
+}
diff --git a/vendor/golang.org/x/sys/windows/svc/go12.go b/vendor/golang.org/x/sys/windows/svc/go12.go
new file mode 100644
index 00000000..cd8b913c
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/go12.go
@@ -0,0 +1,11 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+// +build !go1.3
+
+package svc
+
+// from go12.c
+func getServiceMain(r *uintptr)
diff --git a/vendor/golang.org/x/sys/windows/svc/go13.go b/vendor/golang.org/x/sys/windows/svc/go13.go
new file mode 100644
index 00000000..9d7f3cec
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/go13.go
@@ -0,0 +1,31 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+// +build go1.3
+
+package svc
+
+import "unsafe"
+
+const ptrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const
+
+// Should be a built-in for unsafe.Pointer?
+func add(p unsafe.Pointer, x uintptr) unsafe.Pointer {
+	return unsafe.Pointer(uintptr(p) + x)
+}
+
+// funcPC returns the entry PC of the function f.
+// It assumes that f is a func value. Otherwise the behavior is undefined.
+func funcPC(f interface{}) uintptr {
+	return **(**uintptr)(add(unsafe.Pointer(&f), ptrSize))
+}
+
+// from sys_386.s and sys_amd64.s
+func servicectlhandler(ctl uint32) uintptr
+func servicemain(argc uint32, argv **uint16)
+
+func getServiceMain(r *uintptr) {
+	*r = funcPC(servicemain)
+}
diff --git a/vendor/golang.org/x/sys/windows/svc/mgr/config.go b/vendor/golang.org/x/sys/windows/svc/mgr/config.go
new file mode 100644
index 00000000..0a6edba4
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/mgr/config.go
@@ -0,0 +1,139 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package mgr
+
+import (
+	"syscall"
+	"unicode/utf16"
+	"unsafe"
+
+	"golang.org/x/sys/windows"
+)
+
+const (
+	// Service start types.
+	StartManual    = windows.SERVICE_DEMAND_START // the service must be started manually
+	StartAutomatic = windows.SERVICE_AUTO_START   // the service will start by itself whenever the computer reboots
+	StartDisabled  = windows.SERVICE_DISABLED     // the service cannot be started
+
+	// The severity of the error, and action taken,
+	// if this service fails to start.
+	ErrorCritical = windows.SERVICE_ERROR_CRITICAL
+	ErrorIgnore   = windows.SERVICE_ERROR_IGNORE
+	ErrorNormal   = windows.SERVICE_ERROR_NORMAL
+	ErrorSevere   = windows.SERVICE_ERROR_SEVERE
+)
+
+// TODO(brainman): Password is not returned by windows.QueryServiceConfig, not sure how to get it.
+
+type Config struct {
+	ServiceType      uint32
+	StartType        uint32
+	ErrorControl     uint32
+	BinaryPathName   string // fully qualified path to the service binary file, can also include arguments for an auto-start service
+	LoadOrderGroup   string
+	TagId            uint32
+	Dependencies     []string
+	ServiceStartName string // name of the account under which the service should run
+	DisplayName      string
+	Password         string
+	Description      string
+}
+
+func toString(p *uint16) string {
+	if p == nil {
+		return ""
+	}
+	return syscall.UTF16ToString((*[4096]uint16)(unsafe.Pointer(p))[:])
+}
+
+func toStringSlice(ps *uint16) []string {
+	if ps == nil {
+		return nil
+	}
+	r := make([]string, 0)
+	for from, i, p := 0, 0, (*[1 << 24]uint16)(unsafe.Pointer(ps)); true; i++ {
+		if p[i] == 0 {
+			// empty string marks the end
+			if i <= from {
+				break
+			}
+			r = append(r, string(utf16.Decode(p[from:i])))
+			from = i + 1
+		}
+	}
+	return r
+}
+
+// Config retrieves service s configuration paramteres.
+func (s *Service) Config() (Config, error) {
+	var p *windows.QUERY_SERVICE_CONFIG
+	n := uint32(1024)
+	for {
+		b := make([]byte, n)
+		p = (*windows.QUERY_SERVICE_CONFIG)(unsafe.Pointer(&b[0]))
+		err := windows.QueryServiceConfig(s.Handle, p, n, &n)
+		if err == nil {
+			break
+		}
+		if err.(syscall.Errno) != syscall.ERROR_INSUFFICIENT_BUFFER {
+			return Config{}, err
+		}
+		if n <= uint32(len(b)) {
+			return Config{}, err
+		}
+	}
+
+	var p2 *windows.SERVICE_DESCRIPTION
+	n = uint32(1024)
+	for {
+		b := make([]byte, n)
+		p2 = (*windows.SERVICE_DESCRIPTION)(unsafe.Pointer(&b[0]))
+		err := windows.QueryServiceConfig2(s.Handle,
+			windows.SERVICE_CONFIG_DESCRIPTION, &b[0], n, &n)
+		if err == nil {
+			break
+		}
+		if err.(syscall.Errno) != syscall.ERROR_INSUFFICIENT_BUFFER {
+			return Config{}, err
+		}
+		if n <= uint32(len(b)) {
+			return Config{}, err
+		}
+	}
+
+	return Config{
+		ServiceType:      p.ServiceType,
+		StartType:        p.StartType,
+		ErrorControl:     p.ErrorControl,
+		BinaryPathName:   toString(p.BinaryPathName),
+		LoadOrderGroup:   toString(p.LoadOrderGroup),
+		TagId:            p.TagId,
+		Dependencies:     toStringSlice(p.Dependencies),
+		ServiceStartName: toString(p.ServiceStartName),
+		DisplayName:      toString(p.DisplayName),
+		Description:      toString(p2.Description),
+	}, nil
+}
+
+func updateDescription(handle windows.Handle, desc string) error {
+	d := windows.SERVICE_DESCRIPTION{toPtr(desc)}
+	return windows.ChangeServiceConfig2(handle,
+		windows.SERVICE_CONFIG_DESCRIPTION, (*byte)(unsafe.Pointer(&d)))
+}
+
+// UpdateConfig updates service s configuration parameters.
+func (s *Service) UpdateConfig(c Config) error {
+	err := windows.ChangeServiceConfig(s.Handle, c.ServiceType, c.StartType,
+		c.ErrorControl, toPtr(c.BinaryPathName), toPtr(c.LoadOrderGroup),
+		nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName),
+		toPtr(c.Password), toPtr(c.DisplayName))
+	if err != nil {
+		return err
+	}
+	return updateDescription(s.Handle, c.Description)
+}
diff --git a/vendor/golang.org/x/sys/windows/svc/mgr/mgr.go b/vendor/golang.org/x/sys/windows/svc/mgr/mgr.go
new file mode 100644
index 00000000..76965b56
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/mgr/mgr.go
@@ -0,0 +1,162 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// Package mgr can be used to manage Windows service programs.
+// It can be used to install and remove them. It can also start,
+// stop and pause them. The package can query / change current
+// service state and config parameters.
+//
+package mgr
+
+import (
+	"syscall"
+	"unicode/utf16"
+	"unsafe"
+
+	"golang.org/x/sys/windows"
+)
+
+// Mgr is used to manage Windows service.
+type Mgr struct {
+	Handle windows.Handle
+}
+
+// Connect establishes a connection to the service control manager.
+func Connect() (*Mgr, error) {
+	return ConnectRemote("")
+}
+
+// ConnectRemote establishes a connection to the
+// service control manager on computer named host.
+func ConnectRemote(host string) (*Mgr, error) {
+	var s *uint16
+	if host != "" {
+		s = syscall.StringToUTF16Ptr(host)
+	}
+	h, err := windows.OpenSCManager(s, nil, windows.SC_MANAGER_ALL_ACCESS)
+	if err != nil {
+		return nil, err
+	}
+	return &Mgr{Handle: h}, nil
+}
+
+// Disconnect closes connection to the service control manager m.
+func (m *Mgr) Disconnect() error {
+	return windows.CloseServiceHandle(m.Handle)
+}
+
+func toPtr(s string) *uint16 {
+	if len(s) == 0 {
+		return nil
+	}
+	return syscall.StringToUTF16Ptr(s)
+}
+
+// toStringBlock terminates strings in ss with 0, and then
+// concatenates them together. It also adds extra 0 at the end.
+func toStringBlock(ss []string) *uint16 {
+	if len(ss) == 0 {
+		return nil
+	}
+	t := ""
+	for _, s := range ss {
+		if s != "" {
+			t += s + "\x00"
+		}
+	}
+	if t == "" {
+		return nil
+	}
+	t += "\x00"
+	return &utf16.Encode([]rune(t))[0]
+}
+
+// CreateService installs new service name on the system.
+// The service will be executed by running exepath binary.
+// Use config c to specify service parameters.
+// Any args will be passed as command-line arguments when
+// the service is started; these arguments are distinct from
+// the arguments passed to Service.Start or via the "Start
+// parameters" field in the service's Properties dialog box.
+func (m *Mgr) CreateService(name, exepath string, c Config, args ...string) (*Service, error) {
+	if c.StartType == 0 {
+		c.StartType = StartManual
+	}
+	if c.ErrorControl == 0 {
+		c.ErrorControl = ErrorNormal
+	}
+	if c.ServiceType == 0 {
+		c.ServiceType = windows.SERVICE_WIN32_OWN_PROCESS
+	}
+	s := syscall.EscapeArg(exepath)
+	for _, v := range args {
+		s += " " + syscall.EscapeArg(v)
+	}
+	h, err := windows.CreateService(m.Handle, toPtr(name), toPtr(c.DisplayName),
+		windows.SERVICE_ALL_ACCESS, c.ServiceType,
+		c.StartType, c.ErrorControl, toPtr(s), toPtr(c.LoadOrderGroup),
+		nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName), toPtr(c.Password))
+	if err != nil {
+		return nil, err
+	}
+	if c.Description != "" {
+		err = updateDescription(h, c.Description)
+		if err != nil {
+			return nil, err
+		}
+	}
+	return &Service{Name: name, Handle: h}, nil
+}
+
+// OpenService retrieves access to service name, so it can
+// be interrogated and controlled.
+func (m *Mgr) OpenService(name string) (*Service, error) {
+	h, err := windows.OpenService(m.Handle, syscall.StringToUTF16Ptr(name), windows.SERVICE_ALL_ACCESS)
+	if err != nil {
+		return nil, err
+	}
+	return &Service{Name: name, Handle: h}, nil
+}
+
+// ListServices enumerates services in the specified
+// service control manager database m.
+// If the caller does not have the SERVICE_QUERY_STATUS
+// access right to a service, the service is silently
+// omitted from the list of services returned.
+func (m *Mgr) ListServices() ([]string, error) {
+	var err error
+	var bytesNeeded, servicesReturned uint32
+	var buf []byte
+	for {
+		var p *byte
+		if len(buf) > 0 {
+			p = &buf[0]
+		}
+		err = windows.EnumServicesStatusEx(m.Handle, windows.SC_ENUM_PROCESS_INFO,
+			windows.SERVICE_WIN32, windows.SERVICE_STATE_ALL,
+			p, uint32(len(buf)), &bytesNeeded, &servicesReturned, nil, nil)
+		if err == nil {
+			break
+		}
+		if err != syscall.ERROR_MORE_DATA {
+			return nil, err
+		}
+		if bytesNeeded <= uint32(len(buf)) {
+			return nil, err
+		}
+		buf = make([]byte, bytesNeeded)
+	}
+	if servicesReturned == 0 {
+		return nil, nil
+	}
+	services := (*[1 << 20]windows.ENUM_SERVICE_STATUS_PROCESS)(unsafe.Pointer(&buf[0]))[:servicesReturned]
+	var names []string
+	for _, s := range services {
+		name := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(s.ServiceName))[:])
+		names = append(names, name)
+	}
+	return names, nil
+}
diff --git a/vendor/golang.org/x/sys/windows/svc/mgr/service.go b/vendor/golang.org/x/sys/windows/svc/mgr/service.go
new file mode 100644
index 00000000..fdc46af5
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/mgr/service.go
@@ -0,0 +1,72 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package mgr
+
+import (
+	"syscall"
+
+	"golang.org/x/sys/windows"
+	"golang.org/x/sys/windows/svc"
+)
+
+// TODO(brainman): Use EnumDependentServices to enumerate dependent services.
+
+// Service is used to access Windows service.
+type Service struct {
+	Name   string
+	Handle windows.Handle
+}
+
+// Delete marks service s for deletion from the service control manager database.
+func (s *Service) Delete() error {
+	return windows.DeleteService(s.Handle)
+}
+
+// Close relinquish access to the service s.
+func (s *Service) Close() error {
+	return windows.CloseServiceHandle(s.Handle)
+}
+
+// Start starts service s.
+// args will be passed to svc.Handler.Execute.
+func (s *Service) Start(args ...string) error {
+	var p **uint16
+	if len(args) > 0 {
+		vs := make([]*uint16, len(args))
+		for i := range vs {
+			vs[i] = syscall.StringToUTF16Ptr(args[i])
+		}
+		p = &vs[0]
+	}
+	return windows.StartService(s.Handle, uint32(len(args)), p)
+}
+
+// Control sends state change request c to the servce s.
+func (s *Service) Control(c svc.Cmd) (svc.Status, error) {
+	var t windows.SERVICE_STATUS
+	err := windows.ControlService(s.Handle, uint32(c), &t)
+	if err != nil {
+		return svc.Status{}, err
+	}
+	return svc.Status{
+		State:   svc.State(t.CurrentState),
+		Accepts: svc.Accepted(t.ControlsAccepted),
+	}, nil
+}
+
+// Query returns current status of service s.
+func (s *Service) Query() (svc.Status, error) {
+	var t windows.SERVICE_STATUS
+	err := windows.QueryServiceStatus(s.Handle, &t)
+	if err != nil {
+		return svc.Status{}, err
+	}
+	return svc.Status{
+		State:   svc.State(t.CurrentState),
+		Accepts: svc.Accepted(t.ControlsAccepted),
+	}, nil
+}
diff --git a/vendor/golang.org/x/sys/windows/svc/security.go b/vendor/golang.org/x/sys/windows/svc/security.go
new file mode 100644
index 00000000..6fbc9236
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/security.go
@@ -0,0 +1,62 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package svc
+
+import (
+	"unsafe"
+
+	"golang.org/x/sys/windows"
+)
+
+func allocSid(subAuth0 uint32) (*windows.SID, error) {
+	var sid *windows.SID
+	err := windows.AllocateAndInitializeSid(&windows.SECURITY_NT_AUTHORITY,
+		1, subAuth0, 0, 0, 0, 0, 0, 0, 0, &sid)
+	if err != nil {
+		return nil, err
+	}
+	return sid, nil
+}
+
+// IsAnInteractiveSession determines if calling process is running interactively.
+// It queries the process token for membership in the Interactive group.
+// http://stackoverflow.com/questions/2668851/how-do-i-detect-that-my-application-is-running-as-service-or-in-an-interactive-s
+func IsAnInteractiveSession() (bool, error) {
+	interSid, err := allocSid(windows.SECURITY_INTERACTIVE_RID)
+	if err != nil {
+		return false, err
+	}
+	defer windows.FreeSid(interSid)
+
+	serviceSid, err := allocSid(windows.SECURITY_SERVICE_RID)
+	if err != nil {
+		return false, err
+	}
+	defer windows.FreeSid(serviceSid)
+
+	t, err := windows.OpenCurrentProcessToken()
+	if err != nil {
+		return false, err
+	}
+	defer t.Close()
+
+	gs, err := t.GetTokenGroups()
+	if err != nil {
+		return false, err
+	}
+	p := unsafe.Pointer(&gs.Groups[0])
+	groups := (*[2 << 20]windows.SIDAndAttributes)(p)[:gs.GroupCount]
+	for _, g := range groups {
+		if windows.EqualSid(g.Sid, interSid) {
+			return true, nil
+		}
+		if windows.EqualSid(g.Sid, serviceSid) {
+			return false, nil
+		}
+	}
+	return false, nil
+}
diff --git a/vendor/golang.org/x/sys/windows/svc/service.go b/vendor/golang.org/x/sys/windows/svc/service.go
new file mode 100644
index 00000000..903cba3f
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/service.go
@@ -0,0 +1,363 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// Package svc provides everything required to build Windows service.
+//
+package svc
+
+import (
+	"errors"
+	"runtime"
+	"syscall"
+	"unsafe"
+
+	"golang.org/x/sys/windows"
+)
+
+// State describes service execution state (Stopped, Running and so on).
+type State uint32
+
+const (
+	Stopped         = State(windows.SERVICE_STOPPED)
+	StartPending    = State(windows.SERVICE_START_PENDING)
+	StopPending     = State(windows.SERVICE_STOP_PENDING)
+	Running         = State(windows.SERVICE_RUNNING)
+	ContinuePending = State(windows.SERVICE_CONTINUE_PENDING)
+	PausePending    = State(windows.SERVICE_PAUSE_PENDING)
+	Paused          = State(windows.SERVICE_PAUSED)
+)
+
+// Cmd represents service state change request. It is sent to a service
+// by the service manager, and should be actioned upon by the service.
+type Cmd uint32
+
+const (
+	Stop                  = Cmd(windows.SERVICE_CONTROL_STOP)
+	Pause                 = Cmd(windows.SERVICE_CONTROL_PAUSE)
+	Continue              = Cmd(windows.SERVICE_CONTROL_CONTINUE)
+	Interrogate           = Cmd(windows.SERVICE_CONTROL_INTERROGATE)
+	Shutdown              = Cmd(windows.SERVICE_CONTROL_SHUTDOWN)
+	ParamChange           = Cmd(windows.SERVICE_CONTROL_PARAMCHANGE)
+	NetBindAdd            = Cmd(windows.SERVICE_CONTROL_NETBINDADD)
+	NetBindRemove         = Cmd(windows.SERVICE_CONTROL_NETBINDREMOVE)
+	NetBindEnable         = Cmd(windows.SERVICE_CONTROL_NETBINDENABLE)
+	NetBindDisable        = Cmd(windows.SERVICE_CONTROL_NETBINDDISABLE)
+	DeviceEvent           = Cmd(windows.SERVICE_CONTROL_DEVICEEVENT)
+	HardwareProfileChange = Cmd(windows.SERVICE_CONTROL_HARDWAREPROFILECHANGE)
+	PowerEvent            = Cmd(windows.SERVICE_CONTROL_POWEREVENT)
+	SessionChange         = Cmd(windows.SERVICE_CONTROL_SESSIONCHANGE)
+)
+
+// Accepted is used to describe commands accepted by the service.
+// Note that Interrogate is always accepted.
+type Accepted uint32
+
+const (
+	AcceptStop                  = Accepted(windows.SERVICE_ACCEPT_STOP)
+	AcceptShutdown              = Accepted(windows.SERVICE_ACCEPT_SHUTDOWN)
+	AcceptPauseAndContinue      = Accepted(windows.SERVICE_ACCEPT_PAUSE_CONTINUE)
+	AcceptParamChange           = Accepted(windows.SERVICE_ACCEPT_PARAMCHANGE)
+	AcceptNetBindChange         = Accepted(windows.SERVICE_ACCEPT_NETBINDCHANGE)
+	AcceptHardwareProfileChange = Accepted(windows.SERVICE_ACCEPT_HARDWAREPROFILECHANGE)
+	AcceptPowerEvent            = Accepted(windows.SERVICE_ACCEPT_POWEREVENT)
+	AcceptSessionChange         = Accepted(windows.SERVICE_ACCEPT_SESSIONCHANGE)
+)
+
+// Status combines State and Accepted commands to fully describe running service.
+type Status struct {
+	State      State
+	Accepts    Accepted
+	CheckPoint uint32 // used to report progress during a lengthy operation
+	WaitHint   uint32 // estimated time required for a pending operation, in milliseconds
+}
+
+// ChangeRequest is sent to the service Handler to request service status change.
+type ChangeRequest struct {
+	Cmd           Cmd
+	EventType     uint32
+	EventData     uintptr
+	CurrentStatus Status
+}
+
+// Handler is the interface that must be implemented to build Windows service.
+type Handler interface {
+
+	// Execute will be called by the package code at the start of
+	// the service, and the service will exit once Execute completes.
+	// Inside Execute you must read service change requests from r and
+	// act accordingly. You must keep service control manager up to date
+	// about state of your service by writing into s as required.
+	// args contains service name followed by argument strings passed
+	// to the service.
+	// You can provide service exit code in exitCode return parameter,
+	// with 0 being "no error". You can also indicate if exit code,
+	// if any, is service specific or not by using svcSpecificEC
+	// parameter.
+	Execute(args []string, r <-chan ChangeRequest, s chan<- Status) (svcSpecificEC bool, exitCode uint32)
+}
+
+var (
+	// These are used by asm code.
+	goWaitsH                       uintptr
+	cWaitsH                        uintptr
+	ssHandle                       uintptr
+	sName                          *uint16
+	sArgc                          uintptr
+	sArgv                          **uint16
+	ctlHandlerExProc               uintptr
+	cSetEvent                      uintptr
+	cWaitForSingleObject           uintptr
+	cRegisterServiceCtrlHandlerExW uintptr
+)
+
+func init() {
+	k := syscall.MustLoadDLL("kernel32.dll")
+	cSetEvent = k.MustFindProc("SetEvent").Addr()
+	cWaitForSingleObject = k.MustFindProc("WaitForSingleObject").Addr()
+	a := syscall.MustLoadDLL("advapi32.dll")
+	cRegisterServiceCtrlHandlerExW = a.MustFindProc("RegisterServiceCtrlHandlerExW").Addr()
+}
+
+// The HandlerEx prototype also has a context pointer but since we don't use
+// it at start-up time we don't have to pass it over either.
+type ctlEvent struct {
+	cmd       Cmd
+	eventType uint32
+	eventData uintptr
+	errno     uint32
+}
+
+// service provides access to windows service api.
+type service struct {
+	name    string
+	h       windows.Handle
+	cWaits  *event
+	goWaits *event
+	c       chan ctlEvent
+	handler Handler
+}
+
+func newService(name string, handler Handler) (*service, error) {
+	var s service
+	var err error
+	s.name = name
+	s.c = make(chan ctlEvent)
+	s.handler = handler
+	s.cWaits, err = newEvent()
+	if err != nil {
+		return nil, err
+	}
+	s.goWaits, err = newEvent()
+	if err != nil {
+		s.cWaits.Close()
+		return nil, err
+	}
+	return &s, nil
+}
+
+func (s *service) close() error {
+	s.cWaits.Close()
+	s.goWaits.Close()
+	return nil
+}
+
+type exitCode struct {
+	isSvcSpecific bool
+	errno         uint32
+}
+
+func (s *service) updateStatus(status *Status, ec *exitCode) error {
+	if s.h == 0 {
+		return errors.New("updateStatus with no service status handle")
+	}
+	var t windows.SERVICE_STATUS
+	t.ServiceType = windows.SERVICE_WIN32_OWN_PROCESS
+	t.CurrentState = uint32(status.State)
+	if status.Accepts&AcceptStop != 0 {
+		t.ControlsAccepted |= windows.SERVICE_ACCEPT_STOP
+	}
+	if status.Accepts&AcceptShutdown != 0 {
+		t.ControlsAccepted |= windows.SERVICE_ACCEPT_SHUTDOWN
+	}
+	if status.Accepts&AcceptPauseAndContinue != 0 {
+		t.ControlsAccepted |= windows.SERVICE_ACCEPT_PAUSE_CONTINUE
+	}
+	if status.Accepts&AcceptParamChange != 0 {
+		t.ControlsAccepted |= windows.SERVICE_ACCEPT_PARAMCHANGE
+	}
+	if status.Accepts&AcceptNetBindChange != 0 {
+		t.ControlsAccepted |= windows.SERVICE_ACCEPT_NETBINDCHANGE
+	}
+	if status.Accepts&AcceptHardwareProfileChange != 0 {
+		t.ControlsAccepted |= windows.SERVICE_ACCEPT_HARDWAREPROFILECHANGE
+	}
+	if status.Accepts&AcceptPowerEvent != 0 {
+		t.ControlsAccepted |= windows.SERVICE_ACCEPT_POWEREVENT
+	}
+	if status.Accepts&AcceptSessionChange != 0 {
+		t.ControlsAccepted |= windows.SERVICE_ACCEPT_SESSIONCHANGE
+	}
+	if ec.errno == 0 {
+		t.Win32ExitCode = windows.NO_ERROR
+		t.ServiceSpecificExitCode = windows.NO_ERROR
+	} else if ec.isSvcSpecific {
+		t.Win32ExitCode = uint32(windows.ERROR_SERVICE_SPECIFIC_ERROR)
+		t.ServiceSpecificExitCode = ec.errno
+	} else {
+		t.Win32ExitCode = ec.errno
+		t.ServiceSpecificExitCode = windows.NO_ERROR
+	}
+	t.CheckPoint = status.CheckPoint
+	t.WaitHint = status.WaitHint
+	return windows.SetServiceStatus(s.h, &t)
+}
+
+const (
+	sysErrSetServiceStatusFailed = uint32(syscall.APPLICATION_ERROR) + iota
+	sysErrNewThreadInCallback
+)
+
+func (s *service) run() {
+	s.goWaits.Wait()
+	s.h = windows.Handle(ssHandle)
+	argv := (*[100]*int16)(unsafe.Pointer(sArgv))[:sArgc]
+	args := make([]string, len(argv))
+	for i, a := range argv {
+		args[i] = syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(a))[:])
+	}
+
+	cmdsToHandler := make(chan ChangeRequest)
+	changesFromHandler := make(chan Status)
+	exitFromHandler := make(chan exitCode)
+
+	go func() {
+		ss, errno := s.handler.Execute(args, cmdsToHandler, changesFromHandler)
+		exitFromHandler <- exitCode{ss, errno}
+	}()
+
+	status := Status{State: Stopped}
+	ec := exitCode{isSvcSpecific: true, errno: 0}
+	var outch chan ChangeRequest
+	inch := s.c
+	var cmd Cmd
+	var evtype uint32
+	var evdata uintptr
+loop:
+	for {
+		select {
+		case r := <-inch:
+			if r.errno != 0 {
+				ec.errno = r.errno
+				break loop
+			}
+			inch = nil
+			outch = cmdsToHandler
+			cmd = r.cmd
+			evtype = r.eventType
+			evdata = r.eventData
+		case outch <- ChangeRequest{cmd, evtype, evdata, status}:
+			inch = s.c
+			outch = nil
+		case c := <-changesFromHandler:
+			err := s.updateStatus(&c, &ec)
+			if err != nil {
+				// best suitable error number
+				ec.errno = sysErrSetServiceStatusFailed
+				if err2, ok := err.(syscall.Errno); ok {
+					ec.errno = uint32(err2)
+				}
+				break loop
+			}
+			status = c
+		case ec = <-exitFromHandler:
+			break loop
+		}
+	}
+
+	s.updateStatus(&Status{State: Stopped}, &ec)
+	s.cWaits.Set()
+}
+
+func newCallback(fn interface{}) (cb uintptr, err error) {
+	defer func() {
+		r := recover()
+		if r == nil {
+			return
+		}
+		cb = 0
+		switch v := r.(type) {
+		case string:
+			err = errors.New(v)
+		case error:
+			err = v
+		default:
+			err = errors.New("unexpected panic in syscall.NewCallback")
+		}
+	}()
+	return syscall.NewCallback(fn), nil
+}
+
+// BUG(brainman): There is no mechanism to run multiple services
+// inside one single executable. Perhaps, it can be overcome by
+// using RegisterServiceCtrlHandlerEx Windows api.
+
+// Run executes service name by calling appropriate handler function.
+func Run(name string, handler Handler) error {
+	runtime.LockOSThread()
+
+	tid := windows.GetCurrentThreadId()
+
+	s, err := newService(name, handler)
+	if err != nil {
+		return err
+	}
+
+	ctlHandler := func(ctl uint32, evtype uint32, evdata uintptr, context uintptr) uintptr {
+		e := ctlEvent{cmd: Cmd(ctl), eventType: evtype, eventData: evdata}
+		// We assume that this callback function is running on
+		// the same thread as Run. Nowhere in MS documentation
+		// I could find statement to guarantee that. So putting
+		// check here to verify, otherwise things will go bad
+		// quickly, if ignored.
+		i := windows.GetCurrentThreadId()
+		if i != tid {
+			e.errno = sysErrNewThreadInCallback
+		}
+		s.c <- e
+		// Always return NO_ERROR (0) for now.
+		return 0
+	}
+
+	var svcmain uintptr
+	getServiceMain(&svcmain)
+	t := []windows.SERVICE_TABLE_ENTRY{
+		{syscall.StringToUTF16Ptr(s.name), svcmain},
+		{nil, 0},
+	}
+
+	goWaitsH = uintptr(s.goWaits.h)
+	cWaitsH = uintptr(s.cWaits.h)
+	sName = t[0].ServiceName
+	ctlHandlerExProc, err = newCallback(ctlHandler)
+	if err != nil {
+		return err
+	}
+
+	go s.run()
+
+	err = windows.StartServiceCtrlDispatcher(&t[0])
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+// StatusHandle returns service status handle. It is safe to call this function
+// from inside the Handler.Execute because then it is guaranteed to be set.
+// This code will have to change once multiple services are possible per process.
+func StatusHandle() windows.Handle {
+	return windows.Handle(ssHandle)
+}
diff --git a/vendor/golang.org/x/sys/windows/svc/sys_386.s b/vendor/golang.org/x/sys/windows/svc/sys_386.s
new file mode 100644
index 00000000..2c82a9d9
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/sys_386.s
@@ -0,0 +1,68 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// func servicemain(argc uint32, argv **uint16)
+TEXT ·servicemain(SB),7,$0
+	MOVL	argc+0(FP), AX
+	MOVL	AX, ·sArgc(SB)
+	MOVL	argv+4(FP), AX
+	MOVL	AX, ·sArgv(SB)
+
+	PUSHL	BP
+	PUSHL	BX
+	PUSHL	SI
+	PUSHL	DI
+
+	SUBL	$12, SP
+
+	MOVL	·sName(SB), AX
+	MOVL	AX, (SP)
+	MOVL	$·servicectlhandler(SB), AX
+	MOVL	AX, 4(SP)
+	MOVL	$0, 8(SP)
+	MOVL	·cRegisterServiceCtrlHandlerExW(SB), AX
+	MOVL	SP, BP
+	CALL	AX
+	MOVL	BP, SP
+	CMPL	AX, $0
+	JE	exit
+	MOVL	AX, ·ssHandle(SB)
+
+	MOVL	·goWaitsH(SB), AX
+	MOVL	AX, (SP)
+	MOVL	·cSetEvent(SB), AX
+	MOVL	SP, BP
+	CALL	AX
+	MOVL	BP, SP
+
+	MOVL	·cWaitsH(SB), AX
+	MOVL	AX, (SP)
+	MOVL	$-1, AX
+	MOVL	AX, 4(SP)
+	MOVL	·cWaitForSingleObject(SB), AX
+	MOVL	SP, BP
+	CALL	AX
+	MOVL	BP, SP
+
+exit:
+	ADDL	$12, SP
+
+	POPL	DI
+	POPL	SI
+	POPL	BX
+	POPL	BP
+
+	MOVL	0(SP), CX
+	ADDL	$12, SP
+	JMP	CX
+
+// I do not know why, but this seems to be the only way to call
+// ctlHandlerProc on Windows 7.
+
+// func servicectlhandler(ctl uint32, evtype uint32, evdata uintptr, context uintptr) uintptr {
+TEXT ·servicectlhandler(SB),7,$0
+	MOVL	·ctlHandlerExProc(SB), CX
+	JMP	CX
diff --git a/vendor/golang.org/x/sys/windows/svc/sys_amd64.s b/vendor/golang.org/x/sys/windows/svc/sys_amd64.s
new file mode 100644
index 00000000..06b42590
--- /dev/null
+++ b/vendor/golang.org/x/sys/windows/svc/sys_amd64.s
@@ -0,0 +1,42 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+// func servicemain(argc uint32, argv **uint16)
+TEXT ·servicemain(SB),7,$0
+	MOVL	CX, ·sArgc(SB)
+	MOVL	DX, ·sArgv(SB)
+
+	SUBQ	$32, SP		// stack for the first 4 syscall params
+
+	MOVQ	·sName(SB), CX
+	MOVQ	$·servicectlhandler(SB), DX
+	// BUG(pastarmovj): Figure out a way to pass in context in R8.
+	MOVQ	·cRegisterServiceCtrlHandlerExW(SB), AX
+	CALL	AX
+	CMPQ	AX, $0
+	JE	exit
+	MOVQ	AX, ·ssHandle(SB)
+
+	MOVQ	·goWaitsH(SB), CX
+	MOVQ	·cSetEvent(SB), AX
+	CALL	AX
+
+	MOVQ	·cWaitsH(SB), CX
+	MOVQ	$4294967295, DX
+	MOVQ	·cWaitForSingleObject(SB), AX
+	CALL	AX
+
+exit:
+	ADDQ	$32, SP
+	RET
+
+// I do not know why, but this seems to be the only way to call
+// ctlHandlerProc on Windows 7.
+
+// func ·servicectlhandler(ctl uint32, evtype uint32, evdata uintptr, context uintptr) uintptr {
+TEXT ·servicectlhandler(SB),7,$0
+	MOVQ	·ctlHandlerExProc(SB), AX
+	JMP	AX
-- 
cgit v1.2.3