all: Become a Go module (fixes #5148) (#5384)

* go mod init; rm -rf vendor

* tweak proto files and generation

* go mod vendor

* clean up build.go

* protobuf literals in tests

* downgrade gogo/protobuf
This commit is contained in:
Jakob Borg
2018-12-18 12:36:38 +01:00
committed by GitHub
parent 3cc8918eb4
commit 944ddcf768
1410 changed files with 66232 additions and 688356 deletions

View File

@@ -1,27 +0,0 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

13
vendor/golang.org/x/sys/windows/aliases.go generated vendored Normal file
View File

@@ -0,0 +1,13 @@
// Copyright 2018 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.9
package windows
import "syscall"
type Errno = syscall.Errno
type SysProcAttr = syscall.SysProcAttr

View File

@@ -6,8 +6,8 @@
// System calls for 386, Windows are implemented in runtime/syscall_windows.goc
//
TEXT ·getprocaddress(SB), 7, $0-8
TEXT ·getprocaddress(SB), 7, $0-16
JMP syscall·getprocaddress(SB)
TEXT ·loadlibrary(SB), 7, $0-4
TEXT ·loadlibrary(SB), 7, $0-12
JMP syscall·loadlibrary(SB)

View File

@@ -9,5 +9,5 @@
TEXT ·getprocaddress(SB), 7, $0-32
JMP syscall·getprocaddress(SB)
TEXT ·loadlibrary(SB), 7, $0-8
TEXT ·loadlibrary(SB), 7, $0-24
JMP syscall·loadlibrary(SB)

11
vendor/golang.org/x/sys/windows/asm_windows_arm.s generated vendored Normal file
View File

@@ -0,0 +1,11 @@
// Copyright 2018 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.
#include "textflag.h"
TEXT ·getprocaddress(SB),NOSPLIT,$0
B syscall·getprocaddress(SB)
TEXT ·loadlibrary(SB),NOSPLIT,$0
B syscall·loadlibrary(SB)

View File

@@ -1,15 +0,0 @@
// 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.4
package windows
import "syscall"
func Unsetenv(key string) error {
// This was added in Go 1.4.
return syscall.Unsetenv(key)
}

View File

@@ -23,3 +23,7 @@ func Clearenv() {
func Environ() []string {
return syscall.Environ()
}
func Unsetenv(key string) error {
return syscall.Unsetenv(key)
}

View File

@@ -1,200 +0,0 @@
// Copyright 2015 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 registry provides access to the Windows registry.
//
// Here is a simple example, opening a registry key and reading a string value from it.
//
// k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
// if err != nil {
// log.Fatal(err)
// }
// defer k.Close()
//
// s, _, err := k.GetStringValue("SystemRoot")
// if err != nil {
// log.Fatal(err)
// }
// fmt.Printf("Windows system root is %q\n", s)
//
package registry
import (
"io"
"syscall"
"time"
)
const (
// Registry key security and access rights.
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms724878.aspx
// for details.
ALL_ACCESS = 0xf003f
CREATE_LINK = 0x00020
CREATE_SUB_KEY = 0x00004
ENUMERATE_SUB_KEYS = 0x00008
EXECUTE = 0x20019
NOTIFY = 0x00010
QUERY_VALUE = 0x00001
READ = 0x20019
SET_VALUE = 0x00002
WOW64_32KEY = 0x00200
WOW64_64KEY = 0x00100
WRITE = 0x20006
)
// Key is a handle to an open Windows registry key.
// Keys can be obtained by calling OpenKey; there are
// also some predefined root keys such as CURRENT_USER.
// Keys can be used directly in the Windows API.
type Key syscall.Handle
const (
// Windows defines some predefined root keys that are always open.
// An application can use these keys as entry points to the registry.
// Normally these keys are used in OpenKey to open new keys,
// but they can also be used anywhere a Key is required.
CLASSES_ROOT = Key(syscall.HKEY_CLASSES_ROOT)
CURRENT_USER = Key(syscall.HKEY_CURRENT_USER)
LOCAL_MACHINE = Key(syscall.HKEY_LOCAL_MACHINE)
USERS = Key(syscall.HKEY_USERS)
CURRENT_CONFIG = Key(syscall.HKEY_CURRENT_CONFIG)
PERFORMANCE_DATA = Key(syscall.HKEY_PERFORMANCE_DATA)
)
// Close closes open key k.
func (k Key) Close() error {
return syscall.RegCloseKey(syscall.Handle(k))
}
// OpenKey opens a new key with path name relative to key k.
// It accepts any open key, including CURRENT_USER and others,
// and returns the new key and an error.
// The access parameter specifies desired access rights to the
// key to be opened.
func OpenKey(k Key, path string, access uint32) (Key, error) {
p, err := syscall.UTF16PtrFromString(path)
if err != nil {
return 0, err
}
var subkey syscall.Handle
err = syscall.RegOpenKeyEx(syscall.Handle(k), p, 0, access, &subkey)
if err != nil {
return 0, err
}
return Key(subkey), nil
}
// OpenRemoteKey opens a predefined registry key on another
// computer pcname. The key to be opened is specified by k, but
// can only be one of LOCAL_MACHINE, PERFORMANCE_DATA or USERS.
// If pcname is "", OpenRemoteKey returns local computer key.
func OpenRemoteKey(pcname string, k Key) (Key, error) {
var err error
var p *uint16
if pcname != "" {
p, err = syscall.UTF16PtrFromString(`\\` + pcname)
if err != nil {
return 0, err
}
}
var remoteKey syscall.Handle
err = regConnectRegistry(p, syscall.Handle(k), &remoteKey)
if err != nil {
return 0, err
}
return Key(remoteKey), nil
}
// ReadSubKeyNames returns the names of subkeys of key k.
// The parameter n controls the number of returned names,
// analogous to the way os.File.Readdirnames works.
func (k Key) ReadSubKeyNames(n int) ([]string, error) {
ki, err := k.Stat()
if err != nil {
return nil, err
}
names := make([]string, 0, ki.SubKeyCount)
buf := make([]uint16, ki.MaxSubKeyLen+1) // extra room for terminating zero byte
loopItems:
for i := uint32(0); ; i++ {
if n > 0 {
if len(names) == n {
return names, nil
}
}
l := uint32(len(buf))
for {
err := syscall.RegEnumKeyEx(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil)
if err == nil {
break
}
if err == syscall.ERROR_MORE_DATA {
// Double buffer size and try again.
l = uint32(2 * len(buf))
buf = make([]uint16, l)
continue
}
if err == _ERROR_NO_MORE_ITEMS {
break loopItems
}
return names, err
}
names = append(names, syscall.UTF16ToString(buf[:l]))
}
if n > len(names) {
return names, io.EOF
}
return names, nil
}
// CreateKey creates a key named path under open key k.
// CreateKey returns the new key and a boolean flag that reports
// whether the key already existed.
// The access parameter specifies the access rights for the key
// to be created.
func CreateKey(k Key, path string, access uint32) (newk Key, openedExisting bool, err error) {
var h syscall.Handle
var d uint32
err = regCreateKeyEx(syscall.Handle(k), syscall.StringToUTF16Ptr(path),
0, nil, _REG_OPTION_NON_VOLATILE, access, nil, &h, &d)
if err != nil {
return 0, false, err
}
return Key(h), d == _REG_OPENED_EXISTING_KEY, nil
}
// DeleteKey deletes the subkey path of key k and its values.
func DeleteKey(k Key, path string) error {
return regDeleteKey(syscall.Handle(k), syscall.StringToUTF16Ptr(path))
}
// A KeyInfo describes the statistics of a key. It is returned by Stat.
type KeyInfo struct {
SubKeyCount uint32
MaxSubKeyLen uint32 // size of the key's subkey with the longest name, in Unicode characters, not including the terminating zero byte
ValueCount uint32
MaxValueNameLen uint32 // size of the key's longest value name, in Unicode characters, not including the terminating zero byte
MaxValueLen uint32 // longest data component among the key's values, in bytes
lastWriteTime syscall.Filetime
}
// ModTime returns the key's last write time.
func (ki *KeyInfo) ModTime() time.Time {
return time.Unix(0, ki.lastWriteTime.Nanoseconds())
}
// Stat retrieves information about the open key k.
func (k Key) Stat() (*KeyInfo, error) {
var ki KeyInfo
err := syscall.RegQueryInfoKey(syscall.Handle(k), nil, nil, nil,
&ki.SubKeyCount, &ki.MaxSubKeyLen, nil, &ki.ValueCount,
&ki.MaxValueNameLen, &ki.MaxValueLen, nil, &ki.lastWriteTime)
if err != nil {
return nil, err
}
return &ki, nil
}

View File

@@ -1,7 +0,0 @@
// Copyright 2015 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.
package registry
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall.go

View File

@@ -1,32 +0,0 @@
// Copyright 2015 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 registry
import "syscall"
const (
_REG_OPTION_NON_VOLATILE = 0
_REG_CREATED_NEW_KEY = 1
_REG_OPENED_EXISTING_KEY = 2
_ERROR_NO_MORE_ITEMS syscall.Errno = 259
)
func LoadRegLoadMUIString() error {
return procRegLoadMUIStringW.Find()
}
//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
//sys regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) = advapi32.RegDeleteKeyW
//sys regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) = advapi32.RegSetValueExW
//sys regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegEnumValueW
//sys regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) = advapi32.RegDeleteValueW
//sys regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) = advapi32.RegLoadMUIStringW
//sys regConnectRegistry(machinename *uint16, key syscall.Handle, result *syscall.Handle) (regerrno error) = advapi32.RegConnectRegistryW
//sys expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) = kernel32.ExpandEnvironmentStringsW

View File

@@ -1,384 +0,0 @@
// Copyright 2015 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 registry
import (
"errors"
"io"
"syscall"
"unicode/utf16"
"unsafe"
)
const (
// Registry value types.
NONE = 0
SZ = 1
EXPAND_SZ = 2
BINARY = 3
DWORD = 4
DWORD_BIG_ENDIAN = 5
LINK = 6
MULTI_SZ = 7
RESOURCE_LIST = 8
FULL_RESOURCE_DESCRIPTOR = 9
RESOURCE_REQUIREMENTS_LIST = 10
QWORD = 11
)
var (
// ErrShortBuffer is returned when the buffer was too short for the operation.
ErrShortBuffer = syscall.ERROR_MORE_DATA
// ErrNotExist is returned when a registry key or value does not exist.
ErrNotExist = syscall.ERROR_FILE_NOT_FOUND
// ErrUnexpectedType is returned by Get*Value when the value's type was unexpected.
ErrUnexpectedType = errors.New("unexpected key value type")
)
// GetValue retrieves the type and data for the specified value associated
// with an open key k. It fills up buffer buf and returns the retrieved
// byte count n. If buf is too small to fit the stored value it returns
// ErrShortBuffer error along with the required buffer size n.
// If no buffer is provided, it returns true and actual buffer size n.
// If no buffer is provided, GetValue returns the value's type only.
// If the value does not exist, the error returned is ErrNotExist.
//
// GetValue is a low level function. If value's type is known, use the appropriate
// Get*Value function instead.
func (k Key) GetValue(name string, buf []byte) (n int, valtype uint32, err error) {
pname, err := syscall.UTF16PtrFromString(name)
if err != nil {
return 0, 0, err
}
var pbuf *byte
if len(buf) > 0 {
pbuf = (*byte)(unsafe.Pointer(&buf[0]))
}
l := uint32(len(buf))
err = syscall.RegQueryValueEx(syscall.Handle(k), pname, nil, &valtype, pbuf, &l)
if err != nil {
return int(l), valtype, err
}
return int(l), valtype, nil
}
func (k Key) getValue(name string, buf []byte) (date []byte, valtype uint32, err error) {
p, err := syscall.UTF16PtrFromString(name)
if err != nil {
return nil, 0, err
}
var t uint32
n := uint32(len(buf))
for {
err = syscall.RegQueryValueEx(syscall.Handle(k), p, nil, &t, (*byte)(unsafe.Pointer(&buf[0])), &n)
if err == nil {
return buf[:n], t, nil
}
if err != syscall.ERROR_MORE_DATA {
return nil, 0, err
}
if n <= uint32(len(buf)) {
return nil, 0, err
}
buf = make([]byte, n)
}
}
// GetStringValue retrieves the string value for the specified
// value name associated with an open key k. It also returns the value's type.
// If value does not exist, GetStringValue returns ErrNotExist.
// If value is not SZ or EXPAND_SZ, it will return the correct value
// type and ErrUnexpectedType.
func (k Key) GetStringValue(name string) (val string, valtype uint32, err error) {
data, typ, err2 := k.getValue(name, make([]byte, 64))
if err2 != nil {
return "", typ, err2
}
switch typ {
case SZ, EXPAND_SZ:
default:
return "", typ, ErrUnexpectedType
}
if len(data) == 0 {
return "", typ, nil
}
u := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[:]
return syscall.UTF16ToString(u), typ, nil
}
// GetMUIStringValue retrieves the localized string value for
// the specified value name associated with an open key k.
// If the value name doesn't exist or the localized string value
// can't be resolved, GetMUIStringValue returns ErrNotExist.
// GetMUIStringValue panics if the system doesn't support
// regLoadMUIString; use LoadRegLoadMUIString to check if
// regLoadMUIString is supported before calling this function.
func (k Key) GetMUIStringValue(name string) (string, error) {
pname, err := syscall.UTF16PtrFromString(name)
if err != nil {
return "", err
}
buf := make([]uint16, 1024)
var buflen uint32
var pdir *uint16
err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
if err == syscall.ERROR_FILE_NOT_FOUND { // Try fallback path
// Try to resolve the string value using the system directory as
// a DLL search path; this assumes the string value is of the form
// @[path]\dllname,-strID but with no path given, e.g. @tzres.dll,-320.
// This approach works with tzres.dll but may have to be revised
// in the future to allow callers to provide custom search paths.
var s string
s, err = ExpandString("%SystemRoot%\\system32\\")
if err != nil {
return "", err
}
pdir, err = syscall.UTF16PtrFromString(s)
if err != nil {
return "", err
}
err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
}
for err == syscall.ERROR_MORE_DATA { // Grow buffer if needed
if buflen <= uint32(len(buf)) {
break // Buffer not growing, assume race; break
}
buf = make([]uint16, buflen)
err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
}
if err != nil {
return "", err
}
return syscall.UTF16ToString(buf), nil
}
// ExpandString expands environment-variable strings and replaces
// them with the values defined for the current user.
// Use ExpandString to expand EXPAND_SZ strings.
func ExpandString(value string) (string, error) {
if value == "" {
return "", nil
}
p, err := syscall.UTF16PtrFromString(value)
if err != nil {
return "", err
}
r := make([]uint16, 100)
for {
n, err := expandEnvironmentStrings(p, &r[0], uint32(len(r)))
if err != nil {
return "", err
}
if n <= uint32(len(r)) {
u := (*[1 << 29]uint16)(unsafe.Pointer(&r[0]))[:]
return syscall.UTF16ToString(u), nil
}
r = make([]uint16, n)
}
}
// GetStringsValue retrieves the []string value for the specified
// value name associated with an open key k. It also returns the value's type.
// If value does not exist, GetStringsValue returns ErrNotExist.
// If value is not MULTI_SZ, it will return the correct value
// type and ErrUnexpectedType.
func (k Key) GetStringsValue(name string) (val []string, valtype uint32, err error) {
data, typ, err2 := k.getValue(name, make([]byte, 64))
if err2 != nil {
return nil, typ, err2
}
if typ != MULTI_SZ {
return nil, typ, ErrUnexpectedType
}
if len(data) == 0 {
return nil, typ, nil
}
p := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[:len(data)/2]
if len(p) == 0 {
return nil, typ, nil
}
if p[len(p)-1] == 0 {
p = p[:len(p)-1] // remove terminating null
}
val = make([]string, 0, 5)
from := 0
for i, c := range p {
if c == 0 {
val = append(val, string(utf16.Decode(p[from:i])))
from = i + 1
}
}
return val, typ, nil
}
// GetIntegerValue retrieves the integer value for the specified
// value name associated with an open key k. It also returns the value's type.
// If value does not exist, GetIntegerValue returns ErrNotExist.
// If value is not DWORD or QWORD, it will return the correct value
// type and ErrUnexpectedType.
func (k Key) GetIntegerValue(name string) (val uint64, valtype uint32, err error) {
data, typ, err2 := k.getValue(name, make([]byte, 8))
if err2 != nil {
return 0, typ, err2
}
switch typ {
case DWORD:
if len(data) != 4 {
return 0, typ, errors.New("DWORD value is not 4 bytes long")
}
return uint64(*(*uint32)(unsafe.Pointer(&data[0]))), DWORD, nil
case QWORD:
if len(data) != 8 {
return 0, typ, errors.New("QWORD value is not 8 bytes long")
}
return uint64(*(*uint64)(unsafe.Pointer(&data[0]))), QWORD, nil
default:
return 0, typ, ErrUnexpectedType
}
}
// GetBinaryValue retrieves the binary value for the specified
// value name associated with an open key k. It also returns the value's type.
// If value does not exist, GetBinaryValue returns ErrNotExist.
// If value is not BINARY, it will return the correct value
// type and ErrUnexpectedType.
func (k Key) GetBinaryValue(name string) (val []byte, valtype uint32, err error) {
data, typ, err2 := k.getValue(name, make([]byte, 64))
if err2 != nil {
return nil, typ, err2
}
if typ != BINARY {
return nil, typ, ErrUnexpectedType
}
return data, typ, nil
}
func (k Key) setValue(name string, valtype uint32, data []byte) error {
p, err := syscall.UTF16PtrFromString(name)
if err != nil {
return err
}
if len(data) == 0 {
return regSetValueEx(syscall.Handle(k), p, 0, valtype, nil, 0)
}
return regSetValueEx(syscall.Handle(k), p, 0, valtype, &data[0], uint32(len(data)))
}
// SetDWordValue sets the data and type of a name value
// under key k to value and DWORD.
func (k Key) SetDWordValue(name string, value uint32) error {
return k.setValue(name, DWORD, (*[4]byte)(unsafe.Pointer(&value))[:])
}
// SetQWordValue sets the data and type of a name value
// under key k to value and QWORD.
func (k Key) SetQWordValue(name string, value uint64) error {
return k.setValue(name, QWORD, (*[8]byte)(unsafe.Pointer(&value))[:])
}
func (k Key) setStringValue(name string, valtype uint32, value string) error {
v, err := syscall.UTF16FromString(value)
if err != nil {
return err
}
buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[:len(v)*2]
return k.setValue(name, valtype, buf)
}
// SetStringValue sets the data and type of a name value
// under key k to value and SZ. The value must not contain a zero byte.
func (k Key) SetStringValue(name, value string) error {
return k.setStringValue(name, SZ, value)
}
// SetExpandStringValue sets the data and type of a name value
// under key k to value and EXPAND_SZ. The value must not contain a zero byte.
func (k Key) SetExpandStringValue(name, value string) error {
return k.setStringValue(name, EXPAND_SZ, value)
}
// SetStringsValue sets the data and type of a name value
// under key k to value and MULTI_SZ. The value strings
// must not contain a zero byte.
func (k Key) SetStringsValue(name string, value []string) error {
ss := ""
for _, s := range value {
for i := 0; i < len(s); i++ {
if s[i] == 0 {
return errors.New("string cannot have 0 inside")
}
}
ss += s + "\x00"
}
v := utf16.Encode([]rune(ss + "\x00"))
buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[:len(v)*2]
return k.setValue(name, MULTI_SZ, buf)
}
// SetBinaryValue sets the data and type of a name value
// under key k to value and BINARY.
func (k Key) SetBinaryValue(name string, value []byte) error {
return k.setValue(name, BINARY, value)
}
// DeleteValue removes a named value from the key k.
func (k Key) DeleteValue(name string) error {
return regDeleteValue(syscall.Handle(k), syscall.StringToUTF16Ptr(name))
}
// ReadValueNames returns the value names of key k.
// The parameter n controls the number of returned names,
// analogous to the way os.File.Readdirnames works.
func (k Key) ReadValueNames(n int) ([]string, error) {
ki, err := k.Stat()
if err != nil {
return nil, err
}
names := make([]string, 0, ki.ValueCount)
buf := make([]uint16, ki.MaxValueNameLen+1) // extra room for terminating null character
loopItems:
for i := uint32(0); ; i++ {
if n > 0 {
if len(names) == n {
return names, nil
}
}
l := uint32(len(buf))
for {
err := regEnumValue(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil)
if err == nil {
break
}
if err == syscall.ERROR_MORE_DATA {
// Double buffer size and try again.
l = uint32(2 * len(buf))
buf = make([]uint16, l)
continue
}
if err == _ERROR_NO_MORE_ITEMS {
break loopItems
}
return names, err
}
names = append(names, syscall.UTF16ToString(buf[:l]))
}
if n > len(names) {
return names, io.EOF
}
return names, nil
}

View File

@@ -1,120 +0,0 @@
// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
package registry
import (
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
var _ unsafe.Pointer
// Do the interface allocations only once for common
// Errno values.
const (
errnoERROR_IO_PENDING = 997
)
var (
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
)
// errnoErr returns common boxed Errno values, to prevent
// allocations at runtime.
func errnoErr(e syscall.Errno) error {
switch e {
case 0:
return nil
case errnoERROR_IO_PENDING:
return errERROR_IO_PENDING
}
// TODO: add more here, after collecting data on the common
// error values see on Windows. (perhaps when running
// all.bat?)
return e
}
var (
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
procRegCreateKeyExW = modadvapi32.NewProc("RegCreateKeyExW")
procRegDeleteKeyW = modadvapi32.NewProc("RegDeleteKeyW")
procRegSetValueExW = modadvapi32.NewProc("RegSetValueExW")
procRegEnumValueW = modadvapi32.NewProc("RegEnumValueW")
procRegDeleteValueW = modadvapi32.NewProc("RegDeleteValueW")
procRegLoadMUIStringW = modadvapi32.NewProc("RegLoadMUIStringW")
procRegConnectRegistryW = modadvapi32.NewProc("RegConnectRegistryW")
procExpandEnvironmentStringsW = modkernel32.NewProc("ExpandEnvironmentStringsW")
)
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) {
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)))
if r0 != 0 {
regerrno = syscall.Errno(r0)
}
return
}
func regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) {
r0, _, _ := syscall.Syscall(procRegDeleteKeyW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(subkey)), 0)
if r0 != 0 {
regerrno = syscall.Errno(r0)
}
return
}
func regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) {
r0, _, _ := syscall.Syscall6(procRegSetValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(valueName)), uintptr(reserved), uintptr(vtype), uintptr(unsafe.Pointer(buf)), uintptr(bufsize))
if r0 != 0 {
regerrno = syscall.Errno(r0)
}
return
}
func regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) {
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)
if r0 != 0 {
regerrno = syscall.Errno(r0)
}
return
}
func regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) {
r0, _, _ := syscall.Syscall(procRegDeleteValueW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(name)), 0)
if r0 != 0 {
regerrno = syscall.Errno(r0)
}
return
}
func regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) {
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)
if r0 != 0 {
regerrno = syscall.Errno(r0)
}
return
}
func regConnectRegistry(machinename *uint16, key syscall.Handle, result *syscall.Handle) (regerrno error) {
r0, _, _ := syscall.Syscall(procRegConnectRegistryW.Addr(), 3, uintptr(unsafe.Pointer(machinename)), uintptr(key), uintptr(unsafe.Pointer(result)))
if r0 != 0 {
regerrno = syscall.Errno(r0)
}
return
}
func expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) {
r0, _, e1 := syscall.Syscall(procExpandEnvironmentStringsW.Addr(), 3, uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(size))
n = uint32(r0)
if n == 0 {
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
}
return
}

