winevt_c 0.1.1-x64-mingw32 → 0.2.0-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bfa938cac989d5c12314ad59291a24b89a80312f8c514d2f99f77d35d2272370
4
- data.tar.gz: 00c375feaa5bc65c1d23dba9ceddaa215ab6a16f82170c1178661aba02c092d4
3
+ metadata.gz: eac2ae7b87b73d1250e31a3e488833c354765182bce3c3a860d1be2a055d29e5
4
+ data.tar.gz: a5bccfadaea2b9aaa47a8e41ef7210c2be4cad1c27eea1c6e50c07ea1ac5dc68
5
5
  SHA512:
6
- metadata.gz: 41a89c35d39ea59a78f59cb09afd273865952954ecd8c6bc22e02cd9be16944e8b218f1492abecc0772ab25a0f6336476e4a888d6d1ef4817e2b1bdbf8f1ace6
7
- data.tar.gz: c2700a0f9ab3141fd2d00649a6df35b70a8bec2a045b8227e2a48b2aa3e148f3f2551459fa2e6212f8ee5e0793c69bad922cfab870adda83e050cf2aa7a95417
6
+ metadata.gz: be0a861927a96a84d1c7ac1eafc674c35f07d2e617780cae14e51d495fee949d13b04615606c302ca7624cb97398b53e9be7c46132834e6005179834266c3bad
7
+ data.tar.gz: 51f7614c2320073bd4e41932478ae13cd91270f44543ab81d894f0ef1e328a407b6cc2d25b5af4009863f6f15c14b0aa85dadb6951bb40ab2b409c06ff32f7f3
data/example/eventlog.rb CHANGED
@@ -1,7 +1,16 @@
1
1
  require 'winevt'
2
+ require 'rexml/document'
2
3
 
3
4
  @query = Winevt::EventLog::Query.new("Application", "*[System[(Level <= 3) and TimeCreated[timediff(@SystemTime) <= 86400000]]]")
4
5
 
5
- @query.each do |eventlog|
6
- puts eventlog
6
+ @query.each do |eventlog, message|
7
+ doc = REXML::Document.new(eventlog)
8
+ nodes = []
9
+ REXML::XPath.each(doc, "/Event/EventData/Data") do |node|
10
+ nodes << node.text
11
+ end
12
+ message = message.gsub(/(%\d+)/, '\1$s')
13
+ message = sprintf(message, *nodes)
14
+
15
+ puts ({eventlog: eventlog, data: message})
7
16
  end
data/example/tailing.rb CHANGED
@@ -1,11 +1,22 @@
1
1
  require 'winevt'
2
+ require 'rexml/document'
2
3
 
3
4
  @subscribe = Winevt::EventLog::Subscribe.new
4
5
  @subscribe.tail = true
5
- @subscribe.subscribe("Application", "*[System[(Level <= 4) and TimeCreated[timediff(@SystemTime) <= 86400000]]]")
6
+ @subscribe.subscribe("Security", "*[System[(Level <= 4) and TimeCreated[timediff(@SystemTime) <= 86400000]]]")
6
7
  while (1) do
7
8
  if @subscribe.next
8
- puts @subscribe.render
9
+ eventlog = @subscribe.render
10
+ message = @subscribe.message
11
+ doc = REXML::Document.new(eventlog)
12
+ nodes = []
13
+ REXML::XPath.each(doc, "/Event/EventData/Data") do |node|
14
+ nodes << node.text
15
+ end
16
+ message = message.gsub(/(%\d+)/, '\1$s')
17
+ message = sprintf(message, *nodes)
18
+
19
+ puts ({eventlog: eventlog, data: message})
9
20
  else
10
21
  printf(".")
11
22
  sleep(1)
data/ext/winevt/winevt.c CHANGED
@@ -1,713 +1,9 @@
1
- #include <ruby.h>
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
- id_call = rb_intern("call");
724
-
725
- rb_define_alloc_func(rb_cSubscribe, rb_winevt_subscribe_alloc);
726
- rb_define_method(rb_cSubscribe, "initialize", rb_winevt_subscribe_initialize, 0);
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
- rb_define_alloc_func(rb_cChannel, rb_winevt_channel_alloc);
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
  }