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
data/ext/winevt/winevt.c
CHANGED
@@ -1,713 +1,9 @@
|
|
1
|
-
#include <
|
2
|
-
#include <ruby/encoding.h>
|
3
|
-
|
4
|
-
#ifdef __GNUC__
|
5
|
-
# include <w32api.h>
|
6
|
-
# define MINIMUM_WINDOWS_VERSION WindowsVista
|
7
|
-
#else /* __GNUC__ */
|
8
|
-
# define MINIMUM_WINDOWS_VERSION 0x0600 /* Vista */
|
9
|
-
#endif /* __GNUC__ */
|
10
|
-
|
11
|
-
#ifdef _WIN32_WINNT
|
12
|
-
# undef WIN32_WINNT
|
13
|
-
#endif /* WIN32_WINNT */
|
14
|
-
#define _WIN32_WINNT MINIMUM_WINDOWS_VERSION
|
15
|
-
|
16
|
-
#include <winevt.h>
|
17
|
-
#define EventQuery(object) ((struct WinevtQuery *)DATA_PTR(object))
|
18
|
-
#define EventBookMark(object) ((struct WinevtBookmark *)DATA_PTR(object))
|
19
|
-
#define EventChannel(object) ((struct WinevtChannel *)DATA_PTR(object))
|
1
|
+
#include <winevt_c.h>
|
20
2
|
|
21
3
|
VALUE rb_mWinevt;
|
22
4
|
VALUE rb_cEventLog;
|
23
|
-
VALUE rb_cSubscribe;
|
24
|
-
VALUE rb_cChannel;
|
25
|
-
VALUE rb_cQuery;
|
26
|
-
VALUE rb_cBookmark;
|
27
|
-
VALUE rb_eWinevtQueryError;
|
28
5
|
|
29
6
|
static ID id_call;
|
30
|
-
static void channel_free(void *ptr);
|
31
|
-
static void subscribe_free(void *ptr);
|
32
|
-
static void query_free(void *ptr);
|
33
|
-
static void bookmark_free(void *ptr);
|
34
|
-
static char* render_event(EVT_HANDLE handle, DWORD flags);
|
35
|
-
static char* wstr_to_mbstr(UINT cp, const WCHAR *wstr, int clen);
|
36
|
-
|
37
|
-
static const rb_data_type_t rb_winevt_channel_type = {
|
38
|
-
"winevt/channel", {
|
39
|
-
0, channel_free, 0,
|
40
|
-
}, NULL, NULL,
|
41
|
-
RUBY_TYPED_FREE_IMMEDIATELY
|
42
|
-
};
|
43
|
-
|
44
|
-
struct WinevtChannel {
|
45
|
-
EVT_HANDLE channels;
|
46
|
-
};
|
47
|
-
|
48
|
-
static const rb_data_type_t rb_winevt_query_type = {
|
49
|
-
"winevt/query", {
|
50
|
-
0, query_free, 0,
|
51
|
-
}, NULL, NULL,
|
52
|
-
RUBY_TYPED_FREE_IMMEDIATELY
|
53
|
-
};
|
54
|
-
|
55
|
-
struct WinevtQuery {
|
56
|
-
EVT_HANDLE query;
|
57
|
-
EVT_HANDLE event;
|
58
|
-
ULONG count;
|
59
|
-
LONG offset;
|
60
|
-
LONG timeout;
|
61
|
-
};
|
62
|
-
|
63
|
-
static const rb_data_type_t rb_winevt_bookmark_type = {
|
64
|
-
"winevt/bookmark", {
|
65
|
-
0, bookmark_free, 0,
|
66
|
-
}, NULL, NULL,
|
67
|
-
RUBY_TYPED_FREE_IMMEDIATELY
|
68
|
-
};
|
69
|
-
|
70
|
-
struct WinevtBookmark {
|
71
|
-
EVT_HANDLE bookmark;
|
72
|
-
ULONG count;
|
73
|
-
};
|
74
|
-
|
75
|
-
static const rb_data_type_t rb_winevt_subscribe_type = {
|
76
|
-
"winevt/subscribe", {
|
77
|
-
0, subscribe_free, 0,
|
78
|
-
}, NULL, NULL,
|
79
|
-
RUBY_TYPED_FREE_IMMEDIATELY
|
80
|
-
};
|
81
|
-
|
82
|
-
struct WinevtSubscribe {
|
83
|
-
HANDLE signalEvent;
|
84
|
-
EVT_HANDLE subscription;
|
85
|
-
EVT_HANDLE bookmark;
|
86
|
-
EVT_HANDLE event;
|
87
|
-
DWORD flags;
|
88
|
-
BOOL tailing;
|
89
|
-
};
|
90
|
-
|
91
|
-
static void
|
92
|
-
channel_free(void *ptr)
|
93
|
-
{
|
94
|
-
struct WinevtChannel *winevtChannel = (struct WinevtChannel *)ptr;
|
95
|
-
if (winevtChannel->channels)
|
96
|
-
EvtClose(winevtChannel->channels);
|
97
|
-
|
98
|
-
xfree(ptr);
|
99
|
-
}
|
100
|
-
|
101
|
-
static VALUE
|
102
|
-
rb_winevt_channel_alloc(VALUE klass)
|
103
|
-
{
|
104
|
-
VALUE obj;
|
105
|
-
struct WinevtChannel *winevtChannel;
|
106
|
-
obj = TypedData_Make_Struct(klass,
|
107
|
-
struct WinevtChannel,
|
108
|
-
&rb_winevt_channel_type,
|
109
|
-
winevtChannel);
|
110
|
-
return obj;
|
111
|
-
}
|
112
|
-
|
113
|
-
static VALUE
|
114
|
-
rb_winevt_channel_initialize(VALUE klass)
|
115
|
-
{
|
116
|
-
return Qnil;
|
117
|
-
}
|
118
|
-
|
119
|
-
static VALUE
|
120
|
-
rb_winevt_channel_each(VALUE self)
|
121
|
-
{
|
122
|
-
EVT_HANDLE hChannels;
|
123
|
-
struct WinevtChannel *winevtChannel;
|
124
|
-
char *errBuf;
|
125
|
-
char * result;
|
126
|
-
LPWSTR buffer = NULL;
|
127
|
-
LPWSTR temp = NULL;
|
128
|
-
DWORD bufferSize = 0;
|
129
|
-
DWORD bufferUsed = 0;
|
130
|
-
DWORD status = ERROR_SUCCESS;
|
131
|
-
|
132
|
-
RETURN_ENUMERATOR(self, 0, 0);
|
133
|
-
|
134
|
-
TypedData_Get_Struct(self, struct WinevtChannel, &rb_winevt_channel_type, winevtChannel);
|
135
|
-
|
136
|
-
hChannels = EvtOpenChannelEnum(NULL, 0);
|
137
|
-
|
138
|
-
if (hChannels) {
|
139
|
-
winevtChannel->channels = hChannels;
|
140
|
-
} else {
|
141
|
-
sprintf(errBuf, "Failed to enumerate channels with %s\n", GetLastError());
|
142
|
-
rb_raise(rb_eRuntimeError, errBuf);
|
143
|
-
}
|
144
|
-
|
145
|
-
while (1) {
|
146
|
-
if (!EvtNextChannelPath(winevtChannel->channels, bufferSize, buffer, &bufferUsed)) {
|
147
|
-
status = GetLastError();
|
148
|
-
|
149
|
-
if (ERROR_NO_MORE_ITEMS == status) {
|
150
|
-
break;
|
151
|
-
} else if (ERROR_INSUFFICIENT_BUFFER == status) {
|
152
|
-
bufferSize = bufferUsed;
|
153
|
-
temp = (LPWSTR)realloc(buffer, bufferSize * sizeof(WCHAR));
|
154
|
-
if (temp) {
|
155
|
-
buffer = temp;
|
156
|
-
temp = NULL;
|
157
|
-
EvtNextChannelPath(winevtChannel->channels, bufferSize, buffer, &bufferUsed);
|
158
|
-
} else {
|
159
|
-
status = ERROR_OUTOFMEMORY;
|
160
|
-
rb_raise(rb_eRuntimeError, "realloc failed");
|
161
|
-
}
|
162
|
-
} else {
|
163
|
-
sprintf(errBuf, "EvtNextChannelPath failed with %lu.\n", status);
|
164
|
-
rb_raise(rb_eRuntimeError, errBuf);
|
165
|
-
}
|
166
|
-
}
|
167
|
-
|
168
|
-
result = wstr_to_mbstr(CP_UTF8, buffer, -1);
|
169
|
-
|
170
|
-
rb_yield(rb_str_new2(result));
|
171
|
-
}
|
172
|
-
|
173
|
-
return Qnil;
|
174
|
-
}
|
175
|
-
|
176
|
-
static char *
|
177
|
-
wstr_to_mbstr(UINT cp, const WCHAR *wstr, int clen)
|
178
|
-
{
|
179
|
-
char *ptr;
|
180
|
-
int len = WideCharToMultiByte(cp, 0, wstr, clen, NULL, 0, NULL, NULL);
|
181
|
-
if (!(ptr = malloc(len))) return 0;
|
182
|
-
WideCharToMultiByte(cp, 0, wstr, clen, ptr, len, NULL, NULL);
|
183
|
-
|
184
|
-
return ptr;
|
185
|
-
}
|
186
|
-
|
187
|
-
|
188
|
-
static void
|
189
|
-
subscribe_free(void *ptr)
|
190
|
-
{
|
191
|
-
struct WinevtSubscribe *winevtSubscribe = (struct WinevtSubscribe *)ptr;
|
192
|
-
if (winevtSubscribe->signalEvent)
|
193
|
-
CloseHandle(winevtSubscribe->signalEvent);
|
194
|
-
|
195
|
-
if (winevtSubscribe->subscription)
|
196
|
-
EvtClose(winevtSubscribe->subscription);
|
197
|
-
|
198
|
-
if (winevtSubscribe->bookmark)
|
199
|
-
EvtClose(winevtSubscribe->bookmark);
|
200
|
-
|
201
|
-
if (winevtSubscribe->event)
|
202
|
-
EvtClose(winevtSubscribe->event);
|
203
|
-
|
204
|
-
xfree(ptr);
|
205
|
-
}
|
206
|
-
|
207
|
-
static VALUE
|
208
|
-
rb_winevt_subscribe_alloc(VALUE klass)
|
209
|
-
{
|
210
|
-
VALUE obj;
|
211
|
-
struct WinevtSubscribe *winevtSubscribe;
|
212
|
-
obj = TypedData_Make_Struct(klass,
|
213
|
-
struct WinevtSubscribe,
|
214
|
-
&rb_winevt_subscribe_type,
|
215
|
-
winevtSubscribe);
|
216
|
-
return obj;
|
217
|
-
}
|
218
|
-
|
219
|
-
static VALUE
|
220
|
-
rb_winevt_subscribe_initialize(VALUE self)
|
221
|
-
{
|
222
|
-
return Qnil;
|
223
|
-
}
|
224
|
-
|
225
|
-
static VALUE
|
226
|
-
rb_winevt_subscribe_set_tail(VALUE self, VALUE rb_tailing_p)
|
227
|
-
{
|
228
|
-
struct WinevtSubscribe *winevtSubscribe;
|
229
|
-
|
230
|
-
TypedData_Get_Struct(self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
231
|
-
|
232
|
-
winevtSubscribe->tailing = RTEST(rb_tailing_p);
|
233
|
-
|
234
|
-
return Qnil;
|
235
|
-
}
|
236
|
-
|
237
|
-
static VALUE
|
238
|
-
rb_winevt_subscribe_tail_p(VALUE self, VALUE rb_flag)
|
239
|
-
{
|
240
|
-
struct WinevtSubscribe *winevtSubscribe;
|
241
|
-
|
242
|
-
TypedData_Get_Struct(self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
243
|
-
|
244
|
-
return winevtSubscribe->tailing ? Qtrue : Qfalse;
|
245
|
-
}
|
246
|
-
|
247
|
-
static VALUE
|
248
|
-
rb_winevt_subscribe_subscribe(int argc, VALUE argv, VALUE self)
|
249
|
-
{
|
250
|
-
VALUE rb_path, rb_query, rb_bookmark;
|
251
|
-
EVT_HANDLE hSubscription = NULL, hBookmark = NULL;
|
252
|
-
HANDLE hSignalEvent;
|
253
|
-
DWORD len, flags;
|
254
|
-
VALUE wpathBuf, wqueryBuf;
|
255
|
-
PWSTR path, query;
|
256
|
-
DWORD status = ERROR_SUCCESS;
|
257
|
-
struct WinevtBookmark *winevtBookmark;
|
258
|
-
struct WinevtSubscribe *winevtSubscribe;
|
259
|
-
|
260
|
-
hSignalEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
261
|
-
|
262
|
-
TypedData_Get_Struct(self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
263
|
-
|
264
|
-
rb_scan_args(argc, argv, "21", &rb_path, &rb_query, &rb_bookmark);
|
265
|
-
Check_Type(rb_path, T_STRING);
|
266
|
-
Check_Type(rb_query, T_STRING);
|
267
|
-
|
268
|
-
if (rb_obj_is_kind_of(rb_bookmark, rb_cBookmark)) {
|
269
|
-
hBookmark = EventBookMark(rb_bookmark)->bookmark;
|
270
|
-
}
|
271
|
-
|
272
|
-
// path : To wide char
|
273
|
-
len = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(rb_path), RSTRING_LEN(rb_path), NULL, 0);
|
274
|
-
path = ALLOCV_N(WCHAR, wpathBuf, len+1);
|
275
|
-
MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(rb_path), RSTRING_LEN(rb_path), path, len);
|
276
|
-
path[len] = L'\0';
|
277
|
-
|
278
|
-
// query : To wide char
|
279
|
-
len = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(rb_query), RSTRING_LEN(rb_query), NULL, 0);
|
280
|
-
query = ALLOCV_N(WCHAR, wqueryBuf, len+1);
|
281
|
-
MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(rb_query), RSTRING_LEN(rb_query), query, len);
|
282
|
-
query[len] = L'\0';
|
283
|
-
|
284
|
-
if (hBookmark){
|
285
|
-
flags |= EvtSubscribeStartAfterBookmark;
|
286
|
-
} else if (winevtSubscribe->tailing) {
|
287
|
-
flags |= EvtSubscribeToFutureEvents;
|
288
|
-
} else {
|
289
|
-
flags |= EvtSubscribeStartAtOldestRecord;
|
290
|
-
}
|
291
|
-
|
292
|
-
hSubscription = EvtSubscribe(NULL, hSignalEvent, path, query, hBookmark, NULL, NULL, flags);
|
293
|
-
|
294
|
-
winevtSubscribe->signalEvent = hSignalEvent;
|
295
|
-
winevtSubscribe->subscription = hSubscription;
|
296
|
-
if (hBookmark) {
|
297
|
-
winevtSubscribe->bookmark = hBookmark;
|
298
|
-
} else {
|
299
|
-
winevtSubscribe->bookmark = EvtCreateBookmark(NULL);
|
300
|
-
}
|
301
|
-
|
302
|
-
status = GetLastError();
|
303
|
-
|
304
|
-
if (status == ERROR_SUCCESS)
|
305
|
-
return Qtrue;
|
306
|
-
|
307
|
-
return Qfalse;
|
308
|
-
}
|
309
|
-
|
310
|
-
static VALUE
|
311
|
-
rb_winevt_subscribe_next(VALUE self)
|
312
|
-
{
|
313
|
-
EVT_HANDLE event;
|
314
|
-
ULONG count;
|
315
|
-
struct WinevtSubscribe *winevtSubscribe;
|
316
|
-
|
317
|
-
TypedData_Get_Struct(self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
318
|
-
|
319
|
-
if (EvtNext(winevtSubscribe->subscription, 1, &event, INFINITE, 0, &count) != FALSE) {
|
320
|
-
winevtSubscribe->event = event;
|
321
|
-
EvtUpdateBookmark(winevtSubscribe->bookmark, winevtSubscribe->event);
|
322
|
-
|
323
|
-
return Qtrue;
|
324
|
-
}
|
325
|
-
|
326
|
-
return Qfalse;
|
327
|
-
}
|
328
|
-
|
329
|
-
static VALUE
|
330
|
-
rb_winevt_subscribe_render(VALUE self)
|
331
|
-
{
|
332
|
-
char* result;
|
333
|
-
struct WinevtSubscribe *winevtSubscribe;
|
334
|
-
|
335
|
-
TypedData_Get_Struct(self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
336
|
-
result = render_event(winevtSubscribe->event, EvtRenderEventXml);
|
337
|
-
|
338
|
-
return rb_str_new2(result);
|
339
|
-
}
|
340
|
-
|
341
|
-
static VALUE
|
342
|
-
rb_winevt_subscribe_each(VALUE self)
|
343
|
-
{
|
344
|
-
struct WinevtSubscribe *winevtSubscribe;
|
345
|
-
|
346
|
-
RETURN_ENUMERATOR(self, 0, 0);
|
347
|
-
|
348
|
-
TypedData_Get_Struct(self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
349
|
-
|
350
|
-
while (rb_winevt_subscribe_next(self)) {
|
351
|
-
rb_yield(rb_winevt_subscribe_render(self));
|
352
|
-
}
|
353
|
-
|
354
|
-
return Qnil;
|
355
|
-
}
|
356
|
-
|
357
|
-
static VALUE
|
358
|
-
rb_winevt_subscribe_get_bookmark(VALUE self)
|
359
|
-
{
|
360
|
-
char* result;
|
361
|
-
struct WinevtSubscribe *winevtSubscribe;
|
362
|
-
|
363
|
-
TypedData_Get_Struct(self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
|
364
|
-
|
365
|
-
result = render_event(winevtSubscribe->bookmark, EvtRenderBookmark);
|
366
|
-
|
367
|
-
return rb_str_new2(result);
|
368
|
-
}
|
369
|
-
|
370
|
-
static void
|
371
|
-
bookmark_free(void *ptr)
|
372
|
-
{
|
373
|
-
struct WinevtBookmark *winevtBookmark = (struct WinevtBookmark *)ptr;
|
374
|
-
if (winevtBookmark->bookmark)
|
375
|
-
EvtClose(winevtBookmark->bookmark);
|
376
|
-
|
377
|
-
xfree(ptr);
|
378
|
-
}
|
379
|
-
|
380
|
-
static VALUE
|
381
|
-
rb_winevt_bookmark_alloc(VALUE klass)
|
382
|
-
{
|
383
|
-
VALUE obj;
|
384
|
-
struct WinevtBookmark *winevtBookmark;
|
385
|
-
obj = TypedData_Make_Struct(klass,
|
386
|
-
struct WinevtBookmark,
|
387
|
-
&rb_winevt_bookmark_type,
|
388
|
-
winevtBookmark);
|
389
|
-
return obj;
|
390
|
-
}
|
391
|
-
|
392
|
-
static VALUE
|
393
|
-
rb_winevt_bookmark_initialize(int argc, VALUE *argv, VALUE self)
|
394
|
-
{
|
395
|
-
PWSTR bookmarkXml;
|
396
|
-
VALUE wbookmarkXmlBuf;
|
397
|
-
DWORD len;
|
398
|
-
struct WinevtBookmark *winevtBookmark;
|
399
|
-
|
400
|
-
TypedData_Get_Struct(self, struct WinevtBookmark, &rb_winevt_bookmark_type, winevtBookmark);
|
401
|
-
|
402
|
-
if (argc == 0) {
|
403
|
-
winevtBookmark->bookmark = EvtCreateBookmark(NULL);
|
404
|
-
} else if (argc == 1) {
|
405
|
-
VALUE rb_bookmarkXml;
|
406
|
-
rb_scan_args(argc, argv, "10", &rb_bookmarkXml);
|
407
|
-
Check_Type(rb_bookmarkXml, T_STRING);
|
408
|
-
|
409
|
-
// bookmarkXml : To wide char
|
410
|
-
len = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(rb_bookmarkXml), RSTRING_LEN(rb_bookmarkXml), NULL, 0);
|
411
|
-
bookmarkXml = ALLOCV_N(WCHAR, wbookmarkXmlBuf, len+1);
|
412
|
-
MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(rb_bookmarkXml), RSTRING_LEN(rb_bookmarkXml), bookmarkXml, len);
|
413
|
-
bookmarkXml[len] = L'\0';
|
414
|
-
winevtBookmark->bookmark = EvtCreateBookmark(bookmarkXml);
|
415
|
-
ALLOCV_END(wbookmarkXmlBuf);
|
416
|
-
}
|
417
|
-
|
418
|
-
return Qnil;
|
419
|
-
}
|
420
|
-
|
421
|
-
static VALUE
|
422
|
-
rb_winevt_bookmark_update(VALUE self, VALUE event)
|
423
|
-
{
|
424
|
-
struct WinevtQuery *winevtQuery;
|
425
|
-
struct WinevtBookmark *winevtBookmark;
|
426
|
-
|
427
|
-
winevtQuery = EventQuery(event);
|
428
|
-
|
429
|
-
TypedData_Get_Struct(self, struct WinevtBookmark, &rb_winevt_bookmark_type, winevtBookmark);
|
430
|
-
|
431
|
-
if(EvtUpdateBookmark(winevtBookmark->bookmark, winevtQuery->event))
|
432
|
-
return Qtrue;
|
433
|
-
|
434
|
-
return Qfalse;
|
435
|
-
}
|
436
|
-
|
437
|
-
static VALUE
|
438
|
-
rb_winevt_bookmark_render(VALUE self)
|
439
|
-
{
|
440
|
-
char* result;
|
441
|
-
struct WinevtBookmark *winevtBookmark;
|
442
|
-
|
443
|
-
TypedData_Get_Struct(self, struct WinevtBookmark, &rb_winevt_bookmark_type, winevtBookmark);
|
444
|
-
|
445
|
-
result = render_event(winevtBookmark->bookmark, EvtRenderBookmark);
|
446
|
-
|
447
|
-
return rb_str_new2(result);
|
448
|
-
}
|
449
|
-
|
450
|
-
static void
|
451
|
-
query_free(void *ptr)
|
452
|
-
{
|
453
|
-
struct WinevtQuery *winevtQuery = (struct WinevtQuery *)ptr;
|
454
|
-
if (winevtQuery->query)
|
455
|
-
EvtClose(winevtQuery->query);
|
456
|
-
|
457
|
-
if (winevtQuery->event)
|
458
|
-
EvtClose(winevtQuery->event);
|
459
|
-
|
460
|
-
xfree(ptr);
|
461
|
-
}
|
462
|
-
|
463
|
-
static VALUE
|
464
|
-
rb_winevt_query_alloc(VALUE klass)
|
465
|
-
{
|
466
|
-
VALUE obj;
|
467
|
-
struct WinevtQuery *winevtQuery;
|
468
|
-
obj = TypedData_Make_Struct(klass,
|
469
|
-
struct WinevtQuery,
|
470
|
-
&rb_winevt_query_type,
|
471
|
-
winevtQuery);
|
472
|
-
return obj;
|
473
|
-
}
|
474
|
-
|
475
|
-
static VALUE
|
476
|
-
rb_winevt_query_initialize(VALUE self, VALUE channel, VALUE xpath)
|
477
|
-
{
|
478
|
-
PWSTR evtChannel, evtXPath;
|
479
|
-
struct WinevtQuery *winevtQuery;
|
480
|
-
DWORD len;
|
481
|
-
VALUE wchannelBuf, wpathBuf;
|
482
|
-
|
483
|
-
Check_Type(channel, T_STRING);
|
484
|
-
Check_Type(xpath, T_STRING);
|
485
|
-
|
486
|
-
// channel : To wide char
|
487
|
-
len = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), NULL, 0);
|
488
|
-
evtChannel = ALLOCV_N(WCHAR, wchannelBuf, len+1);
|
489
|
-
MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(channel), RSTRING_LEN(channel), evtChannel, len);
|
490
|
-
evtChannel[len] = L'\0';
|
491
|
-
|
492
|
-
// xpath : To wide char
|
493
|
-
len = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(xpath), RSTRING_LEN(xpath), NULL, 0);
|
494
|
-
evtXPath = ALLOCV_N(WCHAR, wpathBuf, len+1);
|
495
|
-
MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(xpath), RSTRING_LEN(xpath), evtXPath, len);
|
496
|
-
evtXPath[len] = L'\0';
|
497
|
-
|
498
|
-
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
499
|
-
|
500
|
-
winevtQuery->query = EvtQuery(NULL, evtChannel, evtXPath,
|
501
|
-
EvtQueryChannelPath | EvtQueryTolerateQueryErrors);
|
502
|
-
winevtQuery->offset = 0L;
|
503
|
-
winevtQuery->timeout = 0L;
|
504
|
-
|
505
|
-
ALLOCV_END(wchannelBuf);
|
506
|
-
ALLOCV_END(wpathBuf);
|
507
|
-
|
508
|
-
return Qnil;
|
509
|
-
}
|
510
|
-
|
511
|
-
static VALUE
|
512
|
-
rb_winevt_query_get_offset(VALUE self, VALUE offset)
|
513
|
-
{
|
514
|
-
struct WinevtQuery *winevtQuery;
|
515
|
-
|
516
|
-
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
517
|
-
|
518
|
-
return LONG2NUM(winevtQuery->offset);
|
519
|
-
}
|
520
|
-
|
521
|
-
static VALUE
|
522
|
-
rb_winevt_query_set_offset(VALUE self, VALUE offset)
|
523
|
-
{
|
524
|
-
struct WinevtQuery *winevtQuery;
|
525
|
-
|
526
|
-
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
527
|
-
|
528
|
-
winevtQuery->offset = NUM2LONG(offset);
|
529
|
-
|
530
|
-
return Qnil;
|
531
|
-
}
|
532
|
-
|
533
|
-
static VALUE
|
534
|
-
rb_winevt_query_get_timeout(VALUE self, VALUE timeout)
|
535
|
-
{
|
536
|
-
struct WinevtQuery *winevtQuery;
|
537
|
-
|
538
|
-
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
539
|
-
|
540
|
-
return LONG2NUM(winevtQuery->timeout);
|
541
|
-
}
|
542
|
-
|
543
|
-
static VALUE
|
544
|
-
rb_winevt_query_set_timeout(VALUE self, VALUE timeout)
|
545
|
-
{
|
546
|
-
struct WinevtQuery *winevtQuery;
|
547
|
-
|
548
|
-
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
549
|
-
|
550
|
-
winevtQuery->timeout = NUM2LONG(timeout);
|
551
|
-
|
552
|
-
return Qnil;
|
553
|
-
}
|
554
|
-
|
555
|
-
static VALUE
|
556
|
-
rb_winevt_query_next(VALUE self)
|
557
|
-
{
|
558
|
-
EVT_HANDLE event;
|
559
|
-
ULONG count;
|
560
|
-
struct WinevtQuery *winevtQuery;
|
561
|
-
|
562
|
-
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
563
|
-
|
564
|
-
if (EvtNext(winevtQuery->query, 1, &event, INFINITE, 0, &count) != FALSE) {
|
565
|
-
winevtQuery->event = event;
|
566
|
-
winevtQuery->count = count;
|
567
|
-
|
568
|
-
return Qtrue;
|
569
|
-
}
|
570
|
-
|
571
|
-
return Qfalse;
|
572
|
-
}
|
573
|
-
|
574
|
-
static char* render_event(EVT_HANDLE handle, DWORD flags)
|
575
|
-
{
|
576
|
-
PWSTR buffer = NULL;
|
577
|
-
ULONG bufferSize = 0;
|
578
|
-
ULONG bufferSizeNeeded = 0;
|
579
|
-
EVT_HANDLE event;
|
580
|
-
ULONG status, count;
|
581
|
-
char* errBuf;
|
582
|
-
char* result;
|
583
|
-
LPTSTR msgBuf;
|
584
|
-
|
585
|
-
do {
|
586
|
-
if (bufferSizeNeeded > bufferSize) {
|
587
|
-
free(buffer);
|
588
|
-
bufferSize = bufferSizeNeeded;
|
589
|
-
buffer = malloc(bufferSize);
|
590
|
-
if (buffer == NULL) {
|
591
|
-
status = ERROR_OUTOFMEMORY;
|
592
|
-
bufferSize = 0;
|
593
|
-
rb_raise(rb_eWinevtQueryError, "Out of memory");
|
594
|
-
break;
|
595
|
-
}
|
596
|
-
}
|
597
|
-
|
598
|
-
if (EvtRender(NULL,
|
599
|
-
handle,
|
600
|
-
flags,
|
601
|
-
bufferSize,
|
602
|
-
buffer,
|
603
|
-
&bufferSizeNeeded,
|
604
|
-
&count) != FALSE) {
|
605
|
-
status = ERROR_SUCCESS;
|
606
|
-
} else {
|
607
|
-
status = GetLastError();
|
608
|
-
}
|
609
|
-
} while (status == ERROR_INSUFFICIENT_BUFFER);
|
610
|
-
|
611
|
-
if (status != ERROR_SUCCESS) {
|
612
|
-
FormatMessage(
|
613
|
-
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
614
|
-
FORMAT_MESSAGE_FROM_SYSTEM |
|
615
|
-
FORMAT_MESSAGE_IGNORE_INSERTS,
|
616
|
-
NULL, status,
|
617
|
-
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
618
|
-
&msgBuf, 0, NULL);
|
619
|
-
result = wstr_to_mbstr(CP_ACP, msgBuf, -1);
|
620
|
-
|
621
|
-
rb_raise(rb_eWinevtQueryError, "ErrorCode: %d\nError: %s\n", status, result);
|
622
|
-
}
|
623
|
-
|
624
|
-
result = wstr_to_mbstr(CP_UTF8, buffer, -1);
|
625
|
-
|
626
|
-
if (buffer)
|
627
|
-
free(buffer);
|
628
|
-
|
629
|
-
return result;
|
630
|
-
}
|
631
|
-
|
632
|
-
static VALUE
|
633
|
-
rb_winevt_query_render(VALUE self)
|
634
|
-
{
|
635
|
-
char* result;
|
636
|
-
struct WinevtQuery *winevtQuery;
|
637
|
-
|
638
|
-
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
639
|
-
result = render_event(winevtQuery->event, EvtRenderEventXml);
|
640
|
-
|
641
|
-
return rb_str_new2(result);
|
642
|
-
}
|
643
|
-
|
644
|
-
static DWORD
|
645
|
-
get_evt_seek_flag_from_cstr(char* flag_str)
|
646
|
-
{
|
647
|
-
if (strcmp(flag_str, "first") == 0)
|
648
|
-
return EvtSeekRelativeToFirst;
|
649
|
-
else if (strcmp(flag_str, "last") == 0)
|
650
|
-
return EvtSeekRelativeToLast;
|
651
|
-
else if (strcmp(flag_str, "current") == 0)
|
652
|
-
return EvtSeekRelativeToCurrent;
|
653
|
-
else if (strcmp(flag_str, "bookmark") == 0)
|
654
|
-
return EvtSeekRelativeToBookmark;
|
655
|
-
else if (strcmp(flag_str, "originmask") == 0)
|
656
|
-
return EvtSeekOriginMask;
|
657
|
-
else if (strcmp(flag_str, "strict") == 0)
|
658
|
-
return EvtSeekStrict;
|
659
|
-
}
|
660
|
-
|
661
|
-
static VALUE
|
662
|
-
rb_winevt_query_seek(VALUE self, VALUE bookmark_or_flag)
|
663
|
-
{
|
664
|
-
struct WinevtQuery *winevtQuery;
|
665
|
-
struct WinevtBookmark *winevtBookmark = NULL;
|
666
|
-
DWORD status;
|
667
|
-
DWORD flag;
|
668
|
-
|
669
|
-
switch (TYPE(bookmark_or_flag)) {
|
670
|
-
case T_SYMBOL:
|
671
|
-
flag = get_evt_seek_flag_from_cstr(RSTRING_PTR(rb_sym2str(bookmark_or_flag)));
|
672
|
-
break;
|
673
|
-
case T_STRING:
|
674
|
-
flag = get_evt_seek_flag_from_cstr(StringValueCStr(bookmark_or_flag));
|
675
|
-
break;
|
676
|
-
default:
|
677
|
-
if (!rb_obj_is_kind_of(bookmark_or_flag, rb_cBookmark))
|
678
|
-
rb_raise(rb_eArgError, "Expected a String or a Symbol or a Bookmark instance");
|
679
|
-
|
680
|
-
winevtBookmark = EventBookMark(bookmark_or_flag);
|
681
|
-
}
|
682
|
-
|
683
|
-
if (winevtBookmark) {
|
684
|
-
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
685
|
-
if (EvtSeek(winevtQuery->query, winevtQuery->offset, winevtBookmark->bookmark, winevtQuery->timeout, EvtSeekRelativeToBookmark))
|
686
|
-
return Qtrue;
|
687
|
-
} else {
|
688
|
-
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
689
|
-
if (EvtSeek(winevtQuery->query, winevtQuery->offset, NULL, winevtQuery->timeout, flag))
|
690
|
-
return Qtrue;
|
691
|
-
}
|
692
|
-
|
693
|
-
return Qfalse;
|
694
|
-
}
|
695
|
-
|
696
|
-
static VALUE
|
697
|
-
rb_winevt_query_each(VALUE self)
|
698
|
-
{
|
699
|
-
struct WinevtQuery *winevtQuery;
|
700
|
-
|
701
|
-
RETURN_ENUMERATOR(self, 0, 0);
|
702
|
-
|
703
|
-
TypedData_Get_Struct(self, struct WinevtQuery, &rb_winevt_query_type, winevtQuery);
|
704
|
-
|
705
|
-
while (rb_winevt_query_next(self)) {
|
706
|
-
rb_yield(rb_winevt_query_render(self));
|
707
|
-
}
|
708
|
-
|
709
|
-
return Qnil;
|
710
|
-
}
|
711
7
|
|
712
8
|
void
|
713
9
|
Init_winevt(void)
|
@@ -715,40 +11,13 @@ Init_winevt(void)
|
|
715
11
|
rb_mWinevt = rb_define_module("Winevt");
|
716
12
|
rb_cEventLog = rb_define_class_under(rb_mWinevt, "EventLog", rb_cObject);
|
717
13
|
rb_cQuery = rb_define_class_under(rb_cEventLog, "Query", rb_cObject);
|
718
|
-
rb_cBookmark = rb_define_class_under(rb_cEventLog, "Bookmark", rb_cObject);
|
719
|
-
rb_cChannel = rb_define_class_under(rb_cEventLog, "Channel", rb_cObject);
|
720
14
|
rb_cSubscribe = rb_define_class_under(rb_cEventLog, "Subscribe", rb_cObject);
|
721
15
|
rb_eWinevtQueryError = rb_define_class_under(rb_cQuery, "Error", rb_eStandardError);
|
722
16
|
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
rb_define_method(rb_cSubscribe, "subscribe", rb_winevt_subscribe_subscribe, -1);
|
728
|
-
rb_define_method(rb_cSubscribe, "next", rb_winevt_subscribe_next, 0);
|
729
|
-
rb_define_method(rb_cSubscribe, "render", rb_winevt_subscribe_render, 0);
|
730
|
-
rb_define_method(rb_cSubscribe, "each", rb_winevt_subscribe_each, 0);
|
731
|
-
rb_define_method(rb_cSubscribe, "bookmark", rb_winevt_subscribe_get_bookmark, 0);
|
732
|
-
rb_define_method(rb_cSubscribe, "tail?", rb_winevt_subscribe_tail_p, 0);
|
733
|
-
rb_define_method(rb_cSubscribe, "tail=", rb_winevt_subscribe_set_tail, 1);
|
17
|
+
Init_winevt_channel(rb_cEventLog);
|
18
|
+
Init_winevt_bookmark(rb_cEventLog);
|
19
|
+
Init_winevt_query(rb_cEventLog);
|
20
|
+
Init_winevt_subscribe(rb_cEventLog);
|
734
21
|
|
735
|
-
|
736
|
-
rb_define_method(rb_cChannel, "initialize", rb_winevt_channel_initialize, 0);
|
737
|
-
rb_define_method(rb_cChannel, "each", rb_winevt_channel_each, 0);
|
738
|
-
|
739
|
-
rb_define_alloc_func(rb_cBookmark, rb_winevt_bookmark_alloc);
|
740
|
-
rb_define_method(rb_cBookmark, "initialize", rb_winevt_bookmark_initialize, -1);
|
741
|
-
rb_define_method(rb_cBookmark, "update", rb_winevt_bookmark_update, 1);
|
742
|
-
rb_define_method(rb_cBookmark, "render", rb_winevt_bookmark_render, 0);
|
743
|
-
|
744
|
-
rb_define_alloc_func(rb_cQuery, rb_winevt_query_alloc);
|
745
|
-
rb_define_method(rb_cQuery, "initialize", rb_winevt_query_initialize, 2);
|
746
|
-
rb_define_method(rb_cQuery, "next", rb_winevt_query_next, 0);
|
747
|
-
rb_define_method(rb_cQuery, "render", rb_winevt_query_render, 0);
|
748
|
-
rb_define_method(rb_cQuery, "seek", rb_winevt_query_seek, 1);
|
749
|
-
rb_define_method(rb_cQuery, "offset", rb_winevt_query_get_offset, 0);
|
750
|
-
rb_define_method(rb_cQuery, "offset=", rb_winevt_query_set_offset, 1);
|
751
|
-
rb_define_method(rb_cQuery, "timeout", rb_winevt_query_get_timeout, 0);
|
752
|
-
rb_define_method(rb_cQuery, "timeout=", rb_winevt_query_set_timeout, 1);
|
753
|
-
rb_define_method(rb_cQuery, "each", rb_winevt_query_each, 0);
|
22
|
+
id_call = rb_intern("call");
|
754
23
|
}
|