View File

@@ -296,6 +296,7 @@ const (
TOKEN_ADJUST_PRIVILEGES
TOKEN_ADJUST_GROUPS
TOKEN_ADJUST_DEFAULT
TOKEN_ADJUST_SESSIONID
TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
TOKEN_ASSIGN_PRIMARY |
@@ -305,7 +306,8 @@ const (
TOKEN_QUERY_SOURCE |
TOKEN_ADJUST_PRIVILEGES |
TOKEN_ADJUST_GROUPS |
TOKEN_ADJUST_DEFAULT
TOKEN_ADJUST_DEFAULT |
TOKEN_ADJUST_SESSIONID
TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY
TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
TOKEN_ADJUST_PRIVILEGES |

View File

@@ -43,6 +43,11 @@ const (
SC_STATUS_PROCESS_INFO = 0
SC_ACTION_NONE = 0
SC_ACTION_RESTART = 1
SC_ACTION_REBOOT = 2
SC_ACTION_RUN_COMMAND = 3
SERVICE_STOPPED = 1
SERVICE_START_PENDING = 2
SERVICE_STOP_PENDING = 3
@@ -148,6 +153,19 @@ type ENUM_SERVICE_STATUS_PROCESS struct {
ServiceStatusProcess SERVICE_STATUS_PROCESS
}
type SERVICE_FAILURE_ACTIONS struct {
ResetPeriod uint32
RebootMsg *uint16
Command *uint16
ActionsCount uint32
Actions *SC_ACTION
}
type SC_ACTION struct {
Type uint32
Delay uint32
}
//sys CloseServiceHandle(handle Handle) (err error) = advapi32.CloseServiceHandle
//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
//sys OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenServiceW
@@ -162,3 +180,4 @@ type ENUM_SERVICE_STATUS_PROCESS struct {
//sys ChangeServiceConfig2(service Handle, infoLevel uint32, info *byte) (err error) = advapi32.ChangeServiceConfig2W
//sys QueryServiceConfig2(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceConfig2W
//sys EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serviceState uint32, services *byte, bufSize uint32, bytesNeeded *uint32, servicesReturned *uint32, resumeHandle *uint32, groupName *uint16) (err error) = advapi32.EnumServicesStatusExW
//sys QueryServiceStatusEx(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) = advapi32.QueryServiceStatusEx

View File

@@ -1,56 +0,0 @@
// 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)
}

View File

@@ -1,45 +0,0 @@
// 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
}

View File

@@ -1,48 +0,0 @@
// 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
}

View File

@@ -1,80 +0,0 @@
// 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)
}

