winevt_c 0.1.1-x86-mingw32 → 0.2.0-x86-mingw32
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/example/eventlog.rb +11 -2
- data/example/tailing.rb +13 -2
- data/ext/winevt/winevt.c +6 -737
- data/ext/winevt/winevt_bookmark.c +100 -0
- data/ext/winevt/winevt_c.h +65 -0
- data/ext/winevt/winevt_channel.c +103 -0
- data/ext/winevt/winevt_query.c +245 -0
- data/ext/winevt/winevt_subscribe.c +220 -0
- data/ext/winevt/winevt_utils.c +236 -0
- data/lib/winevt/2.4/winevt.so +0 -0
- data/lib/winevt/2.5/winevt.so +0 -0
- data/lib/winevt/2.6/winevt.so +0 -0
- data/lib/winevt/version.rb +1 -1
- metadata +8 -2
@@ -0,0 +1,220 @@
|
|
1
|
+
#include <winevt_c.h>
|
2
|
+
|
3
|
+
static void subscribe_free(void *ptr);
|
4
|
+
|
5
|
+
static const rb_data_type_t rb_winevt_subscribe_type = {
|
6
|
+
"winevt/subscribe", {
|
7
|
+
0, subscribe_free, 0,
|
8
|
+
}, NULL, NULL,
|
9
|
+
RUBY_TYPED_FREE_IMMEDIATELY
|
10
|
+
};
|
11
|
+
|
12
|
+
static void
|
13
|
+
subscribe_free(void *ptr)
|
14
|
+
{
|
15
|
+
struct WinevtSubscribe *winevtSubscribe = (struct WinevtSubscribe *)ptr;
|
16
|
+
if (winevtSubscribe->signalEvent)
|
17
|
+
CloseHandle(winevtSubscribe->signalEvent);
|
18
|
+
|
19
|
+
if (winevtSubscribe->subscription)
|
20
|
+
EvtClose(winevtSubscribe->subscription);
|
21
|
+
|
22
|
+
if (winevtSubscribe->bookmark)
|
23
|
+
EvtClose(winevtSubscribe->bookmark);
|
24
|
+
|
25
|
+
if (winevtSubscribe->event)
|
26
|
+
EvtClose(winevtSubscribe->event);
|
27
|
+
|
28
|
+
xfree(ptr);
|
29
|
+
}
|
30
|
+
|
31
|
+
static VALUE
|
32
|
+
rb_winevt_subscribe_alloc(VALUE klass)
|
33
|
+
{
|
34
|
+
VALUE obj;
|
35
|
+
struct WinevtSubscribe *winevtSubscribe;
|
36
|
+
obj = TypedData_Make_Struct(klass,
|
37
|
+
struct WinevtSubscribe,
|
38
|
+
&rb_winevt_subscribe_type,
|
39
|
+
winevtSubscribe);
|
40
|
+
return obj;
|
41
|
+
}
|
42
|
+
|
43
|
+
static VALUE
|
44
|
+
rb_winevt_subscribe_initialize(VALUE self)
|
45
|
+
{
|
46
|
+
return Qnil;
|
47
|
+
}
|
48
|
+
|
49
|
+
static VALUE
|
50
|
+
rb_winevt_subscribe_set_tail(VALUE self, VALUE rb_tailing_p)
|
51
|
+
{
|
52
|
+
struct WinevtSubscribe *winevtSubscribe;
|
53
|
+
|
54
|
+
TypedData_Get_Struct(self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
55
|
+
|
56
|
+
winevtSubscribe->tailing = RTEST(rb_tailing_p);
|
57
|
+
|
58
|
+
return Qnil;
|
59
|
+
}
|
60
|
+
|
61
|
+
static VALUE
|
62
|
+
rb_winevt_subscribe_tail_p(VALUE self, VALUE rb_flag)
|
63
|
+
{
|
64
|
+
struct WinevtSubscribe *winevtSubscribe;
|
65
|
+
|
66
|
+
TypedData_Get_Struct(self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
67
|
+
|
68
|
+
return winevtSubscribe->tailing ? Qtrue : Qfalse;
|
69
|
+
}
|
70
|
+
|
71
|
+
static VALUE
|
72
|
+
rb_winevt_subscribe_subscribe(int argc, VALUE argv, VALUE self)
|
73
|
+
{
|
74
|
+
VALUE rb_path, rb_query, rb_bookmark;
|
75
|
+
EVT_HANDLE hSubscription = NULL, hBookmark = NULL;
|
76
|
+
HANDLE hSignalEvent;
|
77
|
+
DWORD len, flags;
|
78
|
+
VALUE wpathBuf, wqueryBuf;
|
79
|
+
PWSTR path, query;
|
80
|
+
DWORD status = ERROR_SUCCESS;
|
81
|
+
struct WinevtBookmark *winevtBookmark;
|
82
|
+
struct WinevtSubscribe *winevtSubscribe;
|
83
|
+
|
84
|
+
hSignalEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
85
|
+
|
86
|
+
TypedData_Get_Struct(self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
87
|
+
|
88
|
+
rb_scan_args(argc, argv, "21", &rb_path, &rb_query, &rb_bookmark);
|
89
|
+
Check_Type(rb_path, T_STRING);
|
90
|
+
Check_Type(rb_query, T_STRING);
|
91
|
+
|
92
|
+
if (rb_obj_is_kind_of(rb_bookmark, rb_cBookmark)) {
|
93
|
+
hBookmark = EventBookMark(rb_bookmark)->bookmark;
|
94
|
+
}
|
95
|
+
|
96
|
+
// path : To wide char
|
97
|
+
len = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(rb_path), RSTRING_LEN(rb_path), NULL, 0);
|
98
|
+
path = ALLOCV_N(WCHAR, wpathBuf, len+1);
|
99
|
+
MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(rb_path), RSTRING_LEN(rb_path), path, len);
|
100
|
+
path[len] = L'\0';
|
101
|
+
|
102
|
+
// query : To wide char
|
103
|
+
len = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(rb_query), RSTRING_LEN(rb_query), NULL, 0);
|
104
|
+
query = ALLOCV_N(WCHAR, wqueryBuf, len+1);
|
105
|
+
MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(rb_query), RSTRING_LEN(rb_query), query, len);
|
106
|
+
query[len] = L'\0';
|
107
|
+
|
108
|
+
if (hBookmark){
|
109
|
+
flags |= EvtSubscribeStartAfterBookmark;
|
110
|
+
} else if (winevtSubscribe->tailing) {
|
111
|
+
flags |= EvtSubscribeToFutureEvents;
|
112
|
+
} else {
|
113
|
+
flags |= EvtSubscribeStartAtOldestRecord;
|
114
|
+
}
|
115
|
+
|
116
|
+
hSubscription = EvtSubscribe(NULL, hSignalEvent, path, query, hBookmark, NULL, NULL, flags);
|
117
|
+
|
118
|
+
winevtSubscribe->signalEvent = hSignalEvent;
|
119
|
+
winevtSubscribe->subscription = hSubscription;
|
120
|
+
if (hBookmark) {
|
121
|
+
winevtSubscribe->bookmark = hBookmark;
|
122
|
+
} else {
|
123
|
+
winevtSubscribe->bookmark = EvtCreateBookmark(NULL);
|
124
|
+
}
|
125
|
+
|
126
|
+
status = GetLastError();
|
127
|
+
|
128
|
+
if (status == ERROR_SUCCESS)
|
129
|
+
return Qtrue;
|
130
|
+
|
131
|
+
return Qfalse;
|
132
|
+
}
|
133
|
+
|
134
|
+
static VALUE
|
135
|
+
rb_winevt_subscribe_next(VALUE self)
|
136
|
+
{
|
137
|
+
EVT_HANDLE event;
|
138
|
+
ULONG count;
|
139
|
+
struct WinevtSubscribe *winevtSubscribe;
|
140
|
+
|
141
|
+
TypedData_Get_Struct(self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
142
|
+
|
143
|
+
if (EvtNext(winevtSubscribe->subscription, 1, &event, INFINITE, 0, &count) != FALSE) {
|
144
|
+
winevtSubscribe->event = event;
|
145
|
+
EvtUpdateBookmark(winevtSubscribe->bookmark, winevtSubscribe->event);
|
146
|
+
|
147
|
+
return Qtrue;
|
148
|
+
}
|
149
|
+
|
150
|
+
return Qfalse;
|
151
|
+
}
|
152
|
+
|
153
|
+
static VALUE
|
154
|
+
rb_winevt_subscribe_render(VALUE self)
|
155
|
+
{
|
156
|
+
char* result;
|
157
|
+
struct WinevtSubscribe *winevtSubscribe;
|
158
|
+
|
159
|
+
TypedData_Get_Struct(self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
160
|
+
result = render_event(winevtSubscribe->event, EvtRenderEventXml);
|
161
|
+
|
162
|
+
return rb_str_new2(result);
|
163
|
+
}
|
164
|
+
|
165
|
+
static VALUE
|
166
|
+
rb_winevt_subscribe_message(VALUE self)
|
167
|
+
{
|
168
|
+
char* result;
|
169
|
+
struct WinevtSubscribe *winevtSubscribe;
|
170
|
+
|
171
|
+
TypedData_Get_Struct(self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
172
|
+
result = get_description(winevtSubscribe->event);
|
173
|
+
|
174
|
+
return rb_str_new2(result);
|
175
|
+
}
|
176
|
+
|
177
|
+
static VALUE
|
178
|
+
rb_winevt_subscribe_each(VALUE self)
|
179
|
+
{
|
180
|
+
struct WinevtSubscribe *winevtSubscribe;
|
181
|
+
|
182
|
+
RETURN_ENUMERATOR(self, 0, 0);
|
183
|
+
|
184
|
+
TypedData_Get_Struct(self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
185
|
+
|
186
|
+
while (rb_winevt_subscribe_next(self)) {
|
187
|
+
rb_yield_values(2, rb_winevt_subscribe_render(self), rb_winevt_subscribe_message(self));
|
188
|
+
}
|
189
|
+
|
190
|
+
return Qnil;
|
191
|
+
}
|
192
|
+
|
193
|
+
static VALUE
|
194
|
+
rb_winevt_subscribe_get_bookmark(VALUE self)
|
195
|
+
{
|
196
|
+
char* result;
|
197
|
+
struct WinevtSubscribe *winevtSubscribe;
|
198
|
+
|
199
|
+
TypedData_Get_Struct(self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
200
|
+
|
201
|
+
result = render_event(winevtSubscribe->bookmark, EvtRenderBookmark);
|
202
|
+
|
203
|
+
return rb_str_new2(result);
|
204
|
+
}
|
205
|
+
|
206
|
+
void Init_winevt_subscribe(VALUE rb_cEventLog)
|
207
|
+
{
|
208
|
+
rb_cSubscribe = rb_define_class_under(rb_cEventLog, "Subscribe", rb_cObject);
|
209
|
+
|
210
|
+
rb_define_alloc_func(rb_cSubscribe, rb_winevt_subscribe_alloc);
|
211
|
+
rb_define_method(rb_cSubscribe, "initialize", rb_winevt_subscribe_initialize, 0);
|
212
|
+
rb_define_method(rb_cSubscribe, "subscribe", rb_winevt_subscribe_subscribe, -1);
|
213
|
+
rb_define_method(rb_cSubscribe, "next", rb_winevt_subscribe_next, 0);
|
214
|
+
rb_define_method(rb_cSubscribe, "render", rb_winevt_subscribe_render, 0);
|
215
|
+
rb_define_method(rb_cSubscribe, "message", rb_winevt_subscribe_message, 0);
|
216
|
+
rb_define_method(rb_cSubscribe, "each", rb_winevt_subscribe_each, 0);
|
217
|
+
rb_define_method(rb_cSubscribe, "bookmark", rb_winevt_subscribe_get_bookmark, 0);
|
218
|
+
rb_define_method(rb_cSubscribe, "tail?", rb_winevt_subscribe_tail_p, 0);
|
219
|
+
rb_define_method(rb_cSubscribe, "tail=", rb_winevt_subscribe_set_tail, 1);
|
220
|
+
}
|
@@ -0,0 +1,236 @@
|
|
1
|
+
#include <winevt_c.h>
|
2
|
+
|
3
|
+
char*
|
4
|
+
wstr_to_mbstr(UINT cp, const WCHAR *wstr, int clen)
|
5
|
+
{
|
6
|
+
char *ptr;
|
7
|
+
int len = WideCharToMultiByte(cp, 0, wstr, clen, NULL, 0, NULL, NULL);
|
8
|
+
if (!(ptr = malloc(len))) return 0;
|
9
|
+
WideCharToMultiByte(cp, 0, wstr, clen, ptr, len, NULL, NULL);
|
10
|
+
|
11
|
+
return ptr;
|
12
|
+
}
|
13
|
+
|
14
|
+
char* render_event(EVT_HANDLE handle, DWORD flags)
|
15
|
+
{
|
16
|
+
PWSTR buffer = NULL;
|
17
|
+
ULONG bufferSize = 0;
|
18
|
+
ULONG bufferSizeNeeded = 0;
|
19
|
+
EVT_HANDLE event;
|
20
|
+
ULONG status, count;
|
21
|
+
char* errBuf;
|
22
|
+
char* result;
|
23
|
+
LPTSTR msgBuf;
|
24
|
+
|
25
|
+
do {
|
26
|
+
if (bufferSizeNeeded > bufferSize) {
|
27
|
+
free(buffer);
|
28
|
+
bufferSize = bufferSizeNeeded;
|
29
|
+
buffer = malloc(bufferSize);
|
30
|
+
if (buffer == NULL) {
|
31
|
+
status = ERROR_OUTOFMEMORY;
|
32
|
+
bufferSize = 0;
|
33
|
+
rb_raise(rb_eWinevtQueryError, "Out of memory");
|
34
|
+
break;
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
if (EvtRender(NULL,
|
39
|
+
handle,
|
40
|
+
flags,
|
41
|
+
bufferSize,
|
42
|
+
buffer,
|
43
|
+
&bufferSizeNeeded,
|
44
|
+
&count) != FALSE) {
|
45
|
+
status = ERROR_SUCCESS;
|
46
|
+
} else {
|
47
|
+
status = GetLastError();
|
48
|
+
}
|
49
|
+
} while (status == ERROR_INSUFFICIENT_BUFFER);
|
50
|
+
|
51
|
+
if (status != ERROR_SUCCESS) {
|
52
|
+
FormatMessage(
|
53
|
+
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
54
|
+
FORMAT_MESSAGE_FROM_SYSTEM |
|
55
|
+
FORMAT_MESSAGE_IGNORE_INSERTS,
|
56
|
+
NULL, status,
|
57
|
+
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
58
|
+
&msgBuf, 0, NULL);
|
59
|
+
result = wstr_to_mbstr(CP_ACP, msgBuf, -1);
|
60
|
+
|
61
|
+
rb_raise(rb_eWinevtQueryError, "ErrorCode: %d\nError: %s\n", status, result);
|
62
|
+
}
|
63
|
+
|
64
|
+
result = wstr_to_mbstr(CP_UTF8, buffer, -1);
|
65
|
+
|
66
|
+
if (buffer)
|
67
|
+
free(buffer);
|
68
|
+
|
69
|
+
return result;
|
70
|
+
}
|
71
|
+
|
72
|
+
char* get_description(EVT_HANDLE handle)
|
73
|
+
{
|
74
|
+
#define MAX_BUFFER 65535
|
75
|
+
WCHAR buffer[4096], file[4096];
|
76
|
+
WCHAR descriptionBuffer[MAX_BUFFER];
|
77
|
+
ULONG bufferSize = 0;
|
78
|
+
ULONG bufferSizeNeeded = 0;
|
79
|
+
EVT_HANDLE event;
|
80
|
+
ULONG status, count;
|
81
|
+
char* errBuf;
|
82
|
+
char* result = "";
|
83
|
+
LPTSTR msgBuf;
|
84
|
+
TCHAR publisherName[MAX_PATH];
|
85
|
+
TCHAR fileName[MAX_PATH];
|
86
|
+
EVT_HANDLE hMetadata = NULL;
|
87
|
+
PEVT_VARIANT values = NULL;
|
88
|
+
PEVT_VARIANT pProperty = NULL;
|
89
|
+
PEVT_VARIANT pTemp = NULL;
|
90
|
+
TCHAR paramEXE[MAX_PATH], messageEXE[MAX_PATH];
|
91
|
+
HMODULE hModule = NULL;
|
92
|
+
|
93
|
+
static PCWSTR eventProperties[] = {L"Event/System/Provider/@Name", L"Event/System/EventID"};
|
94
|
+
EVT_HANDLE renderContext = EvtCreateRenderContext(2, eventProperties, EvtRenderContextValues);
|
95
|
+
if (renderContext == NULL) {
|
96
|
+
rb_raise(rb_eWinevtQueryError, "Failed to create renderContext");
|
97
|
+
}
|
98
|
+
|
99
|
+
if (EvtRender(renderContext,
|
100
|
+
handle,
|
101
|
+
EvtRenderEventValues,
|
102
|
+
_countof(buffer),
|
103
|
+
buffer,
|
104
|
+
&bufferSizeNeeded,
|
105
|
+
&count) != FALSE) {
|
106
|
+
status = ERROR_SUCCESS;
|
107
|
+
} else {
|
108
|
+
status = GetLastError();
|
109
|
+
}
|
110
|
+
|
111
|
+
if (status != ERROR_SUCCESS) {
|
112
|
+
FormatMessage(
|
113
|
+
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
114
|
+
FORMAT_MESSAGE_FROM_SYSTEM |
|
115
|
+
FORMAT_MESSAGE_IGNORE_INSERTS,
|
116
|
+
NULL, status,
|
117
|
+
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
118
|
+
&msgBuf, 0, NULL);
|
119
|
+
result = wstr_to_mbstr(CP_ACP, msgBuf, -1);
|
120
|
+
|
121
|
+
rb_raise(rb_eWinevtQueryError, "ErrorCode: %d\nError: %s\n", status, result);
|
122
|
+
}
|
123
|
+
|
124
|
+
// Obtain buffer as EVT_VARIANT pointer. To avoid ErrorCide 87 in EvtRender.
|
125
|
+
values = (PEVT_VARIANT)buffer;
|
126
|
+
if ((values[0].Type == EvtVarTypeString) && (values[0].StringVal != NULL)) {
|
127
|
+
WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR, values[0].StringVal, -1, publisherName, MAX_PATH, NULL, NULL);
|
128
|
+
}
|
129
|
+
|
130
|
+
DWORD eventId = 0;
|
131
|
+
if (values[1].Type == EvtVarTypeUInt16) {
|
132
|
+
eventId = values[1].UInt16Val;
|
133
|
+
}
|
134
|
+
|
135
|
+
// Open publisher metadata
|
136
|
+
hMetadata = EvtOpenPublisherMetadata(NULL, values[0].StringVal, NULL, MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), SORT_DEFAULT), 0);
|
137
|
+
if (hMetadata == NULL) {
|
138
|
+
// When winevt_c cannot open metadata, then give up to obtain
|
139
|
+
// message file and clean up immediately.
|
140
|
+
goto cleanup;
|
141
|
+
}
|
142
|
+
|
143
|
+
/* TODO: Should we implement parameter file reading in C?
|
144
|
+
// Get the metadata property. If the buffer is not big enough, reallocate the buffer.
|
145
|
+
// Get parameter file first.
|
146
|
+
if (!EvtGetPublisherMetadataProperty(hMetadata, EvtPublisherMetadataParameterFilePath, 0, bufferSize, pProperty, &count)) {
|
147
|
+
status = GetLastError();
|
148
|
+
if (ERROR_INSUFFICIENT_BUFFER == status) {
|
149
|
+
bufferSize = count;
|
150
|
+
pTemp = (PEVT_VARIANT)realloc(pProperty, bufferSize);
|
151
|
+
if (pTemp) {
|
152
|
+
pProperty = pTemp;
|
153
|
+
pTemp = NULL;
|
154
|
+
EvtGetPublisherMetadataProperty(hMetadata, EvtPublisherMetadataParameterFilePath, 0, bufferSize, pProperty, &count);
|
155
|
+
} else {
|
156
|
+
rb_raise(rb_eWinevtQueryError, "realloc failed");
|
157
|
+
}
|
158
|
+
}
|
159
|
+
|
160
|
+
if (ERROR_SUCCESS != (status = GetLastError())) {
|
161
|
+
rb_raise(rb_eWinevtQueryError, "EvtGetPublisherMetadataProperty for parameter file failed with %d\n", GetLastError());
|
162
|
+
}
|
163
|
+
}
|
164
|
+
|
165
|
+
if ((pProperty->Type == EvtVarTypeString) && (pProperty->StringVal != NULL)) {
|
166
|
+
WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR, pProperty->StringVal, -1, fileName, MAX_PATH, NULL, NULL);
|
167
|
+
}
|
168
|
+
if (paramEXE) {
|
169
|
+
ExpandEnvironmentStrings(fileName, paramEXE, _countof(paramEXE));
|
170
|
+
}
|
171
|
+
*/
|
172
|
+
|
173
|
+
// Get the metadata property. If the buffer is not big enough, reallocate the buffer.
|
174
|
+
// Get message file contents.
|
175
|
+
if (!EvtGetPublisherMetadataProperty(hMetadata, EvtPublisherMetadataMessageFilePath, 0, bufferSize, pProperty, &count)) {
|
176
|
+
status = GetLastError();
|
177
|
+
if (ERROR_INSUFFICIENT_BUFFER == status) {
|
178
|
+
bufferSize = count;
|
179
|
+
pTemp = (PEVT_VARIANT)realloc(pProperty, bufferSize);
|
180
|
+
if (pTemp) {
|
181
|
+
pProperty = pTemp;
|
182
|
+
pTemp = NULL;
|
183
|
+
EvtGetPublisherMetadataProperty(hMetadata, EvtPublisherMetadataMessageFilePath, 0, bufferSize, pProperty, &count);
|
184
|
+
} else {
|
185
|
+
rb_raise(rb_eWinevtQueryError, "realloc failed");
|
186
|
+
}
|
187
|
+
}
|
188
|
+
|
189
|
+
if (ERROR_SUCCESS != (status = GetLastError())) {
|
190
|
+
rb_raise(rb_eWinevtQueryError, "EvtGetPublisherMetadataProperty for message file failed with %d\n", GetLastError());
|
191
|
+
}
|
192
|
+
}
|
193
|
+
|
194
|
+
if ((pProperty->Type == EvtVarTypeString) && (pProperty->StringVal != NULL)) {
|
195
|
+
WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR, pProperty->StringVal, -1, fileName, MAX_PATH, NULL, NULL);
|
196
|
+
}
|
197
|
+
if (messageEXE) {
|
198
|
+
ExpandEnvironmentStrings(fileName, messageEXE, _countof(messageEXE));
|
199
|
+
}
|
200
|
+
|
201
|
+
if (messageEXE != NULL) {
|
202
|
+
hModule = LoadLibraryEx(messageEXE, NULL,
|
203
|
+
DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
|
204
|
+
|
205
|
+
if (FormatMessageW(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS,
|
206
|
+
hModule,
|
207
|
+
eventId,
|
208
|
+
0, // Use current code page. Users must specify character encoding in Ruby side.
|
209
|
+
descriptionBuffer,
|
210
|
+
MAX_BUFFER,
|
211
|
+
NULL)) {
|
212
|
+
} else if (!FormatMessageW(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS,
|
213
|
+
hModule,
|
214
|
+
0xB0000000 | eventId,
|
215
|
+
0, // Use current code page. Users must specify character encoding in Ruby side.
|
216
|
+
descriptionBuffer,
|
217
|
+
MAX_BUFFER,
|
218
|
+
NULL)){
|
219
|
+
goto cleanup;
|
220
|
+
}
|
221
|
+
}
|
222
|
+
|
223
|
+
result = wstr_to_mbstr(CP_ACP, descriptionBuffer, -1);
|
224
|
+
|
225
|
+
#undef MAX_BUFFER
|
226
|
+
|
227
|
+
cleanup:
|
228
|
+
|
229
|
+
if (hMetadata)
|
230
|
+
EvtClose(hMetadata);
|
231
|
+
|
232
|
+
if (hModule)
|
233
|
+
FreeLibrary(hModule);
|
234
|
+
|
235
|
+
return result;
|
236
|
+
}
|
data/lib/winevt/2.4/winevt.so
CHANGED
Binary file
|
data/lib/winevt/2.5/winevt.so
CHANGED
Binary file
|
data/lib/winevt/2.6/winevt.so
CHANGED
Binary file
|
data/lib/winevt/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: winevt_c
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: x86-mingw32
|
6
6
|
authors:
|
7
7
|
- Hiroshi Hatake
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-06-
|
11
|
+
date: 2019-06-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -106,6 +106,12 @@ files:
|
|
106
106
|
- example/tailing.rb
|
107
107
|
- ext/winevt/extconf.rb
|
108
108
|
- ext/winevt/winevt.c
|
109
|
+
- ext/winevt/winevt_bookmark.c
|
110
|
+
- ext/winevt/winevt_c.h
|
111
|
+
- ext/winevt/winevt_channel.c
|
112
|
+
- ext/winevt/winevt_query.c
|
113
|
+
- ext/winevt/winevt_subscribe.c
|
114
|
+
- ext/winevt/winevt_utils.c
|
109
115
|
- lib/winevt.rb
|
110
116
|
- lib/winevt/2.4/winevt.so
|
111
117
|
- lib/winevt/2.5/winevt.so
|