use UTF16PtrToString function instead of slicing

This commit is contained in:
Yaroslav Vorobiov
2020-03-25 17:33:26 +02:00
parent d7147e9c79
commit 05e35ff28f
6 changed files with 28 additions and 16 deletions

View File

@@ -8,7 +8,6 @@ package windows
import (
"syscall"
"unicode/utf16"
"unsafe"
)
@@ -40,17 +39,11 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) {
defer DestroyEnvironmentBlock(block)
blockp := uintptr(unsafe.Pointer(block))
for {
entry := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(blockp))[:]
for i, v := range entry {
if v == 0 {
entry = entry[:i]
break
}
}
entry := UTF16PtrToString((*uint16)(unsafe.Pointer(blockp)), (1<<30)-1)
if len(entry) == 0 {
break
}
env = append(env, string(utf16.Decode(entry)))
env = append(env, entry)
blockp += 2 * (uintptr(len(entry)) + 1)
}
return env, nil

View File

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

View File

@@ -50,7 +50,7 @@ func toString(p *uint16) string {
if p == nil {
return ""
}
return syscall.UTF16ToString((*[4096]uint16)(unsafe.Pointer(p))[:])
return windows.UTF16PtrToString(p, 4096)
}
func toStringSlice(ps *uint16) []string {

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: windows.UTF16ToString((*[(1 << 30) - 1]uint16)(unsafe.Pointer(lockStatus.LockOwner))[:]),
Owner: toString(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 := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(s.ServiceName))[:])
name := toString(s.ServiceName)
names = append(names, name)
}
return names, nil

View File

@@ -224,10 +224,10 @@ const (
func (s *service) run() {
s.goWaits.Wait()
s.h = windows.Handle(ssHandle)
argv := (*[100]*int16)(unsafe.Pointer(sArgv))[:sArgc:sArgc]
argv := (*[100]*uint16)(unsafe.Pointer(sArgv))[:sArgc:sArgc]
args := make([]string, len(argv))
for i, a := range argv {
args[i] = syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(a))[:])
args[i] = windows.UTF16PtrToString(a, 1<<20)
}
cmdsToHandler := make(chan ChangeRequest)

View File

@@ -117,6 +117,25 @@ 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 {
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++
}
s := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(p))[:n:n]
return string(utf16.Decode(s))
}
func Getpagesize() int { return 4096 }
// NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention.
@@ -1383,7 +1402,7 @@ func (t Token) KnownFolderPath(folderID *KNOWNFOLDERID, flags uint32) (string, e
return "", err
}
defer CoTaskMemFree(unsafe.Pointer(p))
return UTF16ToString((*[(1 << 30) - 1]uint16)(unsafe.Pointer(p))[:]), nil
return UTF16PtrToString(p, (1<<30)-1), nil
}
// RtlGetVersion returns the version of the underlying operating system, ignoring