View File

@@ -1,70 +0,0 @@
// 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)
}

View File

@@ -1,22 +0,0 @@
// 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)
}

View File

@@ -1,92 +0,0 @@
// 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
}

View File

@@ -1,76 +0,0 @@
// 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
}

View File

@@ -1,62 +0,0 @@
// 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
}

View File

@@ -1,82 +0,0 @@
// 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))
}

View File

@@ -1,24 +0,0 @@
// 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;
}

View File

@@ -1,11 +0,0 @@
// 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)

View File

@@ -1,31 +0,0 @@
// 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)
}

View File

@@ -1,139 +0,0 @@
// 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)
}

View File

@@ -1,162 +0,0 @@
// 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
}

View File

@@ -1,72 +0,0 @@
// 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
}

View File

@@ -1,62 +0,0 @@
// 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
}

View File

@@ -1,363 +0,0 @@
// 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)
}

View File

@@ -1,68 +0,0 @@
// 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

View File

@@ -1,42 +0,0 @@
// 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

View File

@@ -11,11 +11,14 @@
// system, set $GOOS and $GOARCH to the desired system. For example, if
// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS
// to freebsd and $GOARCH to arm.
//
// The primary use of this package is inside other packages that provide a more
// portable interface to the system, such as "os", "time" and "net". Use
// those packages rather than this one if you can.
//
// For details of the functions and data types in this package consult
// the manuals for the appropriate operating system.
//
// These calls return err == nil to indicate success; otherwise
// err represents an operating system error describing the failure and
// holds a value of type syscall.Errno.

