winevt_c 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.clang-format +5 -0
- data/README.md +2 -2
- data/example/rate_limit.rb +14 -0
- data/ext/winevt/extconf.rb +2 -2
- data/ext/winevt/winevt_bookmark.c +44 -39
- data/ext/winevt/winevt_c.h +42 -26
- data/ext/winevt/winevt_channel.c +43 -29
- data/ext/winevt/winevt_query.c +140 -92
- data/ext/winevt/winevt_subscribe.c +214 -89
- data/ext/winevt/winevt_utils.cpp +540 -335
- data/lib/winevt/version.rb +1 -1
- data/winevt_c.gemspec +1 -1
- metadata +5 -3
data/ext/winevt/winevt_utils.cpp
CHANGED
@@ -1,97 +1,71 @@
|
|
1
1
|
#include <winevt_c.h>
|
2
|
+
|
2
3
|
#include <sddl.h>
|
3
4
|
#include <stdlib.h>
|
4
5
|
#include <string>
|
5
6
|
#include <vector>
|
6
7
|
|
7
|
-
char*
|
8
|
-
wstr_to_mbstr(UINT cp, const WCHAR *wstr, int clen)
|
9
|
-
{
|
10
|
-
char *ptr;
|
11
|
-
int len = WideCharToMultiByte(cp, 0, wstr, clen, nullptr, 0, nullptr, nullptr);
|
12
|
-
if (!(ptr = static_cast<char *>(xmalloc(len)))) return nullptr;
|
13
|
-
WideCharToMultiByte(cp, 0, wstr, clen, ptr, len, nullptr, nullptr);
|
14
|
-
|
15
|
-
return ptr;
|
16
|
-
}
|
17
|
-
|
18
|
-
void free_allocated_mbstr(const char* str)
|
19
|
-
{
|
20
|
-
if (str)
|
21
|
-
xfree((char *)str);
|
22
|
-
}
|
23
|
-
|
24
8
|
VALUE
|
25
|
-
wstr_to_rb_str(UINT cp, const WCHAR
|
9
|
+
wstr_to_rb_str(UINT cp, const WCHAR* wstr, int clen)
|
26
10
|
{
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
11
|
+
VALUE vstr;
|
12
|
+
CHAR* ptr;
|
13
|
+
int len = WideCharToMultiByte(cp, 0, wstr, clen, nullptr, 0, nullptr, nullptr);
|
14
|
+
ptr = ALLOCV_N(CHAR, vstr, len);
|
15
|
+
WideCharToMultiByte(cp, 0, wstr, clen, ptr, len, nullptr, nullptr);
|
16
|
+
VALUE str = rb_utf8_str_new_cstr(ptr);
|
17
|
+
ALLOCV_END(vstr);
|
18
|
+
|
19
|
+
return str;
|
36
20
|
}
|
37
21
|
|
38
|
-
|
22
|
+
VALUE
|
23
|
+
render_to_rb_str(EVT_HANDLE handle, DWORD flags)
|
39
24
|
{
|
40
|
-
|
41
|
-
|
42
|
-
ULONG
|
43
|
-
ULONG
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
do {
|
48
|
-
if (bufferSizeNeeded > bufferSize) {
|
49
|
-
bufferSize = bufferSizeNeeded;
|
50
|
-
try {
|
51
|
-
buffer.resize(bufferSize);
|
52
|
-
buffer.shrink_to_fit();
|
53
|
-
} catch (std::bad_alloc e) {
|
54
|
-
status = ERROR_OUTOFMEMORY;
|
55
|
-
bufferSize = 0;
|
56
|
-
rb_raise(rb_eWinevtQueryError, "Out of memory");
|
57
|
-
break;
|
58
|
-
}
|
59
|
-
}
|
25
|
+
VALUE vbuffer;
|
26
|
+
WCHAR* buffer;
|
27
|
+
ULONG bufferSize = 0;
|
28
|
+
ULONG bufferSizeUsed = 0;
|
29
|
+
ULONG count;
|
30
|
+
BOOL succeeded;
|
31
|
+
VALUE result;
|
60
32
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
buffer.size(),
|
65
|
-
&buffer.front(),
|
66
|
-
&bufferSizeNeeded,
|
67
|
-
&count) != FALSE) {
|
68
|
-
status = ERROR_SUCCESS;
|
69
|
-
} else {
|
70
|
-
status = GetLastError();
|
71
|
-
}
|
72
|
-
} while (status == ERROR_INSUFFICIENT_BUFFER);
|
33
|
+
if (flags != EvtRenderEventXml && flags != EvtRenderBookmark) {
|
34
|
+
return Qnil;
|
35
|
+
}
|
73
36
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
37
|
+
// Get the size of the buffer
|
38
|
+
EvtRender(nullptr, handle, flags, 0, NULL, &bufferSize, &count);
|
39
|
+
|
40
|
+
// bufferSize is in bytes, not characters
|
41
|
+
buffer = (WCHAR*)ALLOCV(vbuffer, bufferSize);
|
42
|
+
|
43
|
+
succeeded =
|
44
|
+
EvtRender(nullptr, handle, flags, bufferSize, buffer, &bufferSizeUsed, &count);
|
45
|
+
if (!succeeded) {
|
46
|
+
DWORD status = GetLastError();
|
47
|
+
CHAR msgBuf[256];
|
48
|
+
|
49
|
+
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
50
|
+
nullptr,
|
51
|
+
status,
|
52
|
+
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
53
|
+
msgBuf,
|
54
|
+
_countof(msgBuf),
|
55
|
+
nullptr);
|
56
|
+
ALLOCV_END(vbuffer);
|
57
|
+
rb_raise(rb_eWinevtQueryError, "ErrorCode: %lu\nError: %s\n", status, msgBuf);
|
87
58
|
}
|
88
59
|
|
89
|
-
result =
|
60
|
+
result = wstr_to_rb_str(CP_UTF8, buffer, -1);
|
61
|
+
ALLOCV_END(vbuffer);
|
90
62
|
|
91
63
|
return result;
|
92
64
|
}
|
93
65
|
|
94
|
-
static std::wstring
|
66
|
+
static std::wstring
|
67
|
+
guid_to_wstr(const GUID& guid)
|
68
|
+
{
|
95
69
|
LPOLESTR p = nullptr;
|
96
70
|
if (FAILED(StringFromCLSID(guid, &p))) {
|
97
71
|
return nullptr;
|
@@ -101,259 +75,290 @@ static std::wstring guid_to_wstr(const GUID& guid) {
|
|
101
75
|
return s;
|
102
76
|
}
|
103
77
|
|
104
|
-
VALUE
|
78
|
+
static VALUE
|
79
|
+
extract_user_evt_variants(PEVT_VARIANT pRenderedValues, DWORD propCount)
|
105
80
|
{
|
106
|
-
std::vector<WCHAR> buffer;
|
107
|
-
ULONG bufferSize = 0;
|
108
|
-
ULONG bufferSizeNeeded = 0;
|
109
|
-
DWORD status, propCount = 0;
|
110
|
-
char *result;
|
111
|
-
LPTSTR msgBuf;
|
112
|
-
WCHAR* tmpWChar = nullptr;
|
113
81
|
VALUE userValues = rb_ary_new();
|
114
|
-
|
115
|
-
static PCWSTR eventProperties[] = { L"Event/EventData/Data[1]" };
|
116
|
-
EVT_HANDLE renderContext = EvtCreateRenderContext(0, nullptr, EvtRenderContextUser);
|
117
|
-
if (renderContext == nullptr) {
|
118
|
-
rb_raise(rb_eWinevtQueryError, "Failed to create renderContext");
|
119
|
-
}
|
120
|
-
|
121
|
-
do {
|
122
|
-
if (bufferSizeNeeded > bufferSize) {
|
123
|
-
bufferSize = bufferSizeNeeded;
|
124
|
-
try {
|
125
|
-
buffer.resize(bufferSize);
|
126
|
-
buffer.shrink_to_fit();
|
127
|
-
} catch (std::bad_alloc e) {
|
128
|
-
status = ERROR_OUTOFMEMORY;
|
129
|
-
bufferSize = 0;
|
130
|
-
rb_raise(rb_eWinevtQueryError, "Out of memory");
|
131
|
-
break;
|
132
|
-
}
|
133
|
-
}
|
134
|
-
|
135
|
-
if (EvtRender(renderContext,
|
136
|
-
handle,
|
137
|
-
EvtRenderEventValues,
|
138
|
-
buffer.size(),
|
139
|
-
&buffer.front(),
|
140
|
-
&bufferSizeNeeded,
|
141
|
-
&propCount) != FALSE) {
|
142
|
-
status = ERROR_SUCCESS;
|
143
|
-
} else {
|
144
|
-
status = GetLastError();
|
145
|
-
}
|
146
|
-
} while (status == ERROR_INSUFFICIENT_BUFFER);
|
147
|
-
|
148
|
-
if (status != ERROR_SUCCESS) {
|
149
|
-
FormatMessage(
|
150
|
-
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
151
|
-
FORMAT_MESSAGE_FROM_SYSTEM |
|
152
|
-
FORMAT_MESSAGE_IGNORE_INSERTS,
|
153
|
-
nullptr, status,
|
154
|
-
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
155
|
-
msgBuf, 0, nullptr);
|
156
|
-
|
157
|
-
VALUE errmsg = rb_str_new2(msgBuf);
|
158
|
-
LocalFree(msgBuf);
|
159
|
-
|
160
|
-
rb_raise(rb_eWinevtQueryError, "ErrorCode: %lu\nError: %s\n", status, RSTRING_PTR(errmsg));
|
161
|
-
}
|
162
|
-
|
163
|
-
PEVT_VARIANT pRenderedValues = reinterpret_cast<PEVT_VARIANT>(&buffer.front());
|
164
|
-
LARGE_INTEGER timestamp;
|
165
|
-
SYSTEMTIME st;
|
166
|
-
FILETIME ft;
|
167
|
-
std::vector<CHAR> strTime(128);
|
168
|
-
std::vector<CHAR> sResult(256);
|
169
82
|
VALUE rbObj;
|
170
83
|
|
171
|
-
for (
|
84
|
+
for (DWORD i = 0; i < propCount; i++) {
|
172
85
|
switch (pRenderedValues[i].Type) {
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
86
|
+
case EvtVarTypeNull:
|
87
|
+
rb_ary_push(userValues, Qnil);
|
88
|
+
break;
|
89
|
+
case EvtVarTypeString:
|
90
|
+
if (pRenderedValues[i].StringVal == nullptr) {
|
91
|
+
rb_ary_push(userValues, rb_utf8_str_new_cstr("(NULL)"));
|
92
|
+
} else {
|
93
|
+
std::wstring wStr(pRenderedValues[i].StringVal);
|
94
|
+
rbObj = wstr_to_rb_str(CP_UTF8, &wStr[0], -1);
|
95
|
+
rb_ary_push(userValues, rbObj);
|
96
|
+
}
|
97
|
+
break;
|
98
|
+
case EvtVarTypeAnsiString:
|
99
|
+
if (pRenderedValues[i].AnsiStringVal == nullptr) {
|
100
|
+
rb_ary_push(userValues, rb_utf8_str_new_cstr("(NULL)"));
|
101
|
+
} else {
|
102
|
+
rb_ary_push(
|
103
|
+
userValues,
|
104
|
+
rb_utf8_str_new_cstr(const_cast<char*>(pRenderedValues[i].AnsiStringVal)));
|
105
|
+
}
|
106
|
+
break;
|
107
|
+
case EvtVarTypeSByte:
|
108
|
+
rbObj = INT2NUM(static_cast<UINT32>(pRenderedValues[i].SByteVal));
|
109
|
+
rb_ary_push(userValues, rbObj);
|
110
|
+
break;
|
111
|
+
case EvtVarTypeByte:
|
112
|
+
rbObj = INT2NUM(static_cast<UINT32>(pRenderedValues[i].ByteVal));
|
113
|
+
rb_ary_push(userValues, rbObj);
|
114
|
+
break;
|
115
|
+
case EvtVarTypeInt16:
|
116
|
+
rbObj = INT2NUM(static_cast<INT32>(pRenderedValues[i].Int16Val));
|
117
|
+
rb_ary_push(userValues, rbObj);
|
118
|
+
break;
|
119
|
+
case EvtVarTypeUInt16:
|
120
|
+
rbObj = UINT2NUM(static_cast<UINT32>(pRenderedValues[i].UInt16Val));
|
121
|
+
rb_ary_push(userValues, rbObj);
|
122
|
+
break;
|
123
|
+
case EvtVarTypeInt32:
|
124
|
+
rbObj = INT2NUM(pRenderedValues[i].Int32Val);
|
125
|
+
rb_ary_push(userValues, rbObj);
|
126
|
+
break;
|
127
|
+
case EvtVarTypeUInt32:
|
128
|
+
rbObj = UINT2NUM(pRenderedValues[i].UInt32Val);
|
129
|
+
rb_ary_push(userValues, rbObj);
|
130
|
+
break;
|
131
|
+
case EvtVarTypeInt64:
|
132
|
+
rbObj = LONG2NUM(pRenderedValues[i].Int64Val);
|
133
|
+
rb_ary_push(userValues, rbObj);
|
134
|
+
break;
|
135
|
+
case EvtVarTypeUInt64:
|
136
|
+
rbObj = ULONG2NUM(pRenderedValues[i].UInt64Val);
|
182
137
|
rb_ary_push(userValues, rbObj);
|
138
|
+
break;
|
139
|
+
case EvtVarTypeSingle: {
|
140
|
+
CHAR sResult[256];
|
141
|
+
_snprintf_s(
|
142
|
+
sResult, _countof(sResult), _TRUNCATE, "%f", pRenderedValues[i].SingleVal);
|
143
|
+
rb_ary_push(userValues, rb_utf8_str_new_cstr(sResult));
|
144
|
+
break;
|
183
145
|
}
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
146
|
+
case EvtVarTypeDouble: {
|
147
|
+
CHAR sResult[256];
|
148
|
+
_snprintf_s(
|
149
|
+
sResult, _countof(sResult), _TRUNCATE, "%lf", pRenderedValues[i].DoubleVal);
|
150
|
+
rb_ary_push(userValues, rb_utf8_str_new_cstr(sResult));
|
151
|
+
break;
|
190
152
|
}
|
191
|
-
|
192
|
-
|
193
|
-
rbObj = INT2NUM(static_cast<UINT32>(pRenderedValues[i].SByteVal));
|
194
|
-
rb_ary_push(userValues, rbObj);
|
195
|
-
break;
|
196
|
-
case EvtVarTypeByte:
|
197
|
-
rbObj = INT2NUM(static_cast<UINT32>(pRenderedValues[i].ByteVal));
|
198
|
-
rb_ary_push(userValues, rbObj);
|
199
|
-
break;
|
200
|
-
case EvtVarTypeInt16:
|
201
|
-
rbObj = INT2NUM(static_cast<INT32>(pRenderedValues[i].Int16Val));
|
202
|
-
rb_ary_push(userValues, rbObj);
|
203
|
-
break;
|
204
|
-
case EvtVarTypeUInt16:
|
205
|
-
rbObj = UINT2NUM(static_cast<UINT32>(pRenderedValues[i].UInt16Val));
|
206
|
-
rb_ary_push(userValues, rbObj);
|
207
|
-
break;
|
208
|
-
case EvtVarTypeInt32:
|
209
|
-
rbObj = INT2NUM(pRenderedValues[i].Int32Val);
|
210
|
-
rb_ary_push(userValues, rbObj);
|
211
|
-
break;
|
212
|
-
case EvtVarTypeUInt32:
|
213
|
-
rbObj = UINT2NUM(pRenderedValues[i].UInt32Val);
|
214
|
-
rb_ary_push(userValues, rbObj);
|
215
|
-
break;
|
216
|
-
case EvtVarTypeInt64:
|
217
|
-
rbObj = LONG2NUM(pRenderedValues[i].Int64Val);
|
218
|
-
rb_ary_push(userValues, rbObj);
|
219
|
-
break;
|
220
|
-
case EvtVarTypeUInt64:
|
221
|
-
rbObj = ULONG2NUM(pRenderedValues[i].UInt64Val);
|
222
|
-
rb_ary_push(userValues, rbObj);
|
223
|
-
break;
|
224
|
-
case EvtVarTypeSingle:
|
225
|
-
_snprintf_s(&sResult.front(), sResult.size(), _TRUNCATE, "%f", pRenderedValues[i].SingleVal);
|
226
|
-
rb_ary_push(userValues, rb_utf8_str_new_cstr(&sResult.front()));
|
227
|
-
break;
|
228
|
-
case EvtVarTypeDouble:
|
229
|
-
_snprintf_s(&sResult.front(), sResult.size(), _TRUNCATE, "%lf", pRenderedValues[i].DoubleVal);
|
230
|
-
rb_ary_push(userValues, rb_utf8_str_new_cstr(&sResult.front()));
|
231
|
-
break;
|
232
|
-
case EvtVarTypeBoolean:
|
233
|
-
rbObj = pRenderedValues[i].BooleanVal ? Qtrue : Qfalse;
|
234
|
-
rb_ary_push(userValues, rbObj);
|
235
|
-
break;
|
236
|
-
case EvtVarTypeGuid:
|
237
|
-
if (pRenderedValues[i].GuidVal != nullptr) {
|
238
|
-
const GUID guid = *pRenderedValues[i].GuidVal;
|
239
|
-
std::wstring wstr = guid_to_wstr(guid);
|
240
|
-
rbObj = wstr_to_rb_str(CP_UTF8, wstr.c_str(), -1);
|
153
|
+
case EvtVarTypeBoolean:
|
154
|
+
rbObj = pRenderedValues[i].BooleanVal ? Qtrue : Qfalse;
|
241
155
|
rb_ary_push(userValues, rbObj);
|
242
|
-
|
243
|
-
|
156
|
+
break;
|
157
|
+
case EvtVarTypeGuid:
|
158
|
+
if (pRenderedValues[i].GuidVal != nullptr) {
|
159
|
+
const GUID guid = *pRenderedValues[i].GuidVal;
|
160
|
+
std::wstring wstr = guid_to_wstr(guid);
|
161
|
+
rbObj = wstr_to_rb_str(CP_UTF8, wstr.c_str(), -1);
|
162
|
+
rb_ary_push(userValues, rbObj);
|
163
|
+
} else {
|
164
|
+
rb_ary_push(userValues, rb_utf8_str_new_cstr("?"));
|
165
|
+
}
|
166
|
+
break;
|
167
|
+
case EvtVarTypeSizeT:
|
168
|
+
rbObj = SIZET2NUM(pRenderedValues[i].SizeTVal);
|
169
|
+
rb_ary_push(userValues, rbObj);
|
170
|
+
break;
|
171
|
+
case EvtVarTypeFileTime: {
|
172
|
+
LARGE_INTEGER timestamp;
|
173
|
+
CHAR strTime[128];
|
174
|
+
FILETIME ft;
|
175
|
+
SYSTEMTIME st;
|
176
|
+
timestamp.QuadPart = pRenderedValues[i].FileTimeVal;
|
177
|
+
ft.dwHighDateTime = timestamp.HighPart;
|
178
|
+
ft.dwLowDateTime = timestamp.LowPart;
|
179
|
+
if (FileTimeToSystemTime(&ft, &st)) {
|
180
|
+
_snprintf_s(strTime,
|
181
|
+
_countof(strTime),
|
182
|
+
_TRUNCATE,
|
183
|
+
"%04d-%02d-%02d %02d:%02d:%02d.%dZ",
|
184
|
+
st.wYear,
|
185
|
+
st.wMonth,
|
186
|
+
st.wDay,
|
187
|
+
st.wHour,
|
188
|
+
st.wMinute,
|
189
|
+
st.wSecond,
|
190
|
+
st.wMilliseconds);
|
191
|
+
rb_ary_push(userValues, rb_utf8_str_new_cstr(strTime));
|
192
|
+
} else {
|
193
|
+
rb_ary_push(userValues, rb_utf8_str_new_cstr("?"));
|
194
|
+
}
|
195
|
+
break;
|
244
196
|
}
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
197
|
+
case EvtVarTypeSysTime: {
|
198
|
+
CHAR strTime[128];
|
199
|
+
SYSTEMTIME st;
|
200
|
+
if (pRenderedValues[i].SysTimeVal != nullptr) {
|
201
|
+
st = *pRenderedValues[i].SysTimeVal;
|
202
|
+
_snprintf_s(strTime,
|
203
|
+
_countof(strTime),
|
204
|
+
_TRUNCATE,
|
205
|
+
"%04d-%02d-%02d %02d:%02d:%02d.%dZ",
|
206
|
+
st.wYear,
|
207
|
+
st.wMonth,
|
208
|
+
st.wDay,
|
209
|
+
st.wHour,
|
210
|
+
st.wMinute,
|
211
|
+
st.wSecond,
|
212
|
+
st.wMilliseconds);
|
213
|
+
rb_ary_push(userValues, rb_utf8_str_new_cstr(strTime));
|
214
|
+
} else {
|
215
|
+
rb_ary_push(userValues, rb_utf8_str_new_cstr("?"));
|
216
|
+
}
|
217
|
+
break;
|
262
218
|
}
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
rb_ary_push(userValues, rb_utf8_str_new_cstr("?"));
|
219
|
+
case EvtVarTypeSid: {
|
220
|
+
WCHAR* tmpWChar = nullptr;
|
221
|
+
if (ConvertSidToStringSidW(pRenderedValues[i].SidVal, &tmpWChar)) {
|
222
|
+
rbObj = wstr_to_rb_str(CP_UTF8, tmpWChar, -1);
|
223
|
+
rb_ary_push(userValues, rbObj);
|
224
|
+
LocalFree(tmpWChar);
|
225
|
+
} else {
|
226
|
+
rb_ary_push(userValues, rb_utf8_str_new_cstr("?"));
|
227
|
+
}
|
228
|
+
break;
|
274
229
|
}
|
275
|
-
|
276
|
-
|
277
|
-
if (ConvertSidToStringSidW(pRenderedValues[i].SidVal, &tmpWChar)) {
|
278
|
-
rbObj = wstr_to_rb_str(CP_UTF8, tmpWChar, -1);
|
230
|
+
case EvtVarTypeHexInt32:
|
231
|
+
rbObj = rb_sprintf("%#x", pRenderedValues[i].UInt32Val);
|
279
232
|
rb_ary_push(userValues, rbObj);
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
}
|
284
|
-
break;
|
285
|
-
case EvtVarTypeHexInt32:
|
286
|
-
rbObj = ULONG2NUM(pRenderedValues[i].UInt32Val);
|
287
|
-
rbObj = rb_sprintf("%#x", rbObj);
|
288
|
-
rb_ary_push(userValues, rbObj);
|
289
|
-
break;
|
290
|
-
case EvtVarTypeHexInt64:
|
291
|
-
rbObj = ULONG2NUM(pRenderedValues[i].UInt64Val);
|
292
|
-
rbObj = rb_sprintf("%#x", rbObj);
|
293
|
-
rb_ary_push(userValues, rbObj);
|
294
|
-
break;
|
295
|
-
case EvtVarTypeEvtXml:
|
296
|
-
if (pRenderedValues[i].XmlVal == nullptr) {
|
297
|
-
rb_ary_push(userValues, rb_utf8_str_new_cstr("(NULL)"));
|
298
|
-
} else {
|
299
|
-
rbObj = wstr_to_rb_str(CP_UTF8, pRenderedValues[i].XmlVal, -1);
|
233
|
+
break;
|
234
|
+
case EvtVarTypeHexInt64:
|
235
|
+
rbObj = rb_sprintf("%#I64x", pRenderedValues[i].UInt64Val);
|
300
236
|
rb_ary_push(userValues, rbObj);
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
237
|
+
break;
|
238
|
+
case EvtVarTypeEvtXml:
|
239
|
+
if (pRenderedValues[i].XmlVal == nullptr) {
|
240
|
+
rb_ary_push(userValues, rb_utf8_str_new_cstr("(NULL)"));
|
241
|
+
} else {
|
242
|
+
rbObj = wstr_to_rb_str(CP_UTF8, pRenderedValues[i].XmlVal, -1);
|
243
|
+
rb_ary_push(userValues, rbObj);
|
244
|
+
}
|
245
|
+
break;
|
246
|
+
default:
|
247
|
+
rb_ary_push(userValues, rb_utf8_str_new_cstr("?"));
|
248
|
+
break;
|
306
249
|
}
|
307
250
|
}
|
308
251
|
|
309
|
-
|
252
|
+
return userValues;
|
253
|
+
}
|
254
|
+
|
255
|
+
VALUE
|
256
|
+
get_values(EVT_HANDLE handle)
|
257
|
+
{
|
258
|
+
VALUE vbuffer;
|
259
|
+
PEVT_VARIANT pRenderedValues;
|
260
|
+
ULONG bufferSize = 0;
|
261
|
+
ULONG bufferSizeUsed = 0;
|
262
|
+
DWORD propCount = 0;
|
263
|
+
BOOL succeeded;
|
264
|
+
VALUE userValues = Qnil;
|
265
|
+
|
266
|
+
EVT_HANDLE renderContext = EvtCreateRenderContext(0, nullptr, EvtRenderContextUser);
|
267
|
+
if (renderContext == nullptr) {
|
268
|
+
rb_raise(rb_eWinevtQueryError, "Failed to create renderContext");
|
269
|
+
}
|
270
|
+
|
271
|
+
// Get the size of the buffer
|
272
|
+
EvtRender(
|
273
|
+
renderContext, handle, EvtRenderEventValues, 0, NULL, &bufferSize, &propCount);
|
274
|
+
|
275
|
+
// bufferSize is in bytes, not array size
|
276
|
+
pRenderedValues = (PEVT_VARIANT)ALLOCV(vbuffer, bufferSize);
|
277
|
+
|
278
|
+
succeeded = EvtRender(renderContext,
|
279
|
+
handle,
|
280
|
+
EvtRenderEventValues,
|
281
|
+
bufferSize,
|
282
|
+
pRenderedValues,
|
283
|
+
&bufferSizeUsed,
|
284
|
+
&propCount);
|
285
|
+
if (!succeeded) {
|
286
|
+
DWORD status = GetLastError();
|
287
|
+
CHAR msgBuf[256];
|
288
|
+
|
289
|
+
ALLOCV_END(vbuffer);
|
310
290
|
EvtClose(renderContext);
|
311
291
|
|
292
|
+
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
293
|
+
nullptr,
|
294
|
+
status,
|
295
|
+
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
296
|
+
msgBuf,
|
297
|
+
_countof(msgBuf),
|
298
|
+
nullptr);
|
299
|
+
rb_raise(rb_eWinevtQueryError, "ErrorCode: %lu\nError: %s\n", status, msgBuf);
|
300
|
+
}
|
301
|
+
|
302
|
+
userValues = extract_user_evt_variants(pRenderedValues, propCount);
|
303
|
+
|
304
|
+
ALLOCV_END(vbuffer);
|
305
|
+
EvtClose(renderContext);
|
306
|
+
|
312
307
|
return userValues;
|
313
308
|
}
|
314
309
|
|
315
|
-
static std::vector<WCHAR>
|
310
|
+
static std::vector<WCHAR>
|
311
|
+
get_message(EVT_HANDLE hMetadata, EVT_HANDLE handle)
|
316
312
|
{
|
317
313
|
#define BUFSIZE 4096
|
318
314
|
std::vector<WCHAR> result;
|
319
|
-
ULONG
|
315
|
+
ULONG status;
|
320
316
|
ULONG bufferSizeNeeded = 0;
|
321
317
|
LPVOID lpMsgBuf;
|
322
318
|
std::vector<WCHAR> message(BUFSIZE);
|
323
319
|
|
324
|
-
if (!EvtFormatMessage(hMetadata,
|
320
|
+
if (!EvtFormatMessage(hMetadata,
|
321
|
+
handle,
|
322
|
+
0xffffffff,
|
323
|
+
0,
|
324
|
+
nullptr,
|
325
|
+
EvtFormatMessageEvent,
|
326
|
+
message.size(),
|
327
|
+
&message[0],
|
328
|
+
&bufferSizeNeeded)) {
|
325
329
|
status = GetLastError();
|
326
330
|
|
327
331
|
if (status != ERROR_EVT_UNRESOLVED_VALUE_INSERT) {
|
328
332
|
switch (status) {
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
333
|
+
case ERROR_EVT_MESSAGE_NOT_FOUND:
|
334
|
+
case ERROR_EVT_MESSAGE_ID_NOT_FOUND:
|
335
|
+
case ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND:
|
336
|
+
case ERROR_RESOURCE_LANG_NOT_FOUND:
|
337
|
+
case ERROR_MUI_FILE_NOT_FOUND:
|
338
|
+
case ERROR_EVT_UNRESOLVED_PARAMETER_INSERT: {
|
339
|
+
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
|
340
|
+
FORMAT_MESSAGE_IGNORE_INSERTS,
|
341
|
+
nullptr,
|
342
|
+
status,
|
343
|
+
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
344
|
+
reinterpret_cast<WCHAR*>(&lpMsgBuf),
|
345
|
+
0,
|
346
|
+
nullptr) == 0)
|
347
|
+
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
|
348
|
+
FORMAT_MESSAGE_IGNORE_INSERTS,
|
338
349
|
nullptr,
|
339
350
|
status,
|
340
|
-
MAKELANGID(
|
341
|
-
reinterpret_cast<WCHAR
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
reinterpret_cast<WCHAR *>(&lpMsgBuf), 0, nullptr);
|
349
|
-
|
350
|
-
std::wstring ret(reinterpret_cast<WCHAR *>(lpMsgBuf));
|
351
|
-
std::copy( ret.begin(), ret.end(), std::back_inserter(result));
|
352
|
-
LocalFree(lpMsgBuf);
|
353
|
-
|
354
|
-
goto cleanup;
|
355
|
-
}
|
351
|
+
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
|
352
|
+
reinterpret_cast<WCHAR*>(&lpMsgBuf),
|
353
|
+
0,
|
354
|
+
nullptr);
|
355
|
+
|
356
|
+
std::wstring ret(reinterpret_cast<WCHAR*>(lpMsgBuf));
|
357
|
+
std::copy(ret.begin(), ret.end(), std::back_inserter(result));
|
358
|
+
LocalFree(lpMsgBuf);
|
356
359
|
|
360
|
+
goto cleanup;
|
361
|
+
}
|
357
362
|
}
|
358
363
|
|
359
364
|
if (status != ERROR_INSUFFICIENT_BUFFER)
|
@@ -364,37 +369,49 @@ static std::vector<WCHAR> get_message(EVT_HANDLE hMetadata, EVT_HANDLE handle)
|
|
364
369
|
message.resize(bufferSizeNeeded);
|
365
370
|
message.shrink_to_fit();
|
366
371
|
|
367
|
-
if(!EvtFormatMessage(hMetadata,
|
372
|
+
if (!EvtFormatMessage(hMetadata,
|
373
|
+
handle,
|
374
|
+
0xffffffff,
|
375
|
+
0,
|
376
|
+
nullptr,
|
377
|
+
EvtFormatMessageEvent,
|
378
|
+
message.size(),
|
379
|
+
&message.front(),
|
380
|
+
&bufferSizeNeeded)) {
|
368
381
|
status = GetLastError();
|
369
382
|
|
370
383
|
if (status != ERROR_EVT_UNRESOLVED_VALUE_INSERT) {
|
371
384
|
switch (status) {
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
385
|
+
case ERROR_EVT_MESSAGE_NOT_FOUND:
|
386
|
+
case ERROR_EVT_MESSAGE_ID_NOT_FOUND:
|
387
|
+
case ERROR_EVT_MESSAGE_LOCALE_NOT_FOUND:
|
388
|
+
case ERROR_RESOURCE_LANG_NOT_FOUND:
|
389
|
+
case ERROR_MUI_FILE_NOT_FOUND:
|
390
|
+
case ERROR_EVT_UNRESOLVED_PARAMETER_INSERT:
|
391
|
+
if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
392
|
+
FORMAT_MESSAGE_FROM_SYSTEM |
|
393
|
+
FORMAT_MESSAGE_IGNORE_INSERTS,
|
394
|
+
nullptr,
|
395
|
+
status,
|
396
|
+
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
397
|
+
reinterpret_cast<WCHAR*>(&lpMsgBuf),
|
398
|
+
0,
|
399
|
+
nullptr) == 0)
|
400
|
+
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
401
|
+
FORMAT_MESSAGE_FROM_SYSTEM |
|
402
|
+
FORMAT_MESSAGE_IGNORE_INSERTS,
|
381
403
|
nullptr,
|
382
404
|
status,
|
383
|
-
MAKELANGID(
|
384
|
-
reinterpret_cast<WCHAR
|
385
|
-
|
386
|
-
|
387
|
-
FORMAT_MESSAGE_IGNORE_INSERTS,
|
388
|
-
nullptr,
|
389
|
-
status,
|
390
|
-
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
|
391
|
-
reinterpret_cast<WCHAR *>(&lpMsgBuf), 0, nullptr);
|
405
|
+
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
|
406
|
+
reinterpret_cast<WCHAR*>(&lpMsgBuf),
|
407
|
+
0,
|
408
|
+
nullptr);
|
392
409
|
|
393
|
-
|
394
|
-
|
395
|
-
|
410
|
+
std::wstring ret(reinterpret_cast<WCHAR*>(lpMsgBuf));
|
411
|
+
std::copy(ret.begin(), ret.end(), std::back_inserter(result));
|
412
|
+
LocalFree(lpMsgBuf);
|
396
413
|
|
397
|
-
|
414
|
+
goto cleanup;
|
398
415
|
}
|
399
416
|
|
400
417
|
rb_raise(rb_eWinevtQueryError, "ErrorCode: %lu", status);
|
@@ -412,19 +429,20 @@ cleanup:
|
|
412
429
|
#undef BUFSIZE
|
413
430
|
}
|
414
431
|
|
415
|
-
WCHAR*
|
432
|
+
WCHAR*
|
433
|
+
get_description(EVT_HANDLE handle)
|
416
434
|
{
|
417
435
|
#define BUFSIZE 4096
|
418
436
|
std::vector<WCHAR> buffer(BUFSIZE);
|
419
|
-
ULONG
|
420
|
-
ULONG
|
421
|
-
ULONG status, count;
|
437
|
+
ULONG bufferSizeNeeded = 0;
|
438
|
+
ULONG status, count;
|
422
439
|
std::vector<WCHAR> result;
|
423
|
-
|
440
|
+
CHAR msgBuf[256];
|
424
441
|
EVT_HANDLE hMetadata = nullptr;
|
425
442
|
|
426
|
-
static PCWSTR eventProperties[] = {L"Event/System/Provider/@Name"};
|
427
|
-
EVT_HANDLE renderContext =
|
443
|
+
static PCWSTR eventProperties[] = { L"Event/System/Provider/@Name" };
|
444
|
+
EVT_HANDLE renderContext =
|
445
|
+
EvtCreateRenderContext(1, eventProperties, EvtRenderContextValues);
|
428
446
|
if (renderContext == nullptr) {
|
429
447
|
rb_raise(rb_eWinevtQueryError, "Failed to create renderContext");
|
430
448
|
}
|
@@ -442,25 +460,26 @@ WCHAR* get_description(EVT_HANDLE handle)
|
|
442
460
|
}
|
443
461
|
|
444
462
|
if (status != ERROR_SUCCESS) {
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
VALUE errmsg = rb_str_new2(msgBuf);
|
454
|
-
LocalFree(msgBuf);
|
455
|
-
|
456
|
-
rb_raise(rb_eWinevtQueryError, "ErrorCode: %lu\nError: %s\n", status, RSTRING_PTR(errmsg));
|
463
|
+
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
464
|
+
nullptr,
|
465
|
+
status,
|
466
|
+
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
467
|
+
msgBuf,
|
468
|
+
sizeof(msgBuf),
|
469
|
+
nullptr);
|
470
|
+
rb_raise(rb_eWinevtQueryError, "ErrorCode: %lu\nError: %s\n", status, msgBuf);
|
457
471
|
}
|
458
472
|
|
459
473
|
// Obtain buffer as EVT_VARIANT pointer. To avoid ErrorCide 87 in EvtRender.
|
460
474
|
const PEVT_VARIANT values = reinterpret_cast<PEVT_VARIANT>(&buffer.front());
|
461
475
|
|
462
476
|
// Open publisher metadata
|
463
|
-
hMetadata = EvtOpenPublisherMetadata(
|
477
|
+
hMetadata = EvtOpenPublisherMetadata(
|
478
|
+
nullptr,
|
479
|
+
values[0].StringVal,
|
480
|
+
nullptr,
|
481
|
+
MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), SORT_DEFAULT),
|
482
|
+
0);
|
464
483
|
if (hMetadata == nullptr) {
|
465
484
|
// When winevt_c cannot open metadata, then give up to obtain
|
466
485
|
// message file and clean up immediately.
|
@@ -481,3 +500,189 @@ cleanup:
|
|
481
500
|
|
482
501
|
return _wcsdup(result.data());
|
483
502
|
}
|
503
|
+
|
504
|
+
VALUE
|
505
|
+
render_system_event(EVT_HANDLE hEvent)
|
506
|
+
{
|
507
|
+
DWORD status = ERROR_SUCCESS;
|
508
|
+
EVT_HANDLE hContext = NULL;
|
509
|
+
DWORD dwBufferSize = 0;
|
510
|
+
DWORD dwBufferUsed = 0;
|
511
|
+
DWORD dwPropertyCount = 0;
|
512
|
+
VALUE vRenderedValues;
|
513
|
+
PEVT_VARIANT pRenderedValues = NULL;
|
514
|
+
WCHAR wsGuid[50];
|
515
|
+
LPSTR pwsSid = NULL;
|
516
|
+
ULONGLONG ullTimeStamp = 0;
|
517
|
+
ULONGLONG ullNanoseconds = 0;
|
518
|
+
SYSTEMTIME st;
|
519
|
+
FILETIME ft;
|
520
|
+
CHAR buffer[32];
|
521
|
+
VALUE rbstr;
|
522
|
+
DWORD EventID;
|
523
|
+
VALUE hash = rb_hash_new();
|
524
|
+
|
525
|
+
hContext = EvtCreateRenderContext(0, NULL, EvtRenderContextSystem);
|
526
|
+
if (NULL == hContext) {
|
527
|
+
rb_raise(rb_eWinevtQueryError,
|
528
|
+
"Failed to create renderContext with %lu\n", GetLastError());
|
529
|
+
}
|
530
|
+
|
531
|
+
if (!EvtRender(hContext,
|
532
|
+
hEvent,
|
533
|
+
EvtRenderEventValues,
|
534
|
+
dwBufferSize,
|
535
|
+
pRenderedValues,
|
536
|
+
&dwBufferUsed,
|
537
|
+
&dwPropertyCount)) {
|
538
|
+
status = GetLastError();
|
539
|
+
if (ERROR_INSUFFICIENT_BUFFER == status) {
|
540
|
+
dwBufferSize = dwBufferUsed;
|
541
|
+
pRenderedValues = (PEVT_VARIANT)ALLOCV(vRenderedValues, dwBufferSize);
|
542
|
+
if (pRenderedValues) {
|
543
|
+
EvtRender(hContext,
|
544
|
+
hEvent,
|
545
|
+
EvtRenderEventValues,
|
546
|
+
dwBufferSize,
|
547
|
+
pRenderedValues,
|
548
|
+
&dwBufferUsed,
|
549
|
+
&dwPropertyCount);
|
550
|
+
} else {
|
551
|
+
EvtClose(hContext);
|
552
|
+
rb_raise(rb_eRuntimeError,
|
553
|
+
"Failed to malloc memory with %lu\n", status);
|
554
|
+
}
|
555
|
+
}
|
556
|
+
|
557
|
+
status = GetLastError();
|
558
|
+
if (ERROR_SUCCESS != status) {
|
559
|
+
EvtClose(hContext);
|
560
|
+
ALLOCV_END(vRenderedValues);
|
561
|
+
|
562
|
+
rb_raise(rb_eWinevtQueryError,
|
563
|
+
"EvtRender failed with %lu\n", status);
|
564
|
+
}
|
565
|
+
}
|
566
|
+
|
567
|
+
// EVT_VARIANT value with EvtRenderContextSystem will be decomposed
|
568
|
+
// as the following enum definition:
|
569
|
+
// https://docs.microsoft.com/en-us/windows/win32/api/winevt/ne-winevt-evt_system_property_id
|
570
|
+
rbstr = wstr_to_rb_str(CP_UTF8, pRenderedValues[EvtSystemProviderName].StringVal, -1);
|
571
|
+
rb_hash_aset(hash, rb_str_new2("ProviderName"), rbstr);
|
572
|
+
if (NULL != pRenderedValues[EvtSystemProviderGuid].GuidVal) {
|
573
|
+
const GUID* Guid = pRenderedValues[EvtSystemProviderGuid].GuidVal;
|
574
|
+
StringFromGUID2(*Guid, wsGuid, _countof(wsGuid));
|
575
|
+
rbstr = wstr_to_rb_str(CP_UTF8, wsGuid, -1);
|
576
|
+
rb_hash_aset(hash, rb_str_new2("ProviderGuid"), rbstr);
|
577
|
+
} else {
|
578
|
+
rb_hash_aset(hash, rb_str_new2("ProviderGuid"), Qnil);
|
579
|
+
}
|
580
|
+
|
581
|
+
EventID = pRenderedValues[EvtSystemEventID].UInt16Val;
|
582
|
+
if (EvtVarTypeNull != pRenderedValues[EvtSystemQualifiers].Type) {
|
583
|
+
EventID = MAKELONG(pRenderedValues[EvtSystemEventID].UInt16Val,
|
584
|
+
pRenderedValues[EvtSystemQualifiers].UInt16Val);
|
585
|
+
}
|
586
|
+
rb_hash_aset(hash, rb_str_new2("EventID"), LONG2NUM(EventID));
|
587
|
+
|
588
|
+
rb_hash_aset(hash,
|
589
|
+
rb_str_new2("Version"),
|
590
|
+
(EvtVarTypeNull == pRenderedValues[EvtSystemVersion].Type)
|
591
|
+
? INT2NUM(0)
|
592
|
+
: INT2NUM(pRenderedValues[EvtSystemVersion].ByteVal));
|
593
|
+
rb_hash_aset(hash,
|
594
|
+
rb_str_new2("Level"),
|
595
|
+
(EvtVarTypeNull == pRenderedValues[EvtSystemLevel].Type)
|
596
|
+
? INT2NUM(0)
|
597
|
+
: INT2NUM(pRenderedValues[EvtSystemLevel].ByteVal));
|
598
|
+
rb_hash_aset(hash,
|
599
|
+
rb_str_new2("Task"),
|
600
|
+
(EvtVarTypeNull == pRenderedValues[EvtSystemTask].Type)
|
601
|
+
? INT2NUM(0)
|
602
|
+
: INT2NUM(pRenderedValues[EvtSystemTask].UInt16Val));
|
603
|
+
rb_hash_aset(hash,
|
604
|
+
rb_str_new2("Opcode"),
|
605
|
+
(EvtVarTypeNull == pRenderedValues[EvtSystemOpcode].Type)
|
606
|
+
? INT2NUM(0)
|
607
|
+
: INT2NUM(pRenderedValues[EvtSystemOpcode].ByteVal));
|
608
|
+
_snprintf_s(buffer, _countof(buffer), _TRUNCATE,
|
609
|
+
"0x%llx", pRenderedValues[EvtSystemKeywords].UInt64Val);
|
610
|
+
rb_hash_aset(hash,
|
611
|
+
rb_str_new2("Keywords"),
|
612
|
+
(EvtVarTypeNull == pRenderedValues[EvtSystemKeywords].Type)
|
613
|
+
? Qnil
|
614
|
+
: rb_str_new2(buffer));
|
615
|
+
|
616
|
+
ullTimeStamp = pRenderedValues[EvtSystemTimeCreated].FileTimeVal;
|
617
|
+
ft.dwHighDateTime = (DWORD)((ullTimeStamp >> 32) & 0xFFFFFFFF);
|
618
|
+
ft.dwLowDateTime = (DWORD)(ullTimeStamp & 0xFFFFFFFF);
|
619
|
+
|
620
|
+
FileTimeToSystemTime(&ft, &st);
|
621
|
+
ullNanoseconds =
|
622
|
+
(ullTimeStamp % 10000000) *
|
623
|
+
100; // Display nanoseconds instead of milliseconds for higher resolution
|
624
|
+
_snprintf_s(buffer,
|
625
|
+
_countof(buffer),
|
626
|
+
_TRUNCATE,
|
627
|
+
"%02d/%02d/%02d %02d:%02d:%02d.%llu",
|
628
|
+
st.wYear,
|
629
|
+
st.wMonth,
|
630
|
+
st.wDay,
|
631
|
+
st.wHour,
|
632
|
+
st.wMinute,
|
633
|
+
st.wSecond,
|
634
|
+
ullNanoseconds);
|
635
|
+
rb_hash_aset(hash,
|
636
|
+
rb_str_new2("TimeCreated"),
|
637
|
+
(EvtVarTypeNull == pRenderedValues[EvtSystemKeywords].Type)
|
638
|
+
? Qnil
|
639
|
+
: rb_str_new2(buffer));
|
640
|
+
_snprintf_s(buffer,
|
641
|
+
_countof(buffer),
|
642
|
+
_TRUNCATE,
|
643
|
+
"%llu",
|
644
|
+
pRenderedValues[EvtSystemEventRecordId].UInt64Val);
|
645
|
+
rb_hash_aset(hash,
|
646
|
+
rb_str_new2("EventRecordID"),
|
647
|
+
(EvtVarTypeNull == pRenderedValues[EvtSystemEventRecordId].UInt64Val)
|
648
|
+
? Qnil
|
649
|
+
: rb_str_new2(buffer));
|
650
|
+
|
651
|
+
if (EvtVarTypeNull != pRenderedValues[EvtSystemActivityID].Type) {
|
652
|
+
const GUID* Guid = pRenderedValues[EvtSystemActivityID].GuidVal;
|
653
|
+
StringFromGUID2(*Guid, wsGuid, _countof(wsGuid));
|
654
|
+
rbstr = wstr_to_rb_str(CP_UTF8, wsGuid, -1);
|
655
|
+
rb_hash_aset(hash, rb_str_new2("ActivityID"), rbstr);
|
656
|
+
}
|
657
|
+
|
658
|
+
if (EvtVarTypeNull != pRenderedValues[EvtSystemRelatedActivityID].Type) {
|
659
|
+
const GUID* Guid = pRenderedValues[EvtSystemRelatedActivityID].GuidVal;
|
660
|
+
StringFromGUID2(*Guid, wsGuid, _countof(wsGuid));
|
661
|
+
rbstr = wstr_to_rb_str(CP_UTF8, wsGuid, -1);
|
662
|
+
rb_hash_aset(hash, rb_str_new2("RelatedActivityID"), rbstr);
|
663
|
+
}
|
664
|
+
|
665
|
+
rb_hash_aset(hash,
|
666
|
+
rb_str_new2("ProcessID"),
|
667
|
+
UINT2NUM(pRenderedValues[EvtSystemProcessID].UInt32Val));
|
668
|
+
rb_hash_aset(hash,
|
669
|
+
rb_str_new2("ThreadID"),
|
670
|
+
UINT2NUM(pRenderedValues[EvtSystemThreadID].UInt32Val));
|
671
|
+
rbstr = wstr_to_rb_str(CP_UTF8, pRenderedValues[EvtSystemChannel].StringVal, -1);
|
672
|
+
rb_hash_aset(hash, rb_str_new2("Channel"), rbstr);
|
673
|
+
rbstr = wstr_to_rb_str(CP_UTF8, pRenderedValues[EvtSystemComputer].StringVal, -1);
|
674
|
+
rb_hash_aset(hash, rb_str_new2("Computer"), rbstr);
|
675
|
+
|
676
|
+
if (EvtVarTypeNull != pRenderedValues[EvtSystemUserID].Type) {
|
677
|
+
if (ConvertSidToStringSid(pRenderedValues[EvtSystemUserID].SidVal, &pwsSid)) {
|
678
|
+
rbstr = rb_utf8_str_new_cstr(pwsSid);
|
679
|
+
rb_hash_aset(hash, rb_str_new2("UserID"), rbstr);
|
680
|
+
LocalFree(pwsSid);
|
681
|
+
}
|
682
|
+
}
|
683
|
+
|
684
|
+
EvtClose(hContext);
|
685
|
+
ALLOCV_END(vRenderedValues);
|
686
|
+
|
687
|
+
return hash;
|
688
|
+
}
|