mirror of
https://github.com/rwinkhart/sys.git
synced 2026-09-01 06:46:44 -04:00
windows: replace all StringToUTF16 calls with UTF16FromString
`StringToUTF16` is deprecated and will panic if given an "invalid" string (in particular, one that has a null byte in it). The replacement function is `UTF16FromString`, and it returns an error if there was a problem. This change replaces all uses of `StringToUTF16` with `UTF16FromString`. The `service` struct now no longer stores a `string` name but rather a `*uint16` pointer to the name. It should not be possible to panic due to UTF16 string conversion at this point. Fixes golang/go#73006 Change-Id: Idce9cdbb4651fef8481f0cad19b5df0314fd4277 Reviewed-on: https://go-review.googlesource.com/c/sys/+/659936 Reviewed-by: Carlos Amedee <carlos@golang.org> Auto-Submit: Carlos Amedee <carlos@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Alex Brainman <alex.brainman@gmail.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
This commit is contained in:
committed by
Gopher Robot
parent
1c3b72f1c1
commit
1b2bd6bb49
+11
-2
@@ -164,7 +164,12 @@ loopItems:
|
|||||||
func CreateKey(k Key, path string, access uint32) (newk Key, openedExisting bool, err error) {
|
func CreateKey(k Key, path string, access uint32) (newk Key, openedExisting bool, err error) {
|
||||||
var h syscall.Handle
|
var h syscall.Handle
|
||||||
var d uint32
|
var d uint32
|
||||||
err = regCreateKeyEx(syscall.Handle(k), syscall.StringToUTF16Ptr(path),
|
var pathPointer *uint16
|
||||||
|
pathPointer, err = syscall.UTF16PtrFromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return 0, false, err
|
||||||
|
}
|
||||||
|
err = regCreateKeyEx(syscall.Handle(k), pathPointer,
|
||||||
0, nil, _REG_OPTION_NON_VOLATILE, access, nil, &h, &d)
|
0, nil, _REG_OPTION_NON_VOLATILE, access, nil, &h, &d)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, false, err
|
return 0, false, err
|
||||||
@@ -174,7 +179,11 @@ func CreateKey(k Key, path string, access uint32) (newk Key, openedExisting bool
|
|||||||
|
|
||||||
// DeleteKey deletes the subkey path of key k and its values.
|
// DeleteKey deletes the subkey path of key k and its values.
|
||||||
func DeleteKey(k Key, path string) error {
|
func DeleteKey(k Key, path string) error {
|
||||||
return regDeleteKey(syscall.Handle(k), syscall.StringToUTF16Ptr(path))
|
pathPointer, err := syscall.UTF16PtrFromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return regDeleteKey(syscall.Handle(k), pathPointer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// A KeyInfo describes the statistics of a key. It is returned by Stat.
|
// A KeyInfo describes the statistics of a key. It is returned by Stat.
|
||||||
|
|||||||
@@ -340,7 +340,11 @@ func (k Key) SetBinaryValue(name string, value []byte) error {
|
|||||||
|
|
||||||
// DeleteValue removes a named value from the key k.
|
// DeleteValue removes a named value from the key k.
|
||||||
func (k Key) DeleteValue(name string) error {
|
func (k Key) DeleteValue(name string) error {
|
||||||
return regDeleteValue(syscall.Handle(k), syscall.StringToUTF16Ptr(name))
|
namePointer, err := syscall.UTF16PtrFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return regDeleteValue(syscall.Handle(k), namePointer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadValueNames returns the value names of key k.
|
// ReadValueNames returns the value names of key k.
|
||||||
|
|||||||
@@ -29,11 +29,19 @@ func OpenRemote(host, source string) (*Log, error) {
|
|||||||
if source == "" {
|
if source == "" {
|
||||||
return nil, errors.New("Specify event log source")
|
return nil, errors.New("Specify event log source")
|
||||||
}
|
}
|
||||||
var s *uint16
|
var hostPointer *uint16
|
||||||
if host != "" {
|
if host != "" {
|
||||||
s = syscall.StringToUTF16Ptr(host)
|
var err error
|
||||||
|
hostPointer, err = syscall.UTF16PtrFromString(host)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
h, err := windows.RegisterEventSource(s, syscall.StringToUTF16Ptr(source))
|
sourcePointer, err := syscall.UTF16PtrFromString(source)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
h, err := windows.RegisterEventSource(hostPointer, sourcePointer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -46,7 +54,11 @@ func (l *Log) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *Log) report(etype uint16, eid uint32, msg string) error {
|
func (l *Log) report(etype uint16, eid uint32, msg string) error {
|
||||||
ss := []*uint16{syscall.StringToUTF16Ptr(msg)}
|
msgPointer, err := syscall.UTF16PtrFromString(msg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ss := []*uint16{msgPointer}
|
||||||
return windows.ReportEvent(l.Handle, etype, 0, eid, 0, 1, 0, &ss[0], nil)
|
return windows.ReportEvent(l.Handle, etype, 0, eid, 0, 1, 0, &ss[0], nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,11 @@ func (s *Service) Config() (Config, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func updateDescription(handle windows.Handle, desc string) error {
|
func updateDescription(handle windows.Handle, desc string) error {
|
||||||
d := windows.SERVICE_DESCRIPTION{Description: toPtr(desc)}
|
descPointer, err := toPtr(desc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
d := windows.SERVICE_DESCRIPTION{Description: descPointer}
|
||||||
return windows.ChangeServiceConfig2(handle,
|
return windows.ChangeServiceConfig2(handle,
|
||||||
windows.SERVICE_CONFIG_DESCRIPTION, (*byte)(unsafe.Pointer(&d)))
|
windows.SERVICE_CONFIG_DESCRIPTION, (*byte)(unsafe.Pointer(&d)))
|
||||||
}
|
}
|
||||||
@@ -141,10 +145,30 @@ func updateStartUp(handle windows.Handle, isDelayed bool) error {
|
|||||||
|
|
||||||
// UpdateConfig updates service s configuration parameters.
|
// UpdateConfig updates service s configuration parameters.
|
||||||
func (s *Service) UpdateConfig(c Config) error {
|
func (s *Service) UpdateConfig(c Config) error {
|
||||||
err := windows.ChangeServiceConfig(s.Handle, c.ServiceType, c.StartType,
|
binaryPathNamePointer, err := toPtr(c.BinaryPathName)
|
||||||
c.ErrorControl, toPtr(c.BinaryPathName), toPtr(c.LoadOrderGroup),
|
if err != nil {
|
||||||
nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName),
|
return err
|
||||||
toPtr(c.Password), toPtr(c.DisplayName))
|
}
|
||||||
|
loadOrderGroupPointer, err := toPtr(c.LoadOrderGroup)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
serviceStartNamePointer, err := toPtr(c.ServiceStartName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
passwordPointer, err := toPtr(c.Password)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
displayNamePointer, err := toPtr(c.DisplayName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = windows.ChangeServiceConfig(s.Handle, c.ServiceType, c.StartType,
|
||||||
|
c.ErrorControl, binaryPathNamePointer, loadOrderGroupPointer,
|
||||||
|
nil, toStringBlock(c.Dependencies), serviceStartNamePointer,
|
||||||
|
passwordPointer, displayNamePointer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
+41
-8
@@ -34,7 +34,11 @@ func Connect() (*Mgr, error) {
|
|||||||
func ConnectRemote(host string) (*Mgr, error) {
|
func ConnectRemote(host string) (*Mgr, error) {
|
||||||
var s *uint16
|
var s *uint16
|
||||||
if host != "" {
|
if host != "" {
|
||||||
s = syscall.StringToUTF16Ptr(host)
|
var err error
|
||||||
|
s, err = syscall.UTF16PtrFromString(host)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
h, err := windows.OpenSCManager(s, nil, windows.SC_MANAGER_ALL_ACCESS)
|
h, err := windows.OpenSCManager(s, nil, windows.SC_MANAGER_ALL_ACCESS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -78,11 +82,11 @@ func (m *Mgr) LockStatus() (*LockStatus, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toPtr(s string) *uint16 {
|
func toPtr(s string) (*uint16, error) {
|
||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
return nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
return syscall.StringToUTF16Ptr(s)
|
return syscall.UTF16PtrFromString(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// toStringBlock terminates strings in ss with 0, and then
|
// toStringBlock terminates strings in ss with 0, and then
|
||||||
@@ -122,10 +126,34 @@ func (m *Mgr) CreateService(name, exepath string, c Config, args ...string) (*Se
|
|||||||
for _, v := range args {
|
for _, v := range args {
|
||||||
s += " " + syscall.EscapeArg(v)
|
s += " " + syscall.EscapeArg(v)
|
||||||
}
|
}
|
||||||
h, err := windows.CreateService(m.Handle, toPtr(name), toPtr(c.DisplayName),
|
namePointer, err := toPtr(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
displayNamePointer, err := toPtr(c.DisplayName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sPointer, err := toPtr(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
loadOrderGroupPointer, err := toPtr(c.LoadOrderGroup)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
serviceStartNamePointer, err := toPtr(c.ServiceStartName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
passwordPointer, err := toPtr(c.Password)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
h, err := windows.CreateService(m.Handle, namePointer, displayNamePointer,
|
||||||
windows.SERVICE_ALL_ACCESS, c.ServiceType,
|
windows.SERVICE_ALL_ACCESS, c.ServiceType,
|
||||||
c.StartType, c.ErrorControl, toPtr(s), toPtr(c.LoadOrderGroup),
|
c.StartType, c.ErrorControl, sPointer, loadOrderGroupPointer,
|
||||||
nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName), toPtr(c.Password))
|
nil, toStringBlock(c.Dependencies), serviceStartNamePointer, passwordPointer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -159,7 +187,12 @@ func (m *Mgr) CreateService(name, exepath string, c Config, args ...string) (*Se
|
|||||||
// OpenService retrieves access to service name, so it can
|
// OpenService retrieves access to service name, so it can
|
||||||
// be interrogated and controlled.
|
// be interrogated and controlled.
|
||||||
func (m *Mgr) OpenService(name string) (*Service, error) {
|
func (m *Mgr) OpenService(name string) (*Service, error) {
|
||||||
h, err := windows.OpenService(m.Handle, syscall.StringToUTF16Ptr(name), windows.SERVICE_ALL_ACCESS)
|
namePointer, err := syscall.UTF16PtrFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
h, err := windows.OpenService(m.Handle, namePointer, windows.SERVICE_ALL_ACCESS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,8 +99,13 @@ func (s *Service) ResetPeriod() (uint32, error) {
|
|||||||
// SetRebootMessage sets service s reboot message.
|
// SetRebootMessage sets service s reboot message.
|
||||||
// If msg is "", the reboot message is deleted and no message is broadcast.
|
// If msg is "", the reboot message is deleted and no message is broadcast.
|
||||||
func (s *Service) SetRebootMessage(msg string) error {
|
func (s *Service) SetRebootMessage(msg string) error {
|
||||||
|
msgPointer, err := syscall.UTF16PtrFromString(msg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
rActions := windows.SERVICE_FAILURE_ACTIONS{
|
rActions := windows.SERVICE_FAILURE_ACTIONS{
|
||||||
RebootMsg: syscall.StringToUTF16Ptr(msg),
|
RebootMsg: msgPointer,
|
||||||
}
|
}
|
||||||
return windows.ChangeServiceConfig2(s.Handle, windows.SERVICE_CONFIG_FAILURE_ACTIONS, (*byte)(unsafe.Pointer(&rActions)))
|
return windows.ChangeServiceConfig2(s.Handle, windows.SERVICE_CONFIG_FAILURE_ACTIONS, (*byte)(unsafe.Pointer(&rActions)))
|
||||||
}
|
}
|
||||||
@@ -118,8 +123,13 @@ func (s *Service) RebootMessage() (string, error) {
|
|||||||
// SetRecoveryCommand sets the command line of the process to execute in response to the RunCommand service controller action.
|
// SetRecoveryCommand sets the command line of the process to execute in response to the RunCommand service controller action.
|
||||||
// If cmd is "", the command is deleted and no program is run when the service fails.
|
// If cmd is "", the command is deleted and no program is run when the service fails.
|
||||||
func (s *Service) SetRecoveryCommand(cmd string) error {
|
func (s *Service) SetRecoveryCommand(cmd string) error {
|
||||||
|
cmdPointer, err := syscall.UTF16PtrFromString(cmd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
rActions := windows.SERVICE_FAILURE_ACTIONS{
|
rActions := windows.SERVICE_FAILURE_ACTIONS{
|
||||||
Command: syscall.StringToUTF16Ptr(cmd),
|
Command: cmdPointer,
|
||||||
}
|
}
|
||||||
return windows.ChangeServiceConfig2(s.Handle, windows.SERVICE_CONFIG_FAILURE_ACTIONS, (*byte)(unsafe.Pointer(&rActions)))
|
return windows.ChangeServiceConfig2(s.Handle, windows.SERVICE_CONFIG_FAILURE_ACTIONS, (*byte)(unsafe.Pointer(&rActions)))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,11 @@ func (s *Service) Start(args ...string) error {
|
|||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
vs := make([]*uint16, len(args))
|
vs := make([]*uint16, len(args))
|
||||||
for i := range vs {
|
for i := range vs {
|
||||||
vs[i] = syscall.StringToUTF16Ptr(args[i])
|
argPointer, err := syscall.UTF16PtrFromString(args[i])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
vs[i] = argPointer
|
||||||
}
|
}
|
||||||
p = &vs[0]
|
p = &vs[0]
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-7
@@ -132,10 +132,10 @@ type ctlEvent struct {
|
|||||||
|
|
||||||
// service provides access to windows service api.
|
// service provides access to windows service api.
|
||||||
type service struct {
|
type service struct {
|
||||||
name string
|
namePointer *uint16
|
||||||
h windows.Handle
|
h windows.Handle
|
||||||
c chan ctlEvent
|
c chan ctlEvent
|
||||||
handler Handler
|
handler Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
type exitCode struct {
|
type exitCode struct {
|
||||||
@@ -209,7 +209,7 @@ var theService service // This is, unfortunately, a global, which means only one
|
|||||||
// serviceMain is the entry point called by the service manager, registered earlier by
|
// serviceMain is the entry point called by the service manager, registered earlier by
|
||||||
// the call to StartServiceCtrlDispatcher.
|
// the call to StartServiceCtrlDispatcher.
|
||||||
func serviceMain(argc uint32, argv **uint16) uintptr {
|
func serviceMain(argc uint32, argv **uint16) uintptr {
|
||||||
handle, err := windows.RegisterServiceCtrlHandlerEx(windows.StringToUTF16Ptr(theService.name), ctlHandlerCallback, 0)
|
handle, err := windows.RegisterServiceCtrlHandlerEx(theService.namePointer, ctlHandlerCallback, 0)
|
||||||
if sysErr, ok := err.(windows.Errno); ok {
|
if sysErr, ok := err.(windows.Errno); ok {
|
||||||
return uintptr(sysErr)
|
return uintptr(sysErr)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
@@ -280,15 +280,21 @@ loop:
|
|||||||
|
|
||||||
// Run executes service name by calling appropriate handler function.
|
// Run executes service name by calling appropriate handler function.
|
||||||
func Run(name string, handler Handler) error {
|
func Run(name string, handler Handler) error {
|
||||||
|
// Check to make sure that the service name is valid.
|
||||||
|
namePointer, err := windows.UTF16PtrFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
initCallbacks.Do(func() {
|
initCallbacks.Do(func() {
|
||||||
ctlHandlerCallback = windows.NewCallback(ctlHandler)
|
ctlHandlerCallback = windows.NewCallback(ctlHandler)
|
||||||
serviceMainCallback = windows.NewCallback(serviceMain)
|
serviceMainCallback = windows.NewCallback(serviceMain)
|
||||||
})
|
})
|
||||||
theService.name = name
|
theService.namePointer = namePointer
|
||||||
theService.handler = handler
|
theService.handler = handler
|
||||||
theService.c = make(chan ctlEvent)
|
theService.c = make(chan ctlEvent)
|
||||||
t := []windows.SERVICE_TABLE_ENTRY{
|
t := []windows.SERVICE_TABLE_ENTRY{
|
||||||
{ServiceName: windows.StringToUTF16Ptr(theService.name), ServiceProc: serviceMainCallback},
|
{ServiceName: namePointer, ServiceProc: serviceMainCallback},
|
||||||
{ServiceName: nil, ServiceProc: 0},
|
{ServiceName: nil, ServiceProc: 0},
|
||||||
}
|
}
|
||||||
return windows.StartServiceCtrlDispatcher(&t[0])
|
return windows.StartServiceCtrlDispatcher(&t[0])
|
||||||
|
|||||||
Reference in New Issue
Block a user