View File

@@ -112,12 +112,14 @@ func Getpagesize() int { return 4096 }
// NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention.
// This is useful when interoperating with Windows code requiring callbacks.
// The argument is expected to be a function with with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr.
func NewCallback(fn interface{}) uintptr {
return syscall.NewCallback(fn)
}
// NewCallbackCDecl converts a Go function to a function pointer conforming to the cdecl calling convention.
// This is useful when interoperating with Windows code requiring callbacks.
// The argument is expected to be a function with with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr.
func NewCallbackCDecl(fn interface{}) uintptr {
return syscall.NewCallbackCDecl(fn)
}
@@ -653,7 +655,7 @@ type RawSockaddr struct {
type RawSockaddrAny struct {
Addr RawSockaddr
Pad [96]int8
Pad [100]int8
}
type Sockaddr interface {
@@ -702,19 +704,69 @@ func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) {
return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
}
type RawSockaddrUnix struct {
Family uint16
Path [UNIX_PATH_MAX]int8
}
type SockaddrUnix struct {
Name string
raw RawSockaddrUnix
}
func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) {
// TODO(brainman): implement SockaddrUnix.sockaddr()
return nil, 0, syscall.EWINDOWS
name := sa.Name
n := len(name)
if n > len(sa.raw.Path) {
return nil, 0, syscall.EINVAL
}
if n == len(sa.raw.Path) && name[0] != '@' {
return nil, 0, syscall.EINVAL
}
sa.raw.Family = AF_UNIX
for i := 0; i < n; i++ {
sa.raw.Path[i] = int8(name[i])
}
// length is family (uint16), name, NUL.
sl := int32(2)
if n > 0 {
sl += int32(n) + 1
}
if sa.raw.Path[0] == '@' {
sa.raw.Path[0] = 0
// Don't count trailing NUL for abstract address.
sl--
}
return unsafe.Pointer(&sa.raw), sl, nil
}
func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) {
switch rsa.Addr.Family {
case AF_UNIX:
return nil, syscall.EWINDOWS
pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
sa := new(SockaddrUnix)
if pp.Path[0] == 0 {
// "Abstract" Unix domain socket.
// Rewrite leading NUL as @ for textual display.
// (This is the standard convention.)
// Not friendly to overwrite in place,
// but the callers below don't care.
pp.Path[0] = '@'
}
// Assume path ends at NUL.
// This is not technically the Linux semantics for
// abstract Unix domain sockets--they are supposed
// to be uninterpreted fixed-size binary blobs--but
// everyone uses this convention.
n := 0
for n < len(pp.Path) && pp.Path[n] != 0 {
n++
}
bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
sa.Name = string(bytes)
return sa, nil
case AF_INET:
pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))

