...
1
2
3 package winapi
4
5 import (
6 "errors"
7 "reflect"
8 "syscall"
9 "unsafe"
10
11 "golang.org/x/sys/windows"
12 )
13
14
15
16 func Uint16BufferToSlice(buffer *uint16, bufferLength int) (result []uint16) {
17 hdr := (*reflect.SliceHeader)(unsafe.Pointer(&result))
18 hdr.Data = uintptr(unsafe.Pointer(buffer))
19 hdr.Cap = bufferLength
20 hdr.Len = bufferLength
21
22 return
23 }
24
25
26
27 type UnicodeString struct {
28 Length uint16
29 MaximumLength uint16
30 Buffer *uint16
31 }
32
33
34
35 const NTSTRSAFE_UNICODE_STRING_MAX_CCH = 32767
36
37
38 func (uni UnicodeString) String() string {
39
40
41 return windows.UTF16ToString(Uint16BufferToSlice(uni.Buffer, int(uni.Length/2)))
42 }
43
44
45
46 func NewUnicodeString(s string) (*UnicodeString, error) {
47 buf, err := windows.UTF16FromString(s)
48 if err != nil {
49 return nil, err
50 }
51
52 if len(buf) > NTSTRSAFE_UNICODE_STRING_MAX_CCH {
53 return nil, syscall.ENAMETOOLONG
54 }
55
56 uni := &UnicodeString{
57
58 Length: uint16((len(buf) - 1) * 2),
59 MaximumLength: uint16((len(buf) - 1) * 2),
60 Buffer: &buf[0],
61 }
62 return uni, nil
63 }
64
65
66
67
68 func ConvertStringSetToSlice(buf []byte) ([]string, error) {
69 var results []string
70 prev := 0
71 for i := range buf {
72 if buf[i] == 0 {
73 if prev == i {
74
75 return results, nil
76 }
77 results = append(results, string(buf[prev:i]))
78 prev = i + 1
79 }
80 }
81 return nil, errors.New("string set malformed: missing null terminator at end of buffer")
82 }
83
View as plain text