windows: UTF16PtrToString remove max parameter

This commit is contained in:
Yaroslav Vorobiov
2020-04-27 18:11:46 +03:00
parent 033a5e1701
commit 776a65d8f2
7 changed files with 29 additions and 37 deletions

View File

@@ -39,7 +39,7 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) {
defer DestroyEnvironmentBlock(block)
blockp := uintptr(unsafe.Pointer(block))
for {
entry := UTF16PtrToString((*uint16)(unsafe.Pointer(blockp)), (1<<30)-1)
entry := UTF16PtrToString((*uint16)(unsafe.Pointer(blockp)))
if len(entry) == 0 {
break
}

View File

@@ -1230,7 +1230,7 @@ func (sd *SECURITY_DESCRIPTOR) String() string {
return ""
}
defer LocalFree(Handle(unsafe.Pointer(sddl)))
return UTF16PtrToString(sddl, int(strLen))
return UTF16PtrToString(sddl)
}
// ToAbsolute converts a self-relative security descriptor into an absolute one.

View File

@@ -45,26 +45,19 @@ type Config struct {
DelayedAutoStart bool // the service is started after other auto-start services are started plus a short delay
}
func toString(p *uint16) string {
return windows.UTF16PtrToString(p, 4096)
}
func toStringSlice(ps *uint16) []string {
r := make([]string, 0)
p := unsafe.Pointer(ps)
offset := func(count int) uintptr {
return unsafe.Sizeof(uint16(0)) * (uintptr)(count)
}
for {
s := windows.UTF16PtrToString((*uint16)(p), 4096)
if s == "" {
s := windows.UTF16PtrToString((*uint16)(p))
if len(s) == 0 {
break
}
r = append(r, s)
p = unsafe.Pointer(uintptr(p) + offset(len(s)+1))
offset := unsafe.Sizeof(uint16(0)) * (uintptr)(len(s)+1)
p = unsafe.Pointer(uintptr(p) + offset)
}
return r
@@ -109,13 +102,13 @@ func (s *Service) Config() (Config, error) {
ServiceType: p.ServiceType,
StartType: p.StartType,
ErrorControl: p.ErrorControl,
BinaryPathName: toString(p.BinaryPathName),
LoadOrderGroup: toString(p.LoadOrderGroup),
BinaryPathName: windows.UTF16PtrToString(p.BinaryPathName),
LoadOrderGroup: windows.UTF16PtrToString(p.LoadOrderGroup),
TagId: p.TagId,
Dependencies: toStringSlice(p.Dependencies),
ServiceStartName: toString(p.ServiceStartName),
DisplayName: toString(p.DisplayName),
Description: toString(p2.Description),
ServiceStartName: windows.UTF16PtrToString(p.ServiceStartName),
DisplayName: windows.UTF16PtrToString(p.DisplayName),
Description: windows.UTF16PtrToString(p2.Description),
DelayedAutoStart: delayedStart,
}, nil
}

View File

@@ -73,7 +73,7 @@ func (m *Mgr) LockStatus() (*LockStatus, error) {
status := &LockStatus{
IsLocked: lockStatus.IsLocked != 0,
Age: time.Duration(lockStatus.LockDuration) * time.Second,
Owner: toString(lockStatus.LockOwner),
Owner: windows.UTF16PtrToString(lockStatus.LockOwner),
}
return status, nil
}
@@ -204,7 +204,7 @@ func (m *Mgr) ListServices() ([]string, error) {
services := (*[1 << 20]windows.ENUM_SERVICE_STATUS_PROCESS)(unsafe.Pointer(&buf[0]))[:servicesReturned:servicesReturned]
var names []string
for _, s := range services {
name := toString(s.ServiceName)
name := windows.UTF16PtrToString(s.ServiceName)
names = append(names, name)
}
return names, nil

View File

@@ -112,7 +112,7 @@ func (s *Service) RebootMessage() (string, error) {
return "", err
}
p := (*windows.SERVICE_FAILURE_ACTIONS)(unsafe.Pointer(&b[0]))
return toString(p.RebootMsg), nil
return windows.UTF16PtrToString(p.RebootMsg), nil
}
// SetRecoveryCommand sets the command line of the process to execute in response to the RunCommand service controller action.
@@ -131,5 +131,5 @@ func (s *Service) RecoveryCommand() (string, error) {
return "", err
}
p := (*windows.SERVICE_FAILURE_ACTIONS)(unsafe.Pointer(&b[0]))
return toString(p.Command), nil
return windows.UTF16PtrToString(p.Command), nil
}

View File

@@ -227,7 +227,7 @@ func (s *service) run() {
argv := (*[100]*uint16)(unsafe.Pointer(sArgv))[:sArgc:sArgc]
args := make([]string, len(argv))
for i, a := range argv {
args[i] = windows.UTF16PtrToString(a, 1<<20)
args[i] = windows.UTF16PtrToString(a)
}
cmdsToHandler := make(chan ChangeRequest)

View File

@@ -117,23 +117,22 @@ func UTF16PtrFromString(s string) (*uint16, error) {
return &a[0], nil
}
// UTF16PtrToString is like UTF16ToString, but takes *uint16
// as a parameter instead of []uint16.
// max is how many times p can be advanced looking for the null terminator.
// If max is hit, the string is truncated at that point.
func UTF16PtrToString(p *uint16, max int) string {
// UTF16PtrToString takes a pointer to a UTF-16 sequence and returns the corresponding UTF-8 encoded string.
// If the pointer is nil, this returns the empty string. This assumes that the UTF-16 sequence is terminated
// at a zero word; if the zero word is not present, the program may crash.
func UTF16PtrToString(p *uint16) string {
if p == nil {
return ""
}
// Find NUL terminator.
end := unsafe.Pointer(p)
n := 0
for *(*uint16)(end) != 0 && n < max {
end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p))
n++
var encoded []uint16
for *p != 0 {
encoded = append(encoded, *p)
p = (*uint16)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + unsafe.Sizeof(*p)))
}
s := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(p))[:n:n]
return string(utf16.Decode(s))
return string(utf16.Decode(encoded))
}
func Getpagesize() int { return 4096 }
@@ -1402,7 +1401,7 @@ func (t Token) KnownFolderPath(folderID *KNOWNFOLDERID, flags uint32) (string, e
return "", err
}
defer CoTaskMemFree(unsafe.Pointer(p))
return UTF16PtrToString(p, (1<<30)-1), nil
return UTF16PtrToString(p), nil
}
// RtlGetVersion returns the version of the underlying operating system, ignoring