View File

@@ -94,16 +94,29 @@ const (
FILE_APPEND_DATA = 0x00000004
FILE_WRITE_ATTRIBUTES = 0x00000100
FILE_SHARE_READ = 0x00000001
FILE_SHARE_WRITE = 0x00000002
FILE_SHARE_DELETE = 0x00000004
FILE_ATTRIBUTE_READONLY = 0x00000001
FILE_ATTRIBUTE_HIDDEN = 0x00000002
FILE_ATTRIBUTE_SYSTEM = 0x00000004
FILE_ATTRIBUTE_DIRECTORY = 0x00000010
FILE_ATTRIBUTE_ARCHIVE = 0x00000020
FILE_ATTRIBUTE_NORMAL = 0x00000080
FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400
FILE_SHARE_READ = 0x00000001
FILE_SHARE_WRITE = 0x00000002
FILE_SHARE_DELETE = 0x00000004
FILE_ATTRIBUTE_READONLY = 0x00000001
FILE_ATTRIBUTE_HIDDEN = 0x00000002
FILE_ATTRIBUTE_SYSTEM = 0x00000004
FILE_ATTRIBUTE_DIRECTORY = 0x00000010
FILE_ATTRIBUTE_ARCHIVE = 0x00000020
FILE_ATTRIBUTE_DEVICE = 0x00000040
FILE_ATTRIBUTE_NORMAL = 0x00000080
FILE_ATTRIBUTE_TEMPORARY = 0x00000100
FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200
FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400
FILE_ATTRIBUTE_COMPRESSED = 0x00000800
FILE_ATTRIBUTE_OFFLINE = 0x00001000
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000
FILE_ATTRIBUTE_ENCRYPTED = 0x00004000
FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x00008000
FILE_ATTRIBUTE_VIRTUAL = 0x00010000
FILE_ATTRIBUTE_NO_SCRUB_DATA = 0x00020000
FILE_ATTRIBUTE_RECALL_ON_OPEN = 0x00040000
FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS = 0x00400000
INVALID_FILE_ATTRIBUTES = 0xffffffff
@@ -257,15 +270,87 @@ const (
USAGE_MATCH_TYPE_AND = 0
USAGE_MATCH_TYPE_OR = 1
/* msgAndCertEncodingType values for CertOpenStore function */
X509_ASN_ENCODING = 0x00000001
PKCS_7_ASN_ENCODING = 0x00010000
CERT_STORE_PROV_MEMORY = 2
CERT_STORE_ADD_ALWAYS = 4
/* storeProvider values for CertOpenStore function */
CERT_STORE_PROV_MSG = 1
CERT_STORE_PROV_MEMORY = 2
CERT_STORE_PROV_FILE = 3
CERT_STORE_PROV_REG = 4
CERT_STORE_PROV_PKCS7 = 5
CERT_STORE_PROV_SERIALIZED = 6
CERT_STORE_PROV_FILENAME_A = 7
CERT_STORE_PROV_FILENAME_W = 8
CERT_STORE_PROV_FILENAME = CERT_STORE_PROV_FILENAME_W
CERT_STORE_PROV_SYSTEM_A = 9
CERT_STORE_PROV_SYSTEM_W = 10
CERT_STORE_PROV_SYSTEM = CERT_STORE_PROV_SYSTEM_W
CERT_STORE_PROV_COLLECTION = 11
CERT_STORE_PROV_SYSTEM_REGISTRY_A = 12
CERT_STORE_PROV_SYSTEM_REGISTRY_W = 13
CERT_STORE_PROV_SYSTEM_REGISTRY = CERT_STORE_PROV_SYSTEM_REGISTRY_W
CERT_STORE_PROV_PHYSICAL_W = 14
CERT_STORE_PROV_PHYSICAL = CERT_STORE_PROV_PHYSICAL_W
CERT_STORE_PROV_SMART_CARD_W = 15
CERT_STORE_PROV_SMART_CARD = CERT_STORE_PROV_SMART_CARD_W
CERT_STORE_PROV_LDAP_W = 16
CERT_STORE_PROV_LDAP = CERT_STORE_PROV_LDAP_W
CERT_STORE_PROV_PKCS12 = 17
/* store characteristics (low WORD of flag) for CertOpenStore function */
CERT_STORE_NO_CRYPT_RELEASE_FLAG = 0x00000001
CERT_STORE_SET_LOCALIZED_NAME_FLAG = 0x00000002
CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG = 0x00000004
CERT_STORE_DELETE_FLAG = 0x00000010
CERT_STORE_UNSAFE_PHYSICAL_FLAG = 0x00000020
CERT_STORE_SHARE_STORE_FLAG = 0x00000040
CERT_STORE_SHARE_CONTEXT_FLAG = 0x00000080
CERT_STORE_MANIFOLD_FLAG = 0x00000100
CERT_STORE_ENUM_ARCHIVED_FLAG = 0x00000200
CERT_STORE_UPDATE_KEYID_FLAG = 0x00000400
CERT_STORE_BACKUP_RESTORE_FLAG = 0x00000800
CERT_STORE_MAXIMUM_ALLOWED_FLAG = 0x00001000
CERT_STORE_CREATE_NEW_FLAG = 0x00002000
CERT_STORE_OPEN_EXISTING_FLAG = 0x00004000
CERT_STORE_READONLY_FLAG = 0x00008000
/* store locations (high WORD of flag) for CertOpenStore function */
CERT_SYSTEM_STORE_CURRENT_USER = 0x00010000
CERT_SYSTEM_STORE_LOCAL_MACHINE = 0x00020000
CERT_SYSTEM_STORE_CURRENT_SERVICE = 0x00040000
CERT_SYSTEM_STORE_SERVICES = 0x00050000
CERT_SYSTEM_STORE_USERS = 0x00060000
CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY = 0x00070000
CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY = 0x00080000
CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE = 0x00090000
CERT_SYSTEM_STORE_UNPROTECTED_FLAG = 0x40000000
CERT_SYSTEM_STORE_RELOCATE_FLAG = 0x80000000
/* Miscellaneous high-WORD flags for CertOpenStore function */
CERT_REGISTRY_STORE_REMOTE_FLAG = 0x00010000
CERT_REGISTRY_STORE_SERIALIZED_FLAG = 0x00020000
CERT_REGISTRY_STORE_ROAMING_FLAG = 0x00040000
CERT_REGISTRY_STORE_MY_IE_DIRTY_FLAG = 0x00080000
CERT_REGISTRY_STORE_LM_GPT_FLAG = 0x01000000
CERT_REGISTRY_STORE_CLIENT_GPT_FLAG = 0x80000000
CERT_FILE_STORE_COMMIT_ENABLE_FLAG = 0x00010000
CERT_LDAP_STORE_SIGN_FLAG = 0x00010000
CERT_LDAP_STORE_AREC_EXCLUSIVE_FLAG = 0x00020000
CERT_LDAP_STORE_OPENED_FLAG = 0x00040000
CERT_LDAP_STORE_UNBIND_FLAG = 0x00080000
/* addDisposition values for CertAddCertificateContextToStore function */
CERT_STORE_ADD_NEW = 1
CERT_STORE_ADD_USE_EXISTING = 2
CERT_STORE_ADD_REPLACE_EXISTING = 3
CERT_STORE_ADD_ALWAYS = 4
CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES = 5
CERT_STORE_ADD_NEWER = 6
CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES = 7
/* ErrorStatus values for CertTrustStatus struct */
CERT_TRUST_NO_ERROR = 0x00000000
CERT_TRUST_IS_NOT_TIME_VALID = 0x00000001
CERT_TRUST_IS_REVOKED = 0x00000004
@@ -282,11 +367,31 @@ const (
CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT = 0x00002000
CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT = 0x00004000
CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT = 0x00008000
CERT_TRUST_IS_PARTIAL_CHAIN = 0x00010000
CERT_TRUST_CTL_IS_NOT_TIME_VALID = 0x00020000
CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID = 0x00040000
CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE = 0x00080000
CERT_TRUST_HAS_WEAK_SIGNATURE = 0x00100000
CERT_TRUST_IS_OFFLINE_REVOCATION = 0x01000000
CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY = 0x02000000
CERT_TRUST_IS_EXPLICIT_DISTRUST = 0x04000000
CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT = 0x08000000
/* InfoStatus values for CertTrustStatus struct */
CERT_TRUST_HAS_EXACT_MATCH_ISSUER = 0x00000001
CERT_TRUST_HAS_KEY_MATCH_ISSUER = 0x00000002
CERT_TRUST_HAS_NAME_MATCH_ISSUER = 0x00000004
CERT_TRUST_IS_SELF_SIGNED = 0x00000008
CERT_TRUST_HAS_PREFERRED_ISSUER = 0x00000100
CERT_TRUST_HAS_ISSUANCE_CHAIN_POLICY = 0x00000400
CERT_TRUST_HAS_VALID_NAME_CONSTRAINTS = 0x00000400
CERT_TRUST_IS_PEER_TRUSTED = 0x00000800
CERT_TRUST_HAS_CRL_VALIDITY_EXTENDED = 0x00001000
CERT_TRUST_IS_FROM_EXCLUSIVE_TRUST_STORE = 0x00002000
CERT_TRUST_IS_CA_TRUSTED = 0x00004000
CERT_TRUST_IS_COMPLEX_CHAIN = 0x00010000
/* policyOID values for CertVerifyCertificateChainPolicy function */
CERT_CHAIN_POLICY_BASE = 1
CERT_CHAIN_POLICY_AUTHENTICODE = 2
CERT_CHAIN_POLICY_AUTHENTICODE_TS = 3
@@ -295,6 +400,7 @@ const (
CERT_CHAIN_POLICY_NT_AUTH = 6
CERT_CHAIN_POLICY_MICROSOFT_ROOT = 7
CERT_CHAIN_POLICY_EV = 8
CERT_CHAIN_POLICY_SSL_F12 = 9
CERT_E_EXPIRED = 0x800B0101
CERT_E_ROLE = 0x800B0103
@@ -302,8 +408,16 @@ const (
CERT_E_UNTRUSTEDROOT = 0x800B0109
CERT_E_CN_NO_MATCH = 0x800B010F
/* AuthType values for SSLExtraCertChainPolicyPara struct */
AUTHTYPE_CLIENT = 1
AUTHTYPE_SERVER = 2
/* Checks values for SSLExtraCertChainPolicyPara struct */
SECURITY_FLAG_IGNORE_REVOCATION = 0x00000080
SECURITY_FLAG_IGNORE_UNKNOWN_CA = 0x00000100
SECURITY_FLAG_IGNORE_WRONG_USAGE = 0x00000200
SECURITY_FLAG_IGNORE_CERT_CN_INVALID = 0x00001000
SECURITY_FLAG_IGNORE_CERT_DATE_INVALID = 0x00002000
)
var (
@@ -312,6 +426,14 @@ var (
OID_SGC_NETSCAPE = []byte("2.16.840.1.113730.4.1\x00")
)
// Pointer represents a pointer to an arbitrary Windows type.
//
// Pointer-typed fields may point to one of many different types. It's
// up to the caller to provide a pointer to the appropriate type, cast
// to Pointer. The caller must obey the unsafe.Pointer rules while
// doing so.
type Pointer *struct{}
// Invented values to support what package os expects.
type Timeval struct {
Sec int32
@@ -880,11 +1002,15 @@ type MibIfRow struct {
Descr [MAXLEN_IFDESCR]byte
}
type CertInfo struct {
// Not implemented
}
type CertContext struct {
EncodingType uint32
EncodedCert *byte
Length uint32
CertInfo uintptr
CertInfo *CertInfo
Store Handle
}
@@ -899,12 +1025,16 @@ type CertChainContext struct {
RevocationFreshnessTime uint32
}
type CertTrustListInfo struct {
// Not implemented
}
type CertSimpleChain struct {
Size uint32
TrustStatus CertTrustStatus
NumElements uint32
Elements **CertChainElement
TrustListInfo uintptr
TrustListInfo *CertTrustListInfo
HasRevocationFreshnessTime uint32
RevocationFreshnessTime uint32
}
@@ -919,14 +1049,18 @@ type CertChainElement struct {
ExtendedErrorInfo *uint16
}
type CertRevocationCrlInfo struct {
// Not implemented
}
type CertRevocationInfo struct {
Size uint32
RevocationResult uint32
RevocationOid *byte
OidSpecificInfo uintptr
OidSpecificInfo Pointer
HasFreshnessTime uint32
FreshnessTime uint32
CrlInfo uintptr // *CertRevocationCrlInfo
CrlInfo *CertRevocationCrlInfo
}
type CertTrustStatus struct {
@@ -957,7 +1091,7 @@ type CertChainPara struct {
type CertChainPolicyPara struct {
Size uint32
Flags uint32
ExtraPolicyPara uintptr
ExtraPolicyPara Pointer
}
type SSLExtraCertChainPolicyPara struct {
@@ -972,7 +1106,7 @@ type CertChainPolicyStatus struct {
Error uint32
ChainIndex uint32
ElementIndex uint32
ExtraPolicyStatus uintptr
ExtraPolicyStatus Pointer
}
const (
@@ -1319,7 +1453,7 @@ type SmallRect struct {
Bottom int16
}
// Used with GetConsoleScreenBuffer to retreive information about a console
// Used with GetConsoleScreenBuffer to retrieve information about a console
// screen buffer. See
// https://docs.microsoft.com/en-us/windows/console/console-screen-buffer-info-str
// for details.
@@ -1331,3 +1465,5 @@ type ConsoleScreenBufferInfo struct {
Window SmallRect
MaximumWindowSize Coord
}
const UNIX_PATH_MAX = 108 // defined in afunix.h

22
vendor/golang.org/x/sys/windows/types_windows_arm.go generated vendored Normal file
View File

@@ -0,0 +1,22 @@
// Copyright 2018 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.
package windows
type WSAData struct {
Version uint16
HighVersion uint16
Description [WSADESCRIPTION_LEN + 1]byte
SystemStatus [WSASYS_STATUS_LEN + 1]byte
MaxSockets uint16
MaxUdpDg uint16
VendorInfo *byte
}
type Servent struct {
Name *byte
Aliases **byte
Port uint16
Proto *byte
}

View File

@@ -1,4 +1,4 @@
// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
// Code generated by 'go generate'; DO NOT EDIT.
package windows
@@ -65,6 +65,7 @@ var (
procChangeServiceConfig2W = modadvapi32.NewProc("ChangeServiceConfig2W")
procQueryServiceConfig2W = modadvapi32.NewProc("QueryServiceConfig2W")
procEnumServicesStatusExW = modadvapi32.NewProc("EnumServicesStatusExW")
procQueryServiceStatusEx = modadvapi32.NewProc("QueryServiceStatusEx")
procGetLastError = modkernel32.NewProc("GetLastError")
procLoadLibraryW = modkernel32.NewProc("LoadLibraryW")
procLoadLibraryExW = modkernel32.NewProc("LoadLibraryExW")
@@ -472,6 +473,18 @@ func EnumServicesStatusEx(mgr Handle, infoLevel uint32, serviceType uint32, serv
return
}
func QueryServiceStatusEx(service Handle, infoLevel uint32, buff *byte, buffSize uint32, bytesNeeded *uint32) (err error) {
r1, _, e1 := syscall.Syscall6(procQueryServiceStatusEx.Addr(), 5, uintptr(service), uintptr(infoLevel), uintptr(unsafe.Pointer(buff)), uintptr(buffSize), uintptr(unsafe.Pointer(bytesNeeded)), 0)
if r1 == 0 {
if e1 != 0 {
err = errnoErr(e1)
} else {
err = syscall.EINVAL
}
}
return
}
func GetLastError() (lasterr error) {
r0, _, _ := syscall.Syscall(procGetLastError.Addr(), 0, 0, 0, 0)
if r0 != 0 {