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.
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
  }