Merge pull request #3550 from kevpar/remove-eventlog
Remove Windows EventLog logging hook
This commit is contained in:
		| @@ -17,7 +17,6 @@ | |||||||
| package command | package command | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"bytes" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
| 	"log" | 	"log" | ||||||
| @@ -35,7 +34,6 @@ import ( | |||||||
| 	"golang.org/x/sys/windows" | 	"golang.org/x/sys/windows" | ||||||
| 	"golang.org/x/sys/windows/svc" | 	"golang.org/x/sys/windows/svc" | ||||||
| 	"golang.org/x/sys/windows/svc/debug" | 	"golang.org/x/sys/windows/svc/debug" | ||||||
| 	"golang.org/x/sys/windows/svc/eventlog" |  | ||||||
| 	"golang.org/x/sys/windows/svc/mgr" | 	"golang.org/x/sys/windows/svc/mgr" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -54,18 +52,6 @@ var ( | |||||||
| 	service *handler | 	service *handler | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( |  | ||||||
| 	// These should match the values in event_messages.mc. |  | ||||||
| 	eventInfo  = 1 |  | ||||||
| 	eventWarn  = 1 |  | ||||||
| 	eventError = 1 |  | ||||||
| 	eventDebug = 2 |  | ||||||
| 	eventPanic = 3 |  | ||||||
| 	eventFatal = 4 |  | ||||||
|  |  | ||||||
| 	eventExtraOffset = 10 // Add this to any event to get a string that supports extended data |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // serviceFlags returns an array of flags for configuring containerd to run | // serviceFlags returns an array of flags for configuring containerd to run | ||||||
| // as a Windows service under control of SCM. | // as a Windows service under control of SCM. | ||||||
| func serviceFlags() []cli.Flag { | func serviceFlags() []cli.Flag { | ||||||
| @@ -124,93 +110,6 @@ type handler struct { | |||||||
| 	done    chan struct{} // Indicates back to app main to quit | 	done    chan struct{} // Indicates back to app main to quit | ||||||
| } | } | ||||||
|  |  | ||||||
| type etwHook struct { |  | ||||||
| 	log *eventlog.Log |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *etwHook) Levels() []logrus.Level { |  | ||||||
| 	return []logrus.Level{ |  | ||||||
| 		logrus.PanicLevel, |  | ||||||
| 		logrus.FatalLevel, |  | ||||||
| 		logrus.ErrorLevel, |  | ||||||
| 		logrus.WarnLevel, |  | ||||||
| 		logrus.InfoLevel, |  | ||||||
| 		logrus.DebugLevel, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (h *etwHook) Fire(e *logrus.Entry) error { |  | ||||||
| 	var ( |  | ||||||
| 		etype uint16 |  | ||||||
| 		eid   uint32 |  | ||||||
| 	) |  | ||||||
|  |  | ||||||
| 	switch e.Level { |  | ||||||
| 	case logrus.PanicLevel: |  | ||||||
| 		etype = windows.EVENTLOG_ERROR_TYPE |  | ||||||
| 		eid = eventPanic |  | ||||||
| 	case logrus.FatalLevel: |  | ||||||
| 		etype = windows.EVENTLOG_ERROR_TYPE |  | ||||||
| 		eid = eventFatal |  | ||||||
| 	case logrus.ErrorLevel: |  | ||||||
| 		etype = windows.EVENTLOG_ERROR_TYPE |  | ||||||
| 		eid = eventError |  | ||||||
| 	case logrus.WarnLevel: |  | ||||||
| 		etype = windows.EVENTLOG_WARNING_TYPE |  | ||||||
| 		eid = eventWarn |  | ||||||
| 	case logrus.InfoLevel: |  | ||||||
| 		etype = windows.EVENTLOG_INFORMATION_TYPE |  | ||||||
| 		eid = eventInfo |  | ||||||
| 	case logrus.DebugLevel: |  | ||||||
| 		etype = windows.EVENTLOG_INFORMATION_TYPE |  | ||||||
| 		eid = eventDebug |  | ||||||
| 	default: |  | ||||||
| 		return errors.Wrap(errdefs.ErrInvalidArgument, "unknown level") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// If there is additional data, include it as a second string. |  | ||||||
| 	exts := "" |  | ||||||
| 	if len(e.Data) > 0 { |  | ||||||
| 		fs := bytes.Buffer{} |  | ||||||
| 		for k, v := range e.Data { |  | ||||||
| 			fs.WriteString(k) |  | ||||||
| 			fs.WriteByte('=') |  | ||||||
| 			fmt.Fprint(&fs, v) |  | ||||||
| 			fs.WriteByte(' ') |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		exts = fs.String()[:fs.Len()-1] |  | ||||||
| 		eid += eventExtraOffset |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if h.log == nil { |  | ||||||
| 		fmt.Fprintf(os.Stderr, "%s [%s]\n", e.Message, exts) |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	var ( |  | ||||||
| 		ss  [2]*uint16 |  | ||||||
| 		err error |  | ||||||
| 	) |  | ||||||
|  |  | ||||||
| 	ss[0], err = windows.UTF16PtrFromString(e.Message) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	count := uint16(1) |  | ||||||
| 	if exts != "" { |  | ||||||
| 		ss[1], err = windows.UTF16PtrFromString(exts) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		count++ |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return windows.ReportEvent(h.log.Handle, etype, 0, eid, 0, count, 0, &ss[0], nil) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func getServicePath() (string, error) { | func getServicePath() (string, error) { | ||||||
| 	p, err := exec.LookPath(os.Args[0]) | 	p, err := exec.LookPath(os.Args[0]) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -283,7 +182,7 @@ func registerService() error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return eventlog.Install(serviceNameFlag, p, false, eventlog.Info|eventlog.Warning|eventlog.Error) | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func unregisterService() error { | func unregisterService() error { | ||||||
| @@ -299,7 +198,6 @@ func unregisterService() error { | |||||||
| 	} | 	} | ||||||
| 	defer s.Close() | 	defer s.Close() | ||||||
|  |  | ||||||
| 	eventlog.Remove(serviceNameFlag) |  | ||||||
| 	err = s.Delete() | 	err = s.Delete() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| @@ -345,20 +243,6 @@ func registerUnregisterService(root string) (bool, error) { | |||||||
| 			return true, err | 			return true, err | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		interactive, err := svc.IsAnInteractiveSession() |  | ||||||
| 		if err != nil { |  | ||||||
| 			return true, err |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		var log *eventlog.Log |  | ||||||
| 		if !interactive { |  | ||||||
| 			log, err = eventlog.Open(serviceNameFlag) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return true, err |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		logrus.AddHook(&etwHook{log}) |  | ||||||
| 		logrus.SetOutput(ioutil.Discard) | 		logrus.SetOutput(ioutil.Discard) | ||||||
| 	} | 	} | ||||||
| 	return false, nil | 	return false, nil | ||||||
|   | |||||||
							
								
								
									
										198
									
								
								vendor/golang.org/x/sys/windows/registry/key.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										198
									
								
								vendor/golang.org/x/sys/windows/registry/key.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,198 +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) { |  | ||||||
| 	names := make([]string, 0) |  | ||||||
| 	// Registry key size limit is 255 bytes and described there: |  | ||||||
| 	// https://msdn.microsoft.com/library/windows/desktop/ms724872.aspx |  | ||||||
| 	buf := make([]uint16, 256) //plus 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 |  | ||||||
| } |  | ||||||
							
								
								
									
										9
									
								
								vendor/golang.org/x/sys/windows/registry/mksyscall.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/golang.org/x/sys/windows/registry/mksyscall.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,9 +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 generate |  | ||||||
|  |  | ||||||
| package registry |  | ||||||
|  |  | ||||||
| //go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall.go |  | ||||||
							
								
								
									
										32
									
								
								vendor/golang.org/x/sys/windows/registry/syscall.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/golang.org/x/sys/windows/registry/syscall.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -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 |  | ||||||
							
								
								
									
										387
									
								
								vendor/golang.org/x/sys/windows/registry/value.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										387
									
								
								vendor/golang.org/x/sys/windows/registry/value.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,387 +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) (data []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") |  | ||||||
| 		} |  | ||||||
| 		var val32 uint32 |  | ||||||
| 		copy((*[4]byte)(unsafe.Pointer(&val32))[:], data) |  | ||||||
| 		return uint64(val32), DWORD, nil |  | ||||||
| 	case QWORD: |  | ||||||
| 		if len(data) != 8 { |  | ||||||
| 			return 0, typ, errors.New("QWORD value is not 8 bytes long") |  | ||||||
| 		} |  | ||||||
| 		copy((*[8]byte)(unsafe.Pointer(&val))[:], data) |  | ||||||
| 		return val, 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 |  | ||||||
| } |  | ||||||
							
								
								
									
										120
									
								
								vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										120
									
								
								vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,120 +0,0 @@ | |||||||
| // Code generated by 'go generate'; 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 |  | ||||||
| } |  | ||||||
							
								
								
									
										80
									
								
								vendor/golang.org/x/sys/windows/svc/eventlog/install.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										80
									
								
								vendor/golang.org/x/sys/windows/svc/eventlog/install.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -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) |  | ||||||
| } |  | ||||||
							
								
								
									
										70
									
								
								vendor/golang.org/x/sys/windows/svc/eventlog/log.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										70
									
								
								vendor/golang.org/x/sys/windows/svc/eventlog/log.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -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) |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user
	 Phil Estes
					Phil Estes