master
c 354 lines 11.4 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "windows-events.h"
4 #include <sddl.h> // For SID string conversion
5
6 // Function to append the separator if the buffer is not empty
7 static inline void append_separator_if_needed(BUFFER *b, const char *separator) {
8 if (buffer_strlen(b) > 0 && separator != NULL)
9 buffer_strcat(b, separator);
10 }
11
12 // Helper function to convert UTF16 strings to UTF8 and append to the buffer
13 static inline void append_utf16(BUFFER *b, LPCWSTR utf16Str, const char *separator) {
14 if (!utf16Str || !*utf16Str) return;
15
16 append_separator_if_needed(b, separator);
17
18 size_t remaining = b->size - b->len;
19 if(remaining < 128) {
20 buffer_need_bytes(b, 128);
21 remaining = b->size - b->len;
22 }
23
24 bool truncated = false;
25 size_t used = utf16_to_utf8(&b->buffer[b->len], remaining, utf16Str, -1, &truncated);
26 if(truncated) {
27 // we need to resize
28 size_t needed = utf16_to_utf8(NULL, 0, utf16Str, -1, NULL); // find the size needed
29 buffer_need_bytes(b, needed);
30 remaining = b->size - b->len;
31 used = utf16_to_utf8(&b->buffer[b->len], remaining, utf16Str, -1, NULL);
32 }
33
34 if(used) {
35 b->len += used - 1;
36
37 internal_fatal(buffer_strlen(b) != strlen(buffer_tostring(b)),
38 "Buffer length mismatch.");
39 }
40 }
41
42 // Function to append binary data to the buffer
43 static inline void append_binary(BUFFER *b, PBYTE data, DWORD size, const char *separator) {
44 if (data == NULL || size == 0) return;
45
46 append_separator_if_needed(b, separator);
47
48 buffer_need_bytes(b, size * 4);
49 for (DWORD i = 0; i < size; i++) {
50 uint8_t value = data[i];
51 b->buffer[b->len++] = hex_digits[(value & 0xf0) >> 4];
52 b->buffer[b->len++] = hex_digits[(value & 0x0f)];
53 }
54 }
55
56 // Function to append size_t to the buffer
57 static inline void append_size_t(BUFFER *b, size_t size, const char *separator) {
58 append_separator_if_needed(b, separator);
59 buffer_print_uint64(b, size);
60 }
61
62 // Function to append HexInt32 in hexadecimal format
63 static inline void append_uint32_hex(BUFFER *b, UINT32 n, const char *separator) {
64 append_separator_if_needed(b, separator);
65 buffer_print_uint64_hex(b, n);
66 }
67
68 // Function to append HexInt64 in hexadecimal format
69 static inline void append_uint64_hex(BUFFER *b, UINT64 n, const char *separator) {
70 append_separator_if_needed(b, separator);
71 buffer_print_uint64_hex(b, n);
72 }
73
74 // Function to append various data types to the buffer
75 static inline void append_uint64(BUFFER *b, UINT64 n, const char *separator) {
76 append_separator_if_needed(b, separator);
77 buffer_print_uint64(b, n);
78 }
79
80 static inline void append_int64(BUFFER *b, INT64 n, const char *separator) {
81 append_separator_if_needed(b, separator);
82 buffer_print_int64(b, n);
83 }
84
85 static inline void append_double(BUFFER *b, double n, const char *separator) {
86 append_separator_if_needed(b, separator);
87 buffer_print_netdata_double(b, n);
88 }
89
90 static inline void append_guid(BUFFER *b, GUID *guid, const char *separator) {
91 fatal_assert(sizeof(GUID) == sizeof(nd_uuid_t));
92
93 append_separator_if_needed(b, separator);
94
95 ND_UUID *uuid = (ND_UUID *)guid;
96 buffer_need_bytes(b, UUID_STR_LEN);
97 uuid_unparse_lower(uuid->uuid, &b->buffer[b->len]);
98 b->len += UUID_STR_LEN - 1;
99
100 internal_fatal(buffer_strlen(b) != strlen(buffer_tostring(b)),
101 "Buffer length mismatch.");
102 }
103
104 static inline void append_systime(BUFFER *b, SYSTEMTIME *st, const char *separator) {
105 append_separator_if_needed(b, separator);
106 buffer_sprintf(b, "%04d-%02d-%02d %02d:%02d:%02d",
107 st->wYear, st->wMonth, st->wDay, st->wHour, st->wMinute, st->wSecond);
108 }
109
110 static inline void append_filetime(BUFFER *b, FILETIME *ft, const char *separator) {
111 SYSTEMTIME st;
112 if (FileTimeToSystemTime(ft, &st))
113 append_systime(b, &st, separator);
114 }
115
116 static inline void append_sid(BUFFER *b, PSID sid, const char *separator) {
117 cached_sid_to_buffer_append(sid, b, separator);
118 }
119
120 static inline void append_sbyte(BUFFER *b, INT8 n, const char *separator) {
121 append_separator_if_needed(b, separator);
122 buffer_print_int64(b, n);
123 }
124
125 static inline void append_byte(BUFFER *b, UINT8 n, const char *separator) {
126 append_separator_if_needed(b, separator);
127 buffer_print_uint64(b, n);
128 }
129
130 static inline void append_int16(BUFFER *b, INT16 n, const char *separator) {
131 append_separator_if_needed(b, separator);
132 buffer_print_int64(b, n);
133 }
134
135 static inline void append_uint16(BUFFER *b, UINT16 n, const char *separator) {
136 append_separator_if_needed(b, separator);
137 buffer_print_uint64(b, n);
138 }
139
140 static inline void append_int32(BUFFER *b, INT32 n, const char *separator) {
141 append_separator_if_needed(b, separator);
142 buffer_print_int64(b, n);
143 }
144
145 static inline void append_uint32(BUFFER *b, UINT32 n, const char *separator) {
146 append_separator_if_needed(b, separator);
147 buffer_print_uint64(b, n);
148 }
149
150 // Function to append EVT_HANDLE to the buffer
151 static inline void append_evt_handle(BUFFER *b, EVT_HANDLE h, const char *separator) {
152 append_separator_if_needed(b, separator);
153 buffer_print_uint64_hex(b, (uintptr_t)h);
154 }
155
156 // Function to append XML data (UTF-16) to the buffer
157 static inline void append_evt_xml(BUFFER *b, LPCWSTR xmlData, const char *separator) {
158 append_utf16(b, xmlData, separator); // XML data is essentially UTF-16 string
159 }
160
161 void evt_variant_to_buffer(BUFFER *b, EVT_VARIANT *ev, const char *separator) {
162 if(ev->Type == EvtVarTypeNull) return;
163
164 if (ev->Type & EVT_VARIANT_TYPE_ARRAY) {
165 for (DWORD i = 0; i < ev->Count; i++) {
166 switch (ev->Type & EVT_VARIANT_TYPE_MASK) {
167 case EvtVarTypeString:
168 append_utf16(b, ev->StringArr[i], separator);
169 break;
170
171 case EvtVarTypeAnsiString:
172 if (ev->AnsiStringArr[i] != NULL) {
173 append_utf16(b, (LPCWSTR)ev->AnsiStringArr[i], separator);
174 }
175 break;
176
177 case EvtVarTypeSByte:
178 append_sbyte(b, ev->SByteArr[i], separator);
179 break;
180
181 case EvtVarTypeByte:
182 append_byte(b, ev->ByteArr[i], separator);
183 break;
184
185 case EvtVarTypeInt16:
186 append_int16(b, ev->Int16Arr[i], separator);
187 break;
188
189 case EvtVarTypeUInt16:
190 append_uint16(b, ev->UInt16Arr[i], separator);
191 break;
192
193 case EvtVarTypeInt32:
194 append_int32(b, ev->Int32Arr[i], separator);
195 break;
196
197 case EvtVarTypeUInt32:
198 append_uint32(b, ev->UInt32Arr[i], separator);
199 break;
200
201 case EvtVarTypeInt64:
202 append_int64(b, ev->Int64Arr[i], separator);
203 break;
204
205 case EvtVarTypeUInt64:
206 append_uint64(b, ev->UInt64Arr[i], separator);
207 break;
208
209 case EvtVarTypeSingle:
210 append_double(b, ev->SingleArr[i], separator);
211 break;
212
213 case EvtVarTypeDouble:
214 append_double(b, ev->DoubleArr[i], separator);
215 break;
216
217 case EvtVarTypeGuid:
218 append_guid(b, &ev->GuidArr[i], separator);
219 break;
220
221 case EvtVarTypeFileTime:
222 append_filetime(b, &ev->FileTimeArr[i], separator);
223 break;
224
225 case EvtVarTypeSysTime:
226 append_systime(b, &ev->SysTimeArr[i], separator);
227 break;
228
229 case EvtVarTypeSid:
230 append_sid(b, ev->SidArr[i], separator);
231 break;
232
233 case EvtVarTypeBinary:
234 append_binary(b, ev->BinaryVal, ev->Count, separator);
235 break;
236
237 case EvtVarTypeSizeT:
238 append_size_t(b, ev->SizeTArr[i], separator);
239 break;
240
241 case EvtVarTypeHexInt32:
242 append_uint32_hex(b, ev->UInt32Arr[i], separator);
243 break;
244
245 case EvtVarTypeHexInt64:
246 append_uint64_hex(b, ev->UInt64Arr[i], separator);
247 break;
248
249 case EvtVarTypeEvtHandle:
250 append_evt_handle(b, ev->EvtHandleVal, separator);
251 break;
252
253 case EvtVarTypeEvtXml:
254 append_evt_xml(b, ev->XmlValArr[i], separator);
255 break;
256
257 default:
258 // Skip unknown array types
259 break;
260 }
261 }
262 } else {
263 switch (ev->Type & EVT_VARIANT_TYPE_MASK) {
264 case EvtVarTypeNull:
265 // Do nothing for null types
266 break;
267
268 case EvtVarTypeString:
269 append_utf16(b, ev->StringVal, separator);
270 break;
271
272 case EvtVarTypeAnsiString:
273 append_utf16(b, (LPCWSTR)ev->AnsiStringVal, separator);
274 break;
275
276 case EvtVarTypeSByte:
277 append_sbyte(b, ev->SByteVal, separator);
278 break;
279
280 case EvtVarTypeByte:
281 append_byte(b, ev->ByteVal, separator);
282 break;
283
284 case EvtVarTypeInt16:
285 append_int16(b, ev->Int16Val, separator);
286 break;
287
288 case EvtVarTypeUInt16:
289 append_uint16(b, ev->UInt16Val, separator);
290 break;
291
292 case EvtVarTypeInt32:
293 append_int32(b, ev->Int32Val, separator);
294 break;
295
296 case EvtVarTypeUInt32:
297 append_uint32(b, ev->UInt32Val, separator);
298 break;
299
300 case EvtVarTypeInt64:
301 append_int64(b, ev->Int64Val, separator);
302 break;
303
304 case EvtVarTypeUInt64:
305 append_uint64(b, ev->UInt64Val, separator);
306 break;
307
308 case EvtVarTypeSingle:
309 append_double(b, ev->SingleVal, separator);
310 break;
311
312 case EvtVarTypeDouble:
313 append_double(b, ev->DoubleVal, separator);
314 break;
315
316 case EvtVarTypeBoolean:
317 append_separator_if_needed(b, separator);
318 buffer_strcat(b, ev->BooleanVal ? "true" : "false");
319 break;
320
321 case EvtVarTypeGuid:
322 append_guid(b, ev->GuidVal, separator);
323 break;
324
325 case EvtVarTypeBinary:
326 append_binary(b, ev->BinaryVal, ev->Count, separator);
327 break;
328
329 case EvtVarTypeSizeT:
330 append_size_t(b, ev->SizeTVal, separator);
331 break;
332
333 case EvtVarTypeHexInt32:
334 append_uint32_hex(b, ev->UInt32Val, separator);
335 break;
336
337 case EvtVarTypeHexInt64:
338 append_uint64_hex(b, ev->UInt64Val, separator);
339 break;
340
341 case EvtVarTypeEvtHandle:
342 append_evt_handle(b, ev->EvtHandleVal, separator);
343 break;
344
345 case EvtVarTypeEvtXml:
346 append_evt_xml(b, ev->XmlVal, separator);
347 break;
348
349 default:
350 // Skip unknown types
351 break;
352 }
353 }
354 }