...
1
2
3 package etw
4
5 import (
6 "bytes"
7 "encoding/binary"
8 )
9
10
11 type inType byte
12
13
14
15
16
17 const (
18 inTypeNull inType = iota
19 inTypeUnicodeString
20 inTypeANSIString
21 inTypeInt8
22 inTypeUint8
23 inTypeInt16
24 inTypeUint16
25 inTypeInt32
26 inTypeUint32
27 inTypeInt64
28 inTypeUint64
29 inTypeFloat
30 inTypeDouble
31 inTypeBool32
32 inTypeBinary
33 inTypeGUID
34 inTypePointerUnsupported
35 inTypeFileTime
36 inTypeSystemTime
37 inTypeSID
38 inTypeHexInt32
39 inTypeHexInt64
40 inTypeCountedString
41 inTypeCountedANSIString
42 inTypeStruct
43 inTypeCountedBinary
44 inTypeCountedArray inType = 32
45 inTypeArray inType = 64
46 )
47
48
49
50 type outType byte
51
52
53
54
55
56 const (
57
58
59 outTypeDefault outType = iota
60 outTypeNoPrint
61 outTypeString
62 outTypeBoolean
63 outTypeHex
64 outTypePID
65 outTypeTID
66 outTypePort
67 outTypeIPv4
68 outTypeIPv6
69 outTypeSocketAddress
70 outTypeXML
71 outTypeJSON
72 outTypeWin32Error
73 outTypeNTStatus
74 outTypeHResult
75 outTypeFileTime
76 outTypeSigned
77 outTypeUnsigned
78 outTypeUTF8 outType = 35
79 outTypePKCS7WithTypeInfo outType = 36
80 outTypeCodePointer outType = 37
81 outTypeDateTimeUTC outType = 38
82 )
83
84
85
86 type eventMetadata struct {
87 buffer bytes.Buffer
88 }
89
90
91
92
93
94 func (em *eventMetadata) toBytes() []byte {
95
96
97 binary.LittleEndian.PutUint16(em.buffer.Bytes(), uint16(em.buffer.Len()))
98 return em.buffer.Bytes()
99 }
100
101
102
103 func (em *eventMetadata) writeEventHeader(name string, tags uint32) {
104 _ = binary.Write(&em.buffer, binary.LittleEndian, uint16(0))
105 em.writeTags(tags)
106 em.buffer.WriteString(name)
107 em.buffer.WriteByte(0)
108 }
109
110 func (em *eventMetadata) writeFieldInner(name string, inType inType, outType outType, tags uint32, arrSize uint16) {
111 em.buffer.WriteString(name)
112 em.buffer.WriteByte(0)
113
114 if outType == outTypeDefault && tags == 0 {
115 em.buffer.WriteByte(byte(inType))
116 } else {
117 em.buffer.WriteByte(byte(inType | 128))
118 if tags == 0 {
119 em.buffer.WriteByte(byte(outType))
120 } else {
121 em.buffer.WriteByte(byte(outType | 128))
122 em.writeTags(tags)
123 }
124 }
125
126 if arrSize != 0 {
127 _ = binary.Write(&em.buffer, binary.LittleEndian, arrSize)
128 }
129 }
130
131
132
133
134
135
136
137
138 func (em *eventMetadata) writeTags(tags uint32) {
139
140 tags &= 0xfffffff
141
142 for {
143
144 val := tags >> 21
145
146 if tags&0x1fffff == 0 {
147
148
149 em.buffer.WriteByte(byte(val & 0x7f))
150 return
151 }
152
153 em.buffer.WriteByte(byte(val | 0x80))
154
155 tags <<= 7
156 }
157 }
158
159
160
161
162 func (em *eventMetadata) writeField(name string, inType inType, outType outType, tags uint32) {
163 em.writeFieldInner(name, inType, outType, tags, 0)
164 }
165
166
167
168
169
170
171 func (em *eventMetadata) writeArray(name string, inType inType, outType outType, tags uint32) {
172 em.writeFieldInner(name, inType|inTypeArray, outType, tags, 0)
173 }
174
175
176
177
178
179
180 func (em *eventMetadata) writeCountedArray(name string, count uint16, inType inType, outType outType, tags uint32) {
181 em.writeFieldInner(name, inType|inTypeCountedArray, outType, tags, count)
182 }
183
184
185
186
187 func (em *eventMetadata) writeStruct(name string, fieldCount uint8, tags uint32) {
188 em.writeFieldInner(name, inTypeStruct, outType(fieldCount), tags, 0)
189 }
190
View